; ; ; ; MIT License
; ; ; ; 
; ; ; ; Copyright (c) 2021 Ramiro Hernán García Iten / Raúl Ripoll Pérez / Alexandru Marius Cozma
; ; ; ; 
; ; ; ; 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 ------------------
; ; ; ;     Ramiro Hernán García Iten: rhgi1@alu.ua.es
; ; ; ;     Raúl Ripoll Pérez: rrp42@alu.ua.es
; ; ; ;     Alexandru Marius Cozma: amc246@alu.ua.es
; ; ; ; 
; ; ; ; Art by Sara Alfosea - IG: @Slinfir
; ; ; ; ---------------------------------------------

; ; ; ; Third Party source code used
; ; ; ; ----------------------------
; ; ; ; CPCtelera - owned by ronaldo / (Cheesetea, Fremos, ByteRealms) - GNU Lesser General Public License.


;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of CPCtelera: An Amstrad CPC Game Engine 
;;  Copyright (C) 2018 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/>.
;;-------------------------------------------------------------------------------


.include "cpctelera.h.s"

;;; ==========================================
;;; ==========================================
;;; RENDER SYSTEM
;;; ==========================================
;;; ==========================================

; Inicializa el sistema de renders
sys_render_init::
   ld    l, #0xB6
   call cpct_setBlendMode_asm

   ld    hl, #0x8000             ; Dibujamos el fondo para los 2 buffers.
   call  sys_render_sky
   ld    hl, #0xC000
   call  sys_render_sky

   ld    hl, #level1
   ld    a, (currentLevel)
   dec   a
   ld    e, a
   sla   e
   sla   e
   ld    d, #0
   add   hl, de

   ld    de, #4
   call  cpct_setPalette_asm

   call  change_screen_to_8000
   ret

; Actualiza la memoria de vídeo dibujando todos los sprites y elementos del mapa
sys_render_update::
   call  sys_render_entities
   call  cpct_waitVSYNC_asm
   call  change_screen
   ret

sys_render_entities::
   ld    (_renderIndex), a

   ld    a, e_life(ix)              ; Si la entidad está muerta
   cp    #0                         ; tenemos que borrar su rastro.
   jp    nz, re_endDead              
      call  sys_render_erasePrev
      call  sys_render_erasePrev2
      cpctm_setBorder_asm HW_BLACK
      jp    ru_end
 re_endDead:

   call  sys_render_erasePrev2

 back_buffer = . + 2
   ld    de, #0x8000
   ld    c, e_x(ix)                 ; Para calcular la posición sin volvernos locos, le pasamos
   ld    a, e_y(ix)
   add   #start_height              ; la posición X e Y a los registros C y B, respectivamente,
   ld    b, a
   call  cpct_getScreenPtr_asm      ; y nos devuelve en HL el puntero.

   ld    a, e_prev_ptr(ix)       ; Pasamos la posición anterior
   ld    e_prev_ptr2(ix), a
   ld    a, e_prev_ptr+1(ix)
   ld    e_prev_ptr2+1(ix), a

   ; Guardamos posicion anterior para borrar en el siguiente 
   ld    e_prev_ptr  (ix), l
   ld    e_prev_ptr+1(ix), h

   ex    de, hl               ; DE: Destination video memory pointer
   ld    l, e_sptr  (ix)      ; HL: Source Sprite Pointer
   ld    h, e_sptr+1(ix)
   ld    c, e_h(ix)           ; C: Sprite Height in bytes        
   ld    b, e_w(ix)           ; B: Sprite Width in bytes

   ld    a, e_type(ix)
   cp    #e_cmp_floor
   jr    z, commonRender
      call  cpct_drawSpriteBlended_asm
      jp    endCommonRender
 commonRender:
      ld    b, e_h(ix)           ; C: Sprite Height in bytes        
      ld    c, e_w(ix)           ; B: Sprite Width in bytes
      call  cpct_drawSprite_asm
 endCommonRender:

   ld    a, e_type(ix)
   cp    #e_cmp_hit
   jr    nz, ru_end
      xor   a
      ld    e_life(ix), a

 ru_end:
   ld    a, (_renderIndex)
   call  man_entity_nextEntity   ; Pasamos al siguiente elemento ...
   dec   a
   jp    nz, sys_render_entities ; si lo hubiese. Si no, terminamos.
   ret

; Renderiza el fondo a partir de una columna de bytes
; Parámetros de entrada:
;  HL: Dirección de vídeo
sys_render_sky::
   ld    de, #_background
   ld    a, #201  ; Contador de líneas a dibujar
   push  af       ; Lo guardamos

loop__rb1:
   ex    de, hl
   pop   af
   dec   a
   ret   z        ; Si no nos quedan líneas, END
   push  af
   
   ld    b, #screen_width
loop__rb2:
   ld    a, (hl)  ; Cargo en DE lo que hay en HL
   ld    (de), a  ;
   inc   de       ; Actualizo DE con +1
   dec   b        ;
   jr    nz, loop__rb2

   ex    de, hl
   inc   de             ; Aumento HL (sí, HL) con +1
   ld    bc, #0x7B0     ; Aumento DE con 0x800 - screen_width
   add   hl, bc   

   ld    a, h 
   and   #0x38
   jr    nz, loop__rb1

   ld    bc, #0xC050 ; Avanzamos
   add   hl, bc
   jp    loop__rb1

; AUXILIAR: Elimina el rastro del puntero anterior
; Parámetros de entrada
;  B: altura
sys_render_erasePrev:
   ld    e, e_prev_ptr  (ix)   ; DE = e_prev_ptr(ix)
   ld    d, e_prev_ptr+1(ix)

   ld    a, #0x00 ; Color fondo
   ld    c, e_w(ix)
   ld    b, e_h(ix)
   call  cpct_drawSolidBox_asm
   ret

; AUXILIAR: Elimina el rastro del puntero anterior 2
; Parámetros de entrada
;  B: altura
sys_render_erasePrev2:
   ld    e, e_prev_ptr2  (ix)  ; DE = e_prev_ptr(ix)
   ld    d, e_prev_ptr2+1(ix)

   ld    a, #0x00 ; Color fondo
   ld    c, e_w(ix)
   ld    b, e_h(ix)
   call  cpct_drawSolidBox_asm
   ret

; Implementación del doble buffer de 32k. En cada llamada, alterna entre
; una pantalla y otra.
change_screen::
f_change_screen = . + 1
   jp    change_screen_to_C000

change_screen_to_C000:
   ld    bc, #0x3C0C          ; REG (C = 12): (B = [13] 1 [12] 1 [11] 1 [10] 1)
   call  cpct_setCRTCReg_asm  ; Video Page: C000 - FFFF

   ld    a, #0x80             ; El buffer en el que ESCRIBIREMOS 
   ld    (back_buffer), a     ; pasa a ser el CONTRARIO (0x8000)

   ld    hl, #change_screen_to_8000 ; La siguiente función que se llame 
   ld    (f_change_screen), hl      ; pasa a ser la CONTRARIA (0x8000)

   ret

change_screen_to_8000:
   ld    bc, #0x2C0C          ; REG (C = 12): (B = [13] 1 [12] 0 [11] 1 [10] 1)
   call  cpct_setCRTCReg_asm  ; Video Page: 8000 - BFFF

   ld    a, #0xC0             ; El buffer en el que ESCRIBIREMOS
   ld    (back_buffer), a     ; pasa a ser el CONTRARIO (0xC000)

   ld    hl, #change_screen_to_C000 ; La siguiente función que se llame 
   ld    (f_change_screen), hl      ; pasa a ser la CONTRARIA (0xC000)

   ret

; Función AUXILIAR utilizada
sys_render_updateEntCount:
   ld    a, (_renderIndex)
   dec   a
   ld    (_renderIndex), a
   ret

