;;####################################################################
;;# GNU Free Documentation License                                   #
;;# Version 1.3, 3 November 2008                                     #
;;#                                                                  #
;;# Copyright (C) 2021 Lumina                                        #
;;# (Paula Garcia Morales, Laura Gil Lopez, Jorge Perez Dominguez)   #
;;#                                                                  #
;;# Everyone is permitted to copy and distribute verbatim copies     #
;;# of this license document, but changing it is not allowed.        #
;;####################################################################


.include "cpctelera.h.s"
.include "render.h.s"

screen_width	==	 40
screen_height	==	256

camera3: .dw 0x0280
camera7: .dw 0x0780
camera10: .dw 0x0B40
camera12: .dw 0x0DC0
camera20: .dw 0x17C0

relojitoCamera: .db #0x00

nivel: .db 0
camera: .dw 0x0000
tile_nivel: .dw 0x0000

reloj50frames: .db #0x00

reset_nivel::
	ld a, #0
	ld (nivel), a
ret

render_getNivel_A::
	ld a, (nivel)
ret

render_getCamera_HL::
	ld hl, (camera)
ret

init_camera::
	ld a, (nivel)
	cp #2
	jr z, poner_camera3
	jp m, poner_camera3

	ld a, (nivel)
	cp #4
	jr z, poner_camera7
	jp m, poner_camera7

	poner_camera12:
		ld hl, (camera12)
		ld (camera), hl

		ld hl, #_nivel_12
		ld (tile_nivel), hl

		ret

	poner_camera7:
		ld hl, (camera7)
		ld (camera), hl

		ld hl, #_nivel_7
		ld (tile_nivel), hl

		ret

	poner_camera3:
		ld hl, (camera3)
		ld (camera), hl

		ld hl, #_nivel_3
		ld (tile_nivel), hl
ret

actualizar_reloj_scroll:
	ld a, (relojitoCamera)
	inc a 
	ld (relojitoCamera), a
ret

comprobar_altura:
	ld hl, (camera)

	ld a, h
	cp #0x01
	jr nz, sigo_scroll

	ld a, l
	cp #0x0E
	jr nz, sigo_scroll

	call change_generoentidades

	sigo_scroll:
ret

scroll_camera::
	call comprobar_altura
	
	call actualizar_reloj_scroll

	cp #0x02 
	jp nz, saltar_scroll

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

	ld hl, (camera)

	ld a, h
	cp #0x00
	jr nz, ccamera

	ld a, l 
	cp #0x46
	jp z, no_camera

	ccamera:
	ld de, #-10
	add hl, de

	ld (camera), hl

    ret

    no_camera:
    	call animation_victoria

    	ld a, (nivel)
    	cp #6
    	jr nz, siguiente_nivel


    	ld a, #0
    	ld (nivel), a
    	
    	call man_menu_game_win
    	call reset_level
    	call reset_nivel

    	ret

    	siguiente_nivel:
    		ld a, (nivel)
    		inc a
    		ld (nivel), a

    		call entityman_reset_game

    		ld a, (nivel)
	    	cp #0
	    	jr z, level11

	    	ld a, (nivel)
	    	cp #1
	    	jr z, level12

	    	ld a, (nivel)
	    	cp #2
	    	jr z, level13

	    	ld a, (nivel)
	    	cp #3
	    	jr z, level21

	    	ld a, (nivel)
	    	cp #4
	    	jr z, level22

	    	ld a, (nivel)
	    	cp #5
	    	jr z, level31

	    	jp level32

	    	level11:
		    	ld a, #49
	    		call next_level

	    		ld a, #49
	    		call next_world

	    		jp salto_check_level

	    	level12:
		    	ld a, #50
	    		call next_level

	    		ld a, #49
	    		call next_world

	    		jp salto_check_level

	    	level13:
		    	ld a, #51
	    		call next_level

	    		ld a, #49
	    		call next_world

	    		jp salto_check_level

	    	level21:
		    	ld a, #49
	    		call next_level

	    		ld a, #50
	    		call next_world

	    		jp salto_check_level

	    	level22:
		    	ld a, #50
	    		call next_level

	    		ld a, #50
	    		call next_world

	    		jp salto_check_level

	    	level31:
		    	ld a, #49
	    		call next_level

	    		ld a, #51
	    		call next_world

	    		jp salto_check_level

	    	level32:
		    	ld a, #50
	    		call next_level

	    		ld a, #51
	    		call next_world

	    		jp salto_check_level

	    	salto_check_level:

    		pop hl
	    	pop hl
	    	pop hl
	    	pop hl
	    	pop hl
	    	pop hl
	    	pop hl

    		jp llamada_siguiente

    saltar_scroll:
ret

sys_render_change_CRTC:
    ;;TODO : there is a macro for this
    ld  bc, #0xBC00
    out (c), d
    inc b   ;; B = 0xBD
    out (c), e
ret


;;poner pantalla de ancho 160pixeles x 256pixeles
screen_init::
    ;; R1 = Screen width (in characters) = 0x14 (20)
    ld de, #0x0114
    call sys_render_change_CRTC

    ;; R2 = Horizontal Sync Start        = 0x24 (36)
    ld de, #0x0224
    call sys_render_change_CRTC

    ;; R6 = Screen Height (in characters) = 0x20 (32)
    ld de, #0x0620
    call sys_render_change_CRTC

    ;; R7 = Vertical Sync Start           = 0x22 (34)
    ld de, #0x0722
    call sys_render_change_CRTC
ret


;;poner pantalla de ancho 320pixeles x 200pixeles
reset_resol:
	;; R1 = Screen width (in characters) = 0x28 (40)
    ld de, #0x0128
    call sys_render_change_CRTC

    ;; R2 = Horizontal Sync Start        = 0x24 (36)
    ld de, #0x022E
    call sys_render_change_CRTC

    ;; R6 = Screen Height (in characters) = 0x19 (25)
    ld de, #0x0619
    call sys_render_change_CRTC

    ;; R7 = Vertical Sync Start           = 0x22 (34)
    ld de, #0x071E
    call sys_render_change_CRTC
ret


;;Poner modo 1 en la pantalla y poner color al borde
render_init::
	ld hl, #_g_palette
    ld de, #4
    call cpct_setPalette_asm

	;;Set mode 1
	ld c,	#1					;;A = 1
	call cpct_setVideoMode_asm	;;SCR_SET_MODE = 1

	cpctm_setBorder_asm HW_BLUE
ret


;;controlar a que change_screen_to_xxxx va a llamar
change_screen:
	f_change_screen = . + 1
	jp change_screen_to_8000

change_screen_to_C000:
	ld de, #0x0C30
	call sys_render_change_CRTC

	;;back_buffer esta en calculate_pos_render para controlar en que pantalla pintar
	ld a, #0x80
	ld (back_buffer), a

	;;back_buffer esta en redibujar_tilemap para controlar en que pantalla borrar la entidad destruida
	ld a, #0x80
	ld (back_buffer_tl), a

	;;back_buffer esta en render_border para controlar en que pantalla borrar la entidad destruida
	ld a, #0x80
	ld (back_buffer_b), a

	ld hl, #change_screen_to_8000
	ld (f_change_screen), hl
ret

change_screen_to_8000:
	ld de, #0x0C20
	call sys_render_change_CRTC

	;;back_buffer esta en calculate_pos_render para controlar en que pantalla pintar
	ld a, #0xC0
	ld (back_buffer), a

	;;back_buffer esta en redibujar_tilemap para controlar en que pantalla borrar la entidad destruida
	ld a, #0xC0
	ld (back_buffer_tl), a

	;;back_buffer esta en render_border para controlar en que pantalla borrar la entidad destruida
	ld a, #0xC0
	ld (back_buffer_b), a

	ld hl, #change_screen_to_C000
	ld (f_change_screen), hl
ret

;;Actualizar el render en cada llamada del bucle principal del juego
render_update::
	call redibujar_tilemap

    call render_border

	ld hl, #render_one_entity
	ld  a, #Render_masc

	call entityman_forall_matching
	call change_screen
ret

render_sprite_1:
	ex	de,	hl

    ld l, 12(ix)
	ld h, 13(ix)

	ld b, 3(ix)
	ld c, 2(ix)

	call mydrawSprite_20x32
ret 

render_sprite_2:
	ex	de,	hl

	ld l, 10(ix)
	ld h, 11(ix)	

	ld b, 3(ix)
	ld c, 2(ix)
		
	call mydrawSprite_20x32
ret

calculate_pos_render:
	;;Calculate the actual position of the entity
	back_buffer = . + 2

	ld	de,	#0x8000
	ld	 c,	0(ix)	;;x
	ld	 b,	1(ix)	;;y
	call mygetScrPrt_20x32 

	call entityman_save_lasts_pos
ret

;;Actualizar el render de una entidad
render_one_entity:

	call calculate_pos_render


	ld a, 7(ix)
	cp #Player_masc
	jr z, special_render


	ld a, 7(ix)
	cp #Rock_masc
	jr z, special_render

	ld a, 7(ix)
	cp #Aguila_masc 
	jr z, special_render

	ld a, 7(ix)
	cp #SpiderR_masc
	jr z, special_render 

	ld a, 7(ix)
	cp #SpiderL_masc
	jr z, special_render 


	ld a, 7(ix)
	cp #Heart_Clock_masc
	jr z, normal_render


	special_render:
		ld a, 14(ix)
		dec a
		jr z, render_sprite_2
		call render_sprite_1

		pop hl
		jp (hl)

	normal_render:
		call render_sprite_1
	
		pop hl
		jp (hl)


;;animacion de la muerte
render_player::
	push ix
		call redibujar_tilemap
    pop ix

	call calculate_pos_render

	ex	de,	hl

	ld hl, #_zacarias_muerta	

	ld b, 3(ix)
	ld c, 2(ix)
		
	call mydrawSprite_20x32

	call change_screen
ret

render_player_win::
	push ix
		call redibujar_tilemap
    pop ix

	call calculate_pos_render

	ex	de,	hl

	ld hl, #_zacarias_victoria	

	ld b, 3(ix)
	ld c, 2(ix)
		
	call mydrawSprite_20x32

	call change_screen
ret

render_player_aturdido::
	push ix
		call redibujar_tilemap
    pop ix

	call calculate_pos_render

	ex	de,	hl

	ld hl, #_zacarias_aturdido	

	ld b, 3(ix)
	ld c, 2(ix)
		
	call mydrawSprite_20x32

	call change_screen
ret

;;se llama desde el entityman_set_for_destruction
;;borrar entidad que llega al fondo de la pantalla o colision
render_delete_entity::
	push ix
	call redibujar_tilemap
	pop ix
ret

set_tilemap::
	ld c, #0x0A  ;;c el ancho en tiles de pantalla
	ld b, #0x20  ;;b el alto en tiles de pantalla
	ld de, #0x000A;; de el ancho del tilemap completo
	ld hl, #_tiles_00
	call mysetdrawtilemap
ret

render_tilemap::
	call render_tilemap_C000
	call render_tilemap_8000
ret 

render_tilemap_C000:
	ld bc, (camera)

	ld hl, (tile_nivel)
	add hl, bc

	ex de, hl

	ld hl, #0xC000
	call mydrawtilemap
ret

render_tilemap_8000:
	ld bc, (camera)

	ld hl, (tile_nivel)
	add hl, bc

	ex de, hl

	ld hl, #0x8000
	call mydrawtilemap
ret


redibujar_tilemap:
	ld bc, (camera)

	ld hl, (tile_nivel)
	add hl, bc

	ex de, hl

	back_buffer_tl = . + 2
	ld hl, #0xC000

	call mydrawtilemap
	;;HL-location in video memory o back buffer where to draw the tilemap
	;;DE-memory adress of the first tile to be drawn
ret

render_clean_screen::
	call change_screen_to_C000

	cpctm_clearScreen_asm #0x00

    call render_init

    call reset_resol
ret


;;textos del menu
;;BC - positions xy
;;HL - texto
render_text::
	push hl 

	ld	de,	#0xC000
	call cpct_getScreenPtr_asm

	ex de, hl
    
    pop hl

    ld c, #0x03
    ld b, #0x00   
    call cpct_drawStringM1_f_asm
ret


;;renderizar las vidas, el reloj o el nivel
;;BC - positions xy
;;A - variable
render_lifes_clock_levels::
	push bc
	push af
	call render_life_clock_C000
	pop af 
	pop bc
	call render_life_clock_8000
ret

render_life_clock_C000:
	push af

	ld  de, #0xC000
    call mygetScrPrt_20x32

    ex de, hl

    pop af

    ld c, #0x03     ;;Color
    ld b, #0x00
    call cpct_drawCharM1_f_asm
ret

render_life_clock_8000:
	push af

	ld  de, #0x8000
    call mygetScrPrt_20x32

    ex de, hl

    pop af

    ld c, #0x03     ;;Color
    ld b, #0x00
    call cpct_drawCharM1_f_asm
ret

render_border:
	back_buffer_b = . + 2

	ld	de,	#0xC000
	ld	 c,	#0	;;lx
	ld	 b,	#0	;;ly
	call cpct_getScreenPtr_asm

	ex	de,	hl

	ld a, #0x00
	ld c, #40
	ld b, #24

	call mydrawsolidbox20x32
ret
