;;------------------------------------------------LICENSE NOTICE------------------------------------------------------------------------------
;;  This file is part of Amstrad CPC videogame "Redsea"
;;  Copyright (C) 2021 Crab Party / Elena López (AneleSplats in itch.io) / Iván Tortosa (Pluvs in itch.io, @IvanTortosaBer1 on Twitter) / Antonio Gosálvez (BalgroHub in itch.io)
;;  Copyright (C) 2015 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
;;
;;  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/>.
;;------------------------------------------------LICENSE NOTICE-------------------------------------------------------------------------
.include "cpctelera.h.s"

.globl cpct_memcpy_asm
.globl cpct_memset_asm
.globl m_entities

;.globl Spawner
;.globl Inmovil
;.globl Movible
.globl Personaje
.globl Suelo
.globl Suelo2
.globl Meta
.globl Arbol
.globl Enemigo
.globl Enemigo2
.globl Llave
.globl Puerta

.globl man_game_create_template
.globl man_entity_deleteAll
.globl sys_render_init
.globl m_next_free_entity
.globl libres

.globl liberarMovimiento
.globl man_entity_update
.globl man_entity_set4destruction

.globl tilemapActual

.globl _tilemap_01
.globl _tilemap_02
.globl _tilemap_03
.globl _tilemap_04
.globl _tilemap_05
.globl _tilemap_06
.globl _tilemap_07
.globl sys_render_tilemap

.globl man_entity_moverEntidad




; Reservamos la memoria para todos los niveles
nNiveles = 7
bytesEntidad = 18
entidades = 7
bytesEntidades = bytesEntidad * entidades
; Nº entidades * Tam de las entidades + Nex_Pointer + libres + tilemap
bytesNivel = entidades*bytesEntidad+2+1+2

; Variables
paraCambiar:: .db #0x00
nivelActual:: .db #0x00
comienzoNiveles:: .ds bytesNivel*nNiveles
nextFreeEntitiesNiveles:: .ds 2*nNiveles


; Elimina todas las entidades del nivel y pinta todo del color de fondo (negro)
borrarEntidades::

    ; Eliminamos todas las entidades
    call man_entity_deleteAll

ret

; Elimina todas las entidades del nivel y pinta todo del color de fondo (negro)
borrarNivel::

    ; Eliminamos todas las entidades y borramos también el tilemap
    call man_entity_deleteAll
    cpctm_clearScreen_asm 0

ret

; Copia todas las entidades del nivel seleccionado y las pega en m_entidades
cargarNivel::

    ;Movemos nuestro idex (hl) a la dir del nivel seleccionado ( hl + bytesNivel*nivelActual )
    ld hl, #comienzoNiveles
    ld a, (#nivelActual)
    comienzoBucle1:
        cp #00
        jr z, salirBucle1

        ld bc, #bytesNivel
        add hl, bc

        sub #1
        cp #00
        jr nz, comienzoBucle1
    salirBucle1:

    ; Copiamos todo el contenido del nivel en m_entities
    ld de, #m_entities
    ld bc, #bytesEntidades
    push hl
    call cpct_memcpy_asm
    pop hl
    

    ; Copiamos todo el contenido de Next y libres en sus respectivas entidades
    ld bc, #bytesEntidades
    ld de, #m_next_free_entity
    add hl, bc
    ld bc, #0d0002
    push hl
    call cpct_memcpy_asm
    pop hl

    inc hl
    inc hl
    ld a, (hl)
    ld (#libres), a

    ; Guardamos en tilemapActual el que corresponda al nivel
    inc hl
    ld de, #tilemapActual
    ld bc, #0d0002
    push hl
    call cpct_memcpy_asm
    pop hl

ret


; Se ejecuta antes del bucle del juego, crea y guarda el nivel creado en memoria y lo vacia
guardarNivel::

    ;Movemos nuestro idex (hl) a la dir del nivel seleccionado ( hl + bytesNivel*nivelActual )
    ld hl, #comienzoNiveles
    ld a, (#nivelActual)
    comienzoBucle:
        cp #00
        jr z, salirBucle

        ld bc, #bytesNivel
        add hl, bc

        sub #1
        cp #00
        jr nz, comienzoBucle
    salirBucle:


    ; Copia todas las entidades, nex_free_entity y libres en su correspondiente hueco en memoria
    push hl
    pop de
    ld hl, #m_entities
    ld bc, #bytesEntidades
    push de
    call cpct_memcpy_asm
    pop hl

    ld bc, #bytesEntidades
    add hl, bc
    ld de, #m_next_free_entity
    ld a, (de)
    ld (hl), a
    inc hl
    inc de
    ld a, (de)
    ld (hl), a

    inc hl
    ld de, #libres
    ld a, (de)
    ld (hl), a

    ; Guardamos el tilemap de cada nivel
    inc hl
    ld de, #tilemapActual
    ld a, (de)
    ld (hl), a
    inc hl
    inc de
    ld a, (de)
    ld (hl), a
    
    
    ; También se hace liberarMovimiento
    call liberarMovimiento
    
    ; Borra todas las entidades y restablece todos los valores predeterminados
    call borrarEntidades

ret

; Se le pasa por a el nivel al que quiere cambiar
cambiarNivel::

    ld (#nivelActual), a

ret


cargarNivel1::

    ld a, #0x00
    ld (#nivelActual), a



;     ld a, #70
;    ld b, a
;    ld a, #20
;    ld c, a
;    call man_entity_moverEntidad

; -------------------------------------

    ld bc, #Personaje
   call man_game_create_template

   ld a, #18
   ld b, a
   ld a, #175
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Meta
   call man_game_create_template

   ld a, #70
   ld b, a
   ld a, #175
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_01
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a

; ; -------------------------------------

    ld bc, #Personaje
   call man_game_create_template

   ld a, #4
   ld b, a
   ld a, #175
   ld c, a
   call man_entity_moverEntidad

   ld bc, #Meta
   call man_game_create_template

   ld a, #66
   ld b, a
   ld a, #40
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_02
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a

; ; ----------------------------------

    ld bc, #Personaje
   call man_game_create_template

   ld a, #8
   ld b, a
   ld a, #80
   ld c, a
   call man_entity_moverEntidad



      ld bc, #Meta
   call man_game_create_template

   ld a, #70
   ld b, a
   ld a, #128
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Llave
   call man_game_create_template

    ld a, #42
   ld b, a
   ld a, #64
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Puerta
   call man_game_create_template

    ld a, #65
   ld b, a
   ld a, #120
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_03
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a

; ; -------------------------------------


    ld bc, #Personaje
   call man_game_create_template
    ld a, #5
   ld b, a
   ld a, #56
   ld c, a
   call man_entity_moverEntidad

   ld bc, #Meta
   call man_game_create_template

   ld bc, #Enemigo
   call man_game_create_template
    ld a, #64
   ld b, a
   ld a, #136
   ld c, a
   call man_entity_moverEntidad

   ld hl, #_tilemap_04
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a

; ; --------------------------------

    ld bc, #Personaje
   call man_game_create_template

   ld a, #6
   ld b, a
   ld a, #60
   ld c, a
   call man_entity_moverEntidad

   


    ld bc, #Enemigo2
   call man_game_create_template
    ld a, #48
   ld b, a
   ld a, #90
   ld c, a
   call man_entity_moverEntidad



     ld bc, #Enemigo2
   call man_game_create_template
    ld a, #48
   ld b, a
   ld a, #110
   ld c, a
   call man_entity_moverEntidad

     ld bc, #Enemigo2
   call man_game_create_template
    ld a, #48
   ld b, a
   ld a, #130
   ld c, a
   call man_entity_moverEntidad

     ld bc, #Enemigo2
   call man_game_create_template
    ld a, #48
   ld b, a
   ld a, #150
   ld c, a
   call man_entity_moverEntidad

   

      ld bc, #Meta
   call man_game_create_template

   ld a, #72
   ld b, a
   ld a, #44
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_05
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a
    

; -----------------------------------


    ld bc, #Personaje
   call man_game_create_template

   ld a, #24
   ld b, a
   ld a, #14
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Enemigo
   call man_game_create_template
    ld a, #16
   ld b, a
   ld a, #90
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Enemigo
   call man_game_create_template
    ld a, #66
   ld b, a
   ld a, #60
   ld c, a
   call man_entity_moverEntidad

         ld bc, #Enemigo
   call man_game_create_template
    ld a, #36
   ld b, a
   ld a, #120
   ld c, a
   call man_entity_moverEntidad



      ld bc, #Meta
   call man_game_create_template

   ld a, #63
   ld b, a
   ld a, #150
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_06
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update
    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a

; ----------------------------------

    ld bc, #Personaje
   call man_game_create_template

   ld a, #8
   ld b, a
   ld a, #150
   ld c, a
   call man_entity_moverEntidad

    ld bc, #Enemigo
   call man_game_create_template
    ld a, #66
   ld b, a
   ld a, #144
   ld c, a
   call man_entity_moverEntidad

    ld bc, #Enemigo
   call man_game_create_template
    ld a, #20
   ld b, a
   ld a, #110
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Arbol
   call man_game_create_template

   ld a, #30
   ld b, a
   ld a, #153
   ld c, a
   call man_entity_moverEntidad

    ld bc, #Llave
   call man_game_create_template

    ld a, #58
   ld b, a
   ld a, #180
   ld c, a
   call man_entity_moverEntidad

      ld bc, #Puerta
   call man_game_create_template

    ld a, #16
   ld b, a
   ld a, #140
   ld c, a
   call man_entity_moverEntidad

      ld hl, #_tilemap_07
    call cambiarTilemap

    call guardarNivel
    call borrarNivel
    call man_entity_update



; -----------------------------------
    ld a, #0x00
    ld (#nivelActual), a
    call cargarNivel

ret




; Se llama al final de cada bucle de juego
; Si la variable paraCambiar es 1, se hace un cargarNivel
levelUpdate::

    ld a, (#paraCambiar)
    cp #1
    ret nz

    call cargarNivel
    call sys_render_tilemap
    ld a, #0x00
    ld (#paraCambiar), a

ret


; Se le suma 1 al nivel seleccionado, se borra el nivel actual y se pone para cargar el siguiente
pasarNivel::

    ld a, (#nivelActual)
    inc a
    ld (#nivelActual), a
    call borrarNivel
    ld a, #0x01
    ld (#paraCambiar), a
    
ret


; Se borra el nivel y se prepara para volver a cargar el nivel actual
resetearNivel::

    call borrarNivel
    ld a, #0x01
    ld (#paraCambiar), a

ret

; Se le pasa por hl la dir del tilemap al que poner
cambiarTilemap::

    ld de, #tilemapActual
    ld a, l
    ld (de), a
    inc de
    ld a, h
    ld (de), a

ret




; Si se llama, se elimina una puerta que encuentre y la llave actual
puertaUpdate::

    ; Se elimina la llave nivelActual
    call man_entity_set4destruction

    ; Se busca una puerta, y se elimina si la encontramos
    ld ix, #m_entities
    siguiente_ent5:
        ; Si es una entidad no válida se sale del bucle
        ld a, (ix)
        or a
        jr z, salir5

        ; Si es una puerta, la borra y se sale del bucle
        ld a, #0x80
        ld d, a
        ld a, 15(ix)
        and d
        cp d
        jr nz, saltito5 ;Si no cumple todos los bites de d, se mira otra entidad

        ; La borra y se sale del bucle
        call man_entity_set4destruction
        jr salir5

        
    saltito5:
        ld bc, #bytesEntidad
        add ix, bc
        jr siguiente_ent5

    salir5:

ret