;; MIT License
;; 
;; Copyright (c) 2021 capAI / Aitana Devis  Ávila (@AitanaDevis) / Carlos Peñarrubia Morcillo  (@carlospm12) / Pablo Ruiz Ponce (@pabloruizp)
;; 
;; 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 "cpctelera.h.s"
.include "entity.h.s"
.include "../sys/animations.h.s"
.include "sprites.h.s"

.globl cpct_akp_musicInit_asm
.globl _prado_song
.globl _halloween_song
.globl _desierto_song
.globl sys_render_hard_delete_entity
.globl sys_render_draw_ground
.globl sys_render_draw_ground_desierto
.globl sys_render_draw_ground_halloween



.globl cpct_memset_asm

.area _DATA

;;;;                  X          Y                    W     H                  V   JUMP_COUNTER  STATE   SPRITE      ANIM_PTR   ANIM_STATE
DefinePlayer _player, 5, #NIVEL_SUELO-P_H_INITIAL,    5,    #P_H_INITIAL, 0, 0, 0,     30,        0,    #_walking_0, _dog_running, 0, 4,#0xC000, #0x8000
DefinePlayer _player_init, 5, #NIVEL_SUELO-P_H_INITIAL, 5, #P_H_INITIAL, 0, 0, 0,      30,        0,    #_walking_0, _dog_running, 0, 4, #0xC000, #0x8000

_entities:: .ds 1000                ;; RESERVAMOS 1000 BYTES DE MEMORIA 

_num_entities_final:: .db #0         ;; AÑADIR BYTE A 0 PARA FORZAR LA SALIDA CUANDO EL ARRAY DE ENTIDADES ESTE LLENO

_next_free_entity:: .db #0xFF, #0xFF  ;; VARIABLE QUE ME DICE DONDE ESTA LA ULTIMA ENTIDAD A UTILIZAR

_entities_start:: .db 0, 0


.area _CODE


;;///////////////////////////////////////////////////////////////////////
;; WE COPY THE MAP TO THE ENTITIES ARRAY 
;;
;; PARAMETROS: DE (ARRAY DE ENTIDADES)
;;///////////////////////////////////////////////////////////////////////
_man_entity_load_map::
   ld de, #_entities
   call cpct_memcpy_asm
   ret


;;///////////////////////////////////////////////////////////////////////
;; FUNCION PARA ITERAR POR TODAS LAS ENTIDADES APLICANDO UNA FUNCION
;;
;; PARAMETROS: HL (FUNCION A APLICAR)
;;
;; REGISTROS MODIFICADOS: DE, A, BC, HL, (+ LAS QUE MODIFIQUE LA FUNCION A LA QUE LLAMAMOS)
;;
;; RETURN: NADA
;;///////////////////////////////////////////////////////////////////////
_man_entity_forall_ai::
   ld de, (#_entities_start)

   loop_ai:
      ld a, (de)        ;; COGEMOS EL TIPO DE LA ENTIDAD
      inc a
      dec a             ;; COMPROBAR QUE ES 0
      jr z, end_ai         ;; SI ES 0 (INVALIDO) TERMINAMOS EL BUCLE

      inc de
      ld a, (de)
      dec de
      dec a
      jr nz, _continuar_ai   ;; SI NO ES DE TIPO AI (BIT COMPONENTE = 1) NO EJECUTAMOS LA FUNCION 

      ld bc, #_continuar_ai
      push bc           ;; GUARDAMOS EN LA PILA EL VALOR DEL PC + 3
      jp (hl)
      _continuar_ai:
         push hl           ;; GUARDAMOS LA DIRECCION DE LA ETIQUETA EN LA PILA
         ld hl, #SIZE_ENTITY
         add hl, de        ;; MODIFICAMOS LA NUEVA POSICION DE MEMORIA
         ld d, h
         ld e, l
         pop hl            ;; RECUPERAMOS EL VALOR DE LA PILA
         jr loop_ai
   end_ai:
   ret 


;;///////////////////////////////////////////////////////////////////////
;; FUNCION PARA ITERAR POR TODAS LAS ENTIDADES APLICANDO UNA FUNCION
;;
;; PARAMETROS: HL (FUNCION A APLICAR)
;;
;; REGISTROS MODIFICADOS: DE, A, BC, HL, (+ LAS QUE MODIFIQUE LA FUNCION A LA QUE LLAMAMOS)
;;
;; RETURN: NADA
;;///////////////////////////////////////////////////////////////////////
_man_entity_forall::
   ld de, (#_entities_start)

   loop:
      ld a, (de)        ;; COGEMOS EL TIPO DE LA ENTIDAD
      inc a
      dec a             ;; COMPROBAR QUE ES 0
      jr z, end         ;; SI ES 0 (INVALIDO) TERMINAMOS EL BUCLE
      
      ld ix, #_player
      ld a, P_PREV(ix)
      cp #1
      jr z, end

      ld bc, #_continuar
      push bc           ;; GUARDAMOS EN LA PILA EL VALOR DEL PC + 3
      jp (hl)
      _continuar:
         push hl           ;; GUARDAMOS LA DIRECCION DE LA ETIQUETA EN LA PILA
         ld hl, #SIZE_ENTITY
         add hl, de        ;; MODIFICAMOS LA NUEVA POSICION DE MEMORIA
         ld d, h
         ld e, l
         pop hl            ;; RECUPERAMOS EL VALOR DE LA PILA
         jr loop
   end:
   ret  




;;///////////////////////////////////////////////////////////////////////
;; FUNCION PARA CONTROLAR LOS FRAMES DEL JUEGO
;;
;; PARAMETROS: H (PORCENTAJE DE ESPERA)
;;
;; REGISTROS MODIFICADOS: H
;;
;; RETURN: NADA
;;///////////////////////////////////////////////////////////////////////
_man_entity_init:: 
   ld hl, #_entities
   ld (_next_free_entity), hl
   ld (_entities_start), hl
   
   dec a
   jr nz, check_mapa_2
   ld bc, #SIZE_MAPA_1
   ld hl, #_mapa1   
   ;;; PRADO
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground
   ld de, #_prado_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init

   check_mapa_2:
   dec a
   jr nz, check_mapa_3
   ld bc, #SIZE_MAPA_2
   ld hl, #_mapa2
   ;;; PRADO
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground
   ld de, #_prado_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init

   check_mapa_3:
   dec a
   jr nz, check_mapa_4
   ld bc, #SIZE_MAPA_3
   ld hl, #_mapa3
   ;;; PRADO
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground
   ld de, #_prado_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init

   check_mapa_4:
   dec a
   jr nz, check_mapa_5
   ld bc, #SIZE_MAPA_4
   ld hl, #_mapa4
   ;;PRADO
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground
   ld de, #_prado_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init

   check_mapa_5:
   dec a
   jr nz, check_mapa_6
   ld bc, #SIZE_MAPA_5
   ld hl, #_mapa5
   ;;DESIERTO 
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground_desierto
   ld de, #_desierto_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init
   
   check_mapa_6:
   dec a
   jr nz, check_mapa_7
   ld bc, #SIZE_MAPA_6
   ld hl, #_mapa6
   ;;DESIERTO 
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground_desierto
   ld de, #_desierto_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init
   
   check_mapa_7:
   dec a
   jr nz, check_mapa_8
   ld bc, #SIZE_MAPA_7
   ld hl, #_mapa7
   ;;HALLOWEEN 
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground_halloween
   ld de, #_halloween_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init
   
   check_mapa_8:
   dec a
   jr nz, check_mapa_9
   ld bc, #SIZE_MAPA_8
   ld hl, #_mapa8
   ;;HALLOWEEN MUSIC
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground_halloween
   ld de, #_halloween_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init
   
   check_mapa_9:
   dec a
   jr nz, check_mapa_10
   ld bc, #SIZE_MAPA_9
   ld hl, #_mapa9
   ;;HALLOWEEN MUSIC
   cpctm_push af, bc, de, hl, ix, iy
   call sys_render_draw_ground_halloween
   ld de, #_halloween_song 
   call cpct_akp_musicInit_asm ;;DESTROYS: AF, AF’, BC, DE, HL, IX, IY
   cpctm_pop iy, ix, hl, de, bc, af
   jp continuar_man_entity_init

   check_mapa_10:
   ret

   continuar_man_entity_init:
  
   call _man_entity_load_map
   ret



;;///////////////////////////////////////////////////////////////////////
;; CREA UNA ENTIDAD
;;
;; PARAMETROS: NADA
;;
;; REGISTROS MODIFICADOS: DE, HL
;;
;; RETURN: HL (PUNTERO A LA ENTIDAD)
;;///////////////////////////////////////////////////////////////////////
_man_entity_create::
    ld de, (_next_free_entity)
    ld hl, #SIZE_ENTITY
    add hl, de
    ld (_next_free_entity), hl
    ld h, d
    ld l, e
    ld (hl), #E_TYPE_DEFAULT   ;; SETEAMOS EL TIPO DE QUE ACABAMOS DE CREAR A DEFAULTS
    ret



;;///////////////////////////////////////////////////////////////////////
;; CAMBIAMOS EL TIPO DE UNA ENTIDAD A MUERTA
;;
;; PARAMETROS: DE (PUNTERO A LA ENTIDAD)
;;
;; REGISTROS MODIFICADOS: A
;;
;; RETURN: DE (PUNTERO A LA ENTIDAD)
;;///////////////////////////////////////////////////////////////////////
_man_entity_set4destroy::
   push hl
   push bc

   ld a, #E_TYPE_DEAD
   ld (de), a

   ld hl, (_entities_start)
   ld b, #0
   ld c, #SIZE_ENTITY
   add hl, bc
   ld (_entities_start), hl

   pop bc
   pop hl
   ret


_man_entity_bonus_consume::
   push de
   pop ix

   ld E_TIPO(ix), #32
   ld E_COMPONENTE(ix), #2
   call sys_render_hard_delete_entity

   ret

_man_player_init:
   ld de, #_player
   ld hl, #_player_init
   ld bc, #SIZE_PLAYER
   call cpct_memcpy_asm
   ret


clean_array_entities:
   ld de, #_entities
   ld a, #0
   ld bc, #1000
   call cpct_memset_asm
   ret