;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of CPCtelera: An Amstrad CPC Game Engine 
;;  Copyright (C) 2021 Daniel José García Evans, Iván Alejandro Ontano Herrera,
;;  Sergio Izquierdo Pintado (PyroClastic Software)
;;
;;  Special Thanks to Ennio Fernando Velásquez Berlingeri (PyroBombastic)
;;
;;  This program is free software: you can redistribute it and/or modify
;;  it under the terms of the GNU Lesser General Public License as published by
;;  the Free Software Foundation, either version 3 of the License, or
;;  (at your option) any later version.
;;
;;  This program is distributed in the hope that it will be useful,
;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;  GNU Lesser General Public License for more details.
;;
;;  You should have received a copy of the GNU Lesser General Public License
;;  along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;
;;RENDER SYSTEM
;;

.include "../globals.h.s"
;;.include "cpctelera.h.s"
;;.include "managers/man_entity.h.s"
;;.include "systems/sys_render.h.s"

screen_init_pointer: .dw #0xC000 ;;(screen_init_pointer)
background_color: .db #0x03 ;;(background_color)
for_sprites: .db #0

sys_render_palette::
    ld c, #0
    call cpct_setVideoMode_asm

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

    ret

sys_render_init::
    ld a, (current_map)
    and a
    jr z, first_map
        dec a
        jr z, second_map
            dec a
            jr z, third_map
                xor a
                ld (current_map), a ;;si por algun motivo no es ningun mapa
                jr first_map    ;;se usa el primero
            third_map:
            xor a
            ld (for_sprites), a
            call sys_render_tilemap3
            jr baobap
        second_map:
            xor a
            ld (for_sprites), a
            call sys_render_tilemap2
            jr baobap
    first_map:
    xor a
    ld (for_sprites), a
    call sys_render_tilemap1

    baobap:
    ld a, (current_map) ;;se carga para el siguiente mapa
    inc a
    ld (current_map), a

    call man_ui_init

    ld hl, #sys_render_update_entity        ;;dibuja las entidades que no se moveran y el resto
    ld b, #(e_cmps_alive | e_cmps_render)
    call man_entity_for_all_matching

    ret

sys_render_update:: ;recibe la entidad por IX
    ld hl, #sys_render_smart_update_entity
    ;;ld b, #(e_cmps_alive | e_cmps_render)
    ld b, #(e_cmps_render)
    call man_entity_for_all_matching

    ret 

;;recibe la entidad por IX
sys_render_update_entity:
    call sys_render_clear_prev_pos_entity
    call sys_render_draw_entity

    ret

;;recibe la entidad por IX y la repinta solo si tiene fisicas
sys_render_smart_update_entity:
    ;;si tiene fisicas borro la anterior
    ;;si esta viva pinto la nueva
    ;;si esta muerta borro la nueva

    ld a, e_cmps(ix) ;;si se mueve limpiamos la posicion anterior
    ld b, a
    and #(e_cmps_physics)
    ret z 

    ;;si tiene fisicas se pinta la posicion anterior
    call sys_render_clear_prev_pos_entity

    ld a, e_cmps(ix)    ;;si esta viva pinto el sprite
    and #(e_cmps_alive)
    jr z, borrar_entidad
        ;;si esta viva    
        call sys_render_draw_entity
        ret 
        
    borrar_entidad:         ;;si esta muerta limpio la posicion actual y pongo la previa y la actual donde no molesten
        call sys_render_clear_pos_entity
        ld e_x(ix), #0 
        ld e_y(ix), #16
        ld e_posPrev + 0(ix), #0x00
        ld e_posPrev + 1(ix), #0xC0
    ret

sys_render_draw_entity:
    ld de, (screen_init_pointer)
    ld c, e_x(ix) ;;pixel x
    ld b, e_y(ix) ;;pixel y
    call cpct_getScreenPtr_asm

    ld e_posPrev(ix), l     ;;guardo la posicion de memoria previa
    ld e_posPrev + 1(ix), h ;;para el borrado del rastro

    ex de, hl
    ld l, e_sprite(ix)  ;;direccion de memoria del sprite a dibujar
    ld h, e_sprite + 1(ix)
    
    ld c, e_w(ix)   ;;ancho = 8 pixeles (4 bytes)
    ld b, e_h(ix)   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSprite_asm

    ret

;;sys_render_draw_entity_iy:
;;    ld de, (screen_init_pointer)
;;    ld c, e_x(iy) ;;pixel x
;;    ld b, e_y(iy) ;;pixel y
;;    call cpct_getScreenPtr_asm
;;
;;    ld e_posPrev(iy), l     ;;guardo la posicion de memoria previa
;;    ld e_posPrev + 1(iy), h ;;para el borrado del rastro
;;
;;    ex de, hl
;;    ld l, e_sprite(iy)  ;;direccion de memoria del sprite a dibujar
;;    ld h, e_sprite + 1(iy)
;;    
;;    ld c, e_w(ix)   ;;ancho = 8 pixeles (4 bytes)
;;    ld b, e_h(ix)   ;;alto  = 16 pixeles = 16 bytes
;;    call cpct_drawSprite_asm
;;
;;    ret

sys_render_clear_prev_pos_entity::    ;;dibuja a color fondo la posicion anterior    ;;si no tiene physics NO HAY QUE HACER CLEAR
    ;;TODO NO poner comprobacion de mascara de fisicas para no dibujar si no se puede mover
    ld e, e_posPrev(ix)
    ld d, e_posPrev + 1(ix)
    ld a, (background_color)     ;;color de fondo
    ld c, e_w(ix)   ;;ancho
    ld b, e_h(ix)   ;;alto
    call cpct_drawSolidBox_asm

    ret 

sys_render_clear_pos_entity::    ;;dibuja a color fondo la posicion anterior    ;;si no tiene physics NO HAY QUE HACER CLEAR
    ld de, (screen_init_pointer)
    ld c, e_x(ix) ;;pixel x
    ld b, e_y(ix) ;;pixel y
    call cpct_getScreenPtr_asm

    ex de, hl
    ld a, (background_color)     ;;color de fondo
    ld c, e_w(ix)   ;;ancho
    ld b, e_h(ix)   ;;alto
    call cpct_drawSolidBox_asm

    ret 

sys_render_clear_pos_entity_iy::    ;;dibuja a color fondo la posicion anterior    ;;si no tiene physics NO HAY QUE HACER CLEAR
    ld de, (screen_init_pointer)
    ld c, e_x(iy) ;;pixel x
    ld b, e_y(iy) ;;pixel y
    call cpct_getScreenPtr_asm

    ex de, hl
    ld a, (background_color)     ;;color de fondo
    ld c, e_w(iy)   ;;ancho
    ld b, e_h(iy)   ;;alto
    call cpct_drawSolidBox_asm

    ret 

draw_clouds:    ;;bucle de dibujado de nubes

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #8 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_00
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #4
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_clouds
    ret 

sys_render_tilemap1:: ;;GREEN
    cpctm_setBorder_asm HW_GREEN

    cpctm_clearScreen_asm #0x03

    ;;ld de, #0xC000
    ;;ld a, #0 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #0, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    ;;ld de, #0xC000
    ;;ld c, #40 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #40, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    call draw_clouds ;;Se dibujan las nubes de arriba, las mismas para los 3 mapas
    
    xor a
    ld (for_sprites), a

    draw_grass1:

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #184 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_07
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #4
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_grass1
    
    xor a
    ld (for_sprites), a
    ;;dibujado del cesped oscuro de la parte inferior de la pantalla
    draw_flowers:

        ld de,(screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_09
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        add a, #4
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_08
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #8
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_flowers
    ret

sys_render_tilemap2:: ;;PINK
    cpctm_setBorder_asm HW_BRIGHT_MAGENTA

    cpctm_clearScreen_asm #0x03

    ;;ld de, #0xC000
    ;;ld a, #0 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #0, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    ;;ld de, #0xC000
    ;;ld c, #40 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #40, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    call draw_clouds ;; Dibujamos las nubes

    xor a
    ld (for_sprites), a
    
    draw_grass3:

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #184 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_04
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #4
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_grass3
    
    xor a
    ld (for_sprites), a
    ;;dibujado del cesped oscuro de la parte inferior de la pantalla
    draw_candy:

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_06
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        add a, #4
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_05
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #8
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_candy
    ret

sys_render_tilemap3:: ;;RED
    cpctm_setBorder_asm HW_RED
    cpctm_clearScreen_asm #0x03

    ;;ld de, #0xC000
    ;;ld a, #0 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #0, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    ;;ld de, #0xC000
    ;;ld c, #40 ;;pixel x
    ;;ld b, #0 ;;pixel y
    ;;call cpct_getScreenPtr_asm

    cpctm_screenPtr_asm, hl, #0xC000, #40, #0

    ex de, hl
    ld a, #0xFF
    ld c, #40   ;;ancho = 8 pixeles (4 bytes)
    ld b, #8   ;;alto  = 16 pixeles = 16 bytes
    call cpct_drawSolidBox_asm

    call draw_clouds    ;;Dibujamos las nubes de arriba

    xor a
    ld (for_sprites), a
    
    draw_grass2:

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #184 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_01
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #4
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_grass2
    
    xor a
    ld (for_sprites), a
    ;;dibujado del cesped oscuro de la parte inferior de la pantalla
    draw_twigs:

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_03
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld de, (screen_init_pointer)
        ld a, (for_sprites) ;;pixel x
        add a, #4
        ld c, a
        ld b, #192 ;;pixel y
        call cpct_getScreenPtr_asm

        ex de, hl
        ld hl, #_map_tiles_02
        ld c, #4   ;;ancho = 8 pixeles (4 bytes)
        ld b, #8   ;;alto  = 16 pixeles = 16 bytes
        call cpct_drawSprite_asm

        ld a, (for_sprites)
        add a, #8
        ld (for_sprites), a

        cp #80
        
        jr nz, draw_twigs
    ret

