;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of The Last Fungus: An Amstrad CPC Game 
;;  Copyright (C) 2021 Miguel Perez Tarruella / Antonio Jose Fernandez Belliure / 
;;                     David Martinez Garcia / Ocacho Games (@OcachoGames)
;;
;;  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/>.
;;------------------------------------------------------------------------------

;;====================================================================
;; GLOBL INCLUDES
;;====================================================================
.include "game.h.s"
.include "cpctelera.h.s"

;;Manager includes
.include "man/entity.h.s"
.include "patrol.h.s"
.include "man/interruptions.h.s"
.include "man/anim_states_machine/state_machine_handlers.h.s"
.include "man/level_loader.h.s"

;;System includes
.include "sys/input.h.s"
.include "sys/ai.h.s"
.include "sys/physics.h.s"
.include "sys/render.h.s"
.include "sys/collision.h.s"
.include "sys/animation.h.s"
.include "sys/music.h.s"

;;Global includes
.include "global/global.h.s"

;;Macros
.include "macros/math.h.s"

;;Resources
.include "resources/templates.h.s"
.include "resources/sprites.h.s"
.include "resources/bullet_animations.h.s"

;;Screens
.include "assets/img/win_screen_c.h.s"
.include "assets/img/lose_screen_c.h.s"

;;Main label directions (To reset the game to the main menu o play another play)
.globl jump_reset_to_menu
.globl jump_reset_to_game

;;====================================================================
;; PRIVATE VARIABLES
;;====================================================================

m_score_player1: 			.db 0
m_score_player2: 			.db 0 ;;HEY!! This is also the score for the AI
m_round_over:	 			.db 0 ;;Whether the round has finished or not
m_level_over:	 			.db 0 ;;Whether the level is over or not (Player can fight against the next enemy)
m_game_over:     			.db 0 ;;Whether the game is over or not (by the AI or Player)
m_gamemode:: 	 			.db 0 ;;Gamemode 0 (Players vs AI) - Gamemode1 (Players vs Player)
m_should_draw_final_screen: .db 0 ;;Should paint final screen? (Win/Lose)

;;====================================================================
;; FUNCTIONS
;;====================================================================

;;====================================================================
;; INIT FUNCTIONS
;;====================================================================
man_game_init::
	call set_int_handler

	call man_game_init_variables

	;;Initialize the manager of entities
	call man_entity_init

	;;Check if the game is singleplayer or multiplayer
	ld a, (#m_gamemode)
	IS_EQUALS 1
	jr z, gamemode_multiplayer_init
		call sys_ai_init

	gamemode_multiplayer_init:
	;;Initialize the render for the game
	call sys_render_game_init

	;;Initialize the game entities
	call man_game_entities_init

	;;Draw the score of the current game
	call man_game_draw_score

	;;Draw the current progress of the game, in singlepplayer mode
	ld a, (#m_gamemode)
	IS_EQUALS 1
	jr z, is_multiplayer_game_init
		
	call man_game_draw_singleplayer_progress

	is_multiplayer_game_init:

	call sys_render_update

	call man_game_countdown

	ld de, #0xC394
	ld a, #00
	ld c, #5
	ld b, #20

	call cpct_drawSolidBox_asm
ret

man_game_init_variables:

    SET_VARIABLE_VALUE m_round_over, 0
    SET_VARIABLE_VALUE m_level_over, 0
    SET_VARIABLE_VALUE m_game_over, 0
	SET_VARIABLE_VALUE m_should_draw_final_screen, 0
ret

man_game_entities_init:

	ld hl, #player_tmpl
	call man_game_create_template_entity

	;;Check if the game is singleplayer or multiplayer
	ld a, (#m_gamemode)
	IS_EQUALS 1
	jr z, gamemode_multiplayer
	
	;;gamemode_singleplayer
	call man_game_create_template_enemy
	
	jr finish_game_init

	gamemode_multiplayer:
	ld hl, #player2_tmpl
	call man_game_create_template_entity

	finish_game_init:
	
	;;TRICK!! 
	call man_entity_create ;;This call is only to increment m_next_free_entity, returns dont matter
	call man_entity_create ;;This call is only to increment m_next_free_entity, returns dont matter
	
	call man_level_set_level_platforms

ret

;;====================================================================
;; UPDATE FUNCTIONS
;;====================================================================
man_game_update::
	ld a, (#current_interruption)
	IS_EQUALS 0
	ret nz

	call sys_music_game_update

	call sys_input_update

	call man_state_machines_update

	;;Check if it is multiplayer or single player mode to update or not the AI
	ld a, (#m_gamemode)
    IS_EQUALS 0
    jr nz, is_multi_player
		call sys_ai_update

	is_multi_player:
	call sys_physics_update

	call sys_collision_update

	call sys_animation_update

	;Aqui estaba el render
	call sys_render_update

	call man_entity_update
ret

;;====================================================================
;; TEMPLATES CREATION FUNCTIONS
;;====================================================================

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - HL: should contain the memory direction for the template to by created
;; Objetive: Creates an entity given a template
;; Modifies: BC
;; Returns: IY points to the created entity
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_create_template_entity::

	;;Man_entity_create uses a math macro that modifies HL
	push hl 

	call man_entity_create
	;;DE and IY conntais the memory direction

	pop hl

	;;HL contains the template and BC the size
	ld bc, #sizeof_e
	
	push de
	call cpct_memcpy_asm
	pop de
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - IX: should contain the memory direction of the entity that
;;        wants to create the bullet (Player)
;; Objetive: Creates a bullet from a player values (facing_right...)
;; Modifies: HL, BC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
total_jump = sizeof_e * 2
man_game_create_template_bullet::

	;;Suponemos que la bala del jugador 1 siempre va a estar en la tercera posicion de m_entities
	;;Suponemos que la bala del jugador 2 / enemy siempre va a estar en la cuarta posicion de m_entities

	;;Check if player has prev_bullet_ref
	ld a, e_bullet_ref_b2(ix)
	IS_EQUALS 0
	jp nz, player_had_prev_bullet_ref

	;;Now, IX is pointing to the player, pe: if we are player 1 (m_entities[0]), IX should point towards m_entites[2]
	push ix
	INCREMENT_REGISTER_2_BYTES ix, total_jump
	ld__hl_ix
	pop ix

	ld e_bullet_ref_b1(ix), l 
	ld e_bullet_ref_b2(ix), h

	player_had_prev_bullet_ref:

	;;If the ref bullet type is != invalid, we cant create a new bullet
	ld l, e_bullet_ref_b1(ix)
	ld h, e_bullet_ref_b2(ix)
	
	ld__iy_hl			;;IY contains the player's bullet memory direction
	ld a, e_type(iy)
	cp #e_type_invalid
	ret nz

	;;Check if the player is too close to the right/left border to dont shoot
	call man_game_is_player_far_from_border
	ret nc

	ld__hl_de ;;Charge in HL the bulelt_tmpl/enemy_bullet_tmpl

	ld__de_iy ;;Charge in DE the player's bullet memory direction		

	;;HL (from) contains the template. BC the size. DE (to) the memory direction to copy
	ld bc, #sizeof_e

	call cpct_memcpy_asm

	;;The bullet has been shot, change the input behaviour for the owner
	call man_entity_set_input_behaviour_shooting

	;;Set the attributes for the bullet
	call man_game_set_bullet_attributes
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - IX: should contain the memory direction of the entity that
;;        wants to create the bullet (Player/Enemy)
;;  - IY: should contain the memory direction of tbullet
;; Objetive: Check if the player is too close to the border to dont shoot
;; Modifies: A
;; Returns: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_is_player_far_from_border:
	
	;;Whether the player is facing right or left
	ld 	a, e_facing_right(ix)	
	IS_EQUALS -1
	jr z, owner_faces_left

	;;owner_faces_right
	ld a, e_pos_x(ix) ;;Position of the player
	INCREMENT_REGISTER_1_BYTE a, m_bullet_spawn_x_distance

    ;;Is the bullet > than right border?
	IS_HIGHER max_bullet_right_border
	ret nc

	;;Is the bullet < than the left border?
	IS_HIGHER 0xF9
	ret nc

	ret

	owner_faces_left:

	ld a, e_pos_x(ix) ;;Position of the player
	DECREMENT_REGISTER_1_BYTE a, m_bullet_spawn_x_distance

    ;;Is the bullet > than right border?
	IS_HIGHER max_bullet_right_border
	ret nc

	;;Is the bullet < than the left border?
	IS_HIGHER 0xFC
	ret nc

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - IX: should contain the memory direction of the entity that
;;        wants to create the bullet (Player/Enemy)
;;  - IY: should contain the memory direction of tbullet
;; Objetive: Set the attributes for the bullet based on a player
;; Modifies: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_set_bullet_attributes:
	;;Change the bullet values related to the player

	;;Whether the player is facing right (vel_x bullet 1) or not (vel_x bullet -1)
	ld          a, e_facing_right(ix)
	ld e_vel_x(iy),  a

	;;Spawning the bullet in front of the player + some x distance
	ld 			a, e_facing_right(ix)	
	IS_EQUALS -1
	jr z, bullet_face_left

	;;bullet_face_right
	ld          a, e_pos_x(ix)                          ;;
	INCREMENT_REGISTER_1_BYTE a, m_bullet_spawn_x_distance		;; Bullet.pos_x = Player.pos_x + m_bullet_spawn_x_distance(-)
	ld e_pos_x(iy), a									;;
	
	jr next_attribute

	bullet_face_left:
	ld          a, e_pos_x(ix)                          ;;
	DECREMENT_REGISTER_1_BYTE a, m_bullet_spawn_x_distance   	;; Bullet.pos_x = Player.pos_x + m_bullet_spawn_x_distance(+)
	ld e_pos_x(iy), a									;;

	next_attribute:

	ld          a, e_pos_y(ix)                          ;;
	add a, #7
	ld e_pos_y(iy), a                                   ;; Bullet.pos_y = Player.pos_y

	;;Setting the same facing right for the bullet as the player
	ld 					a, e_facing_right(ix)			;;
	ld e_facing_right(iy), a 							;; Bullet.facing_right = Player.facing_right

	;;Setting the bullet ref of the bullet to the player owner of the bullet
	ld__hl_ix
	ld e_bullet_ref_b1(iy), l
	ld e_bullet_ref_b2(iy), h

	;;Change the sprite of the bullet depending on the owner (level game)
	call man_level_select_bullet_sprite
	ld e_sprite_b1(iy), l
	ld e_sprite_b2(iy), h

	;;Change the animation of the bullet depending on the owner
	ld e_anim_b1(iy), c
	ld e_anim_b2(iy), b 
	
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - HL: should contain the memory direction for the template to by created
;; Objetive: Creates an enemy template given in HL, and select a random x position
;; Modifies: HL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_create_template_enemy:

	call man_level_select_enemy_template
	call man_game_create_template_entity
	call man_level_set_level_enemy_patrol

	;;Set random X position to spawn
	call cpct_getRandom_xsp40_u8_asm
    and #0x05
    add #69
    ld e_pos_x(iy), a ;;IY contains the memory direction of created entity
ret

;;====================================================================
;;====================================================================

;; GAME  MANAGMENT FUNCTIONS

;;====================================================================
;;====================================================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;  - IX: should contain the memory direction of the bullet
;;  - IY: should contain the memory direction of the dead player
;; Objetive: In case on of the players are dead, pre finish the game
;; Modifies: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_pre_finish_game::

	;;Check if the game is over to not do this
	ld a, (#m_round_over)
	IS_EQUALS 1
	ret z

	;;If the round wasn't over, do it
	SET_VARIABLE_VALUE m_round_over, 1

	;;Bullet finishim animation
	ld hl, #bullet_explosion
	ld e_anim_b1(ix), l
	ld e_anim_b2(ix), h
	call man_entity_set_type_to_dying_animation

	push ix
	ld__ix_iy
	;;Dead player finishim animation
	call man_entity_set_type_to_dying_animation
	pop ix

	;;Update the state machine to set the dead animation
	call man_state_machines_update

	;;Ban the players from moving
	call man_entity_disable_player_move

ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;		-
;; Objetive: In case on of the players are dead, finish the game
;; Modifies: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_finish_game::

	ld__iy_ix

	;;Update scores
	call man_game_update_players_score

	;;Draw the score of the current game
	call man_game_draw_score

	;;Now, we have to check, in case we are on singleplayer, we need to check if we should go to the next level o restart
	call man_game_should_next_level

	;;Draw the end options for the game
	call man_game_show_screen_options_after_game

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: Update the scores of the player depending on who won
;;			 the game
;; Modifies: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_update_players_score:

	;;Lets check who won the game
	IS_ENTITY_GIVEN_TYPE_IY e_type_player1
	jr z, player1_won

	ld a, (#m_gamemode)
	IS_EQUALS 0
	jr z, enemy_won
	
	;;player2_won:
	ld a, (#m_score_player2)
	inc a
	ld (#m_score_player2), a

	ret

	enemy_won:
	ld a, (#m_score_player2) 	
	inc a
	ld (#m_score_player2), a

	ret

	player1_won:
	ld a, (#m_score_player1)
	inc a
	ld (#m_score_player1), a
	
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: In case we are playing singleplayer
;; check if we have won at least 3 games to go to the next level.
;; Otherwise, if the AI have won 3 games we should reset the game
;; Modifies: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_should_next_level:
	
	;;Check if we have won at least 3 games
	ld a, (#m_score_player1)
	IS_EQUALS 3
	jr z, player_wins

	;;Player didnt win, check if AI did
	ld a, (#m_score_player2)
	IS_EQUALS 3
	ret nz

	;;AI or player2 wins:

	ld a, (#m_gamemode)
	IS_EQUALS 1
	jr z, player_wins

	;;The whole game has finished, AI won
	jr final_of_the_whole_game

	player_wins:
		INCREMENT_VARIABLE m_current_level, 1

		;;Now we have to check if m_current_level to reset the game
		ld a, (#m_current_level)
		IS_EQUALS 4
		jr z, final_of_the_whole_game
		
		call man_game_level_over_set
		
		ret

	final_of_the_whole_game:
		SET_VARIABLE_VALUE m_game_over, 1

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: Reset the game variables for a new game
;; Modifies: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_reset::

    SET_VARIABLE_VALUE m_score_player1, 0
    SET_VARIABLE_VALUE m_score_player2, 0
    SET_VARIABLE_VALUE m_round_over, 	0
    SET_VARIABLE_VALUE m_level_over, 	0
	SET_VARIABLE_VALUE m_current_level,	0
	SET_VARIABLE_VALUE m_should_draw_final_screen, 0
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: Set some game variables to finish the level
;; Modifies: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_level_over_set:

    SET_VARIABLE_VALUE m_score_player1, 0
	SET_VARIABLE_VALUE m_score_player2, 0
	SET_VARIABLE_VALUE m_level_over, 1
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: Set the game mode to Player vs AI
;; Modifies: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_set_gamemode_singleplayer::
	SET_VARIABLE_VALUE m_gamemode, 0
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;	-
;; Objetive: Set the game mode to Player vs Player
;; Modifies: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_set_gamemode_multiplayer::
	SET_VARIABLE_VALUE m_gamemode, 1
ret

;;====================================================================
;;====================================================================

;; VISUAL GAME FUNCTIONS

;;====================================================================
;;====================================================================

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;		-
;; Objetive: Show the options menu after the game finish, 
;;			 to play again o go back to the menu
;; Modifies: DE, A, CB, HL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
countdown_sprites:
	.dw #_spr_num_score_3
	.dw #_spr_num_score_2
	.dw #_spr_num_score_1
	.dw #0x0000
man_game_countdown: 

	ld e, #1

	;;ATTENCION!: The scores numbers H and W should be the game for all of them
	ld ix, #countdown_sprites - 2

	loop_count_down:
	INCREMENT_REGISTER_2_BYTES ix, 2

	repeat_counter:
	call cpct_waitVSYNCStart_asm
	dec e
	jr nz, repeat_counter

	ld a, 1(ix)
	IS_EQUALS 0
	ret z

	ld l, 0(ix)
	ld h, 1(ix)

	ld de, #0xC394	
	ld  c, #5
	ld  b, #20
	call cpct_drawSprite_asm

	ld e, #50
	jr loop_count_down

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;		-
;; Objetive: Show the options menu after the game finish, 
;;			 to play again o go back to the menu
;; Modifies: DE, A, CB, HL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
win_game_str: 		.asciz "YOU WIN!!"
lose_game_str: 		.asciz "YOU LOSE.."

player1_wins_str: 	.asciz "PLAYER 1 WINS"
player2_wins_str: 	.asciz "PLAYER 2 WINS"
ai_wins_str: 		.asciz "ENEMY WINS"

next_enemy_str: 	.asciz "SPACE.NEXT ENEMY"
next_round_str: 	.asciz "SPACE.NEXT ROUND"
next_game_str:  	.asciz "SPACE.NEXT GAME"
reset_game_str: 	.asciz "SPACE.RESET GAME"

back_menu_str: 		.asciz "ESC.MENU"

man_game_show_screen_options_after_game:
	;;Draw background rectangle
	ld de, #0xC1E8
    ld  a, #HW_PASTEL_YELLOW
    ld  c, #64
    ld  b, #64
    call cpct_drawSolidBox_asm

	ld h, #8
	ld l, #9
	call cpct_setDrawCharM0_asm

	;;Here we draw the strings
	call man_game_select_first_string_final_game

	ld a, (#m_should_draw_final_screen)
	IS_EQUALS 1
	jr z, loop_to_reset

    ld hl, #0xC28D
    call cpct_drawStringM0_asm

	call man_game_select_second_string_final_game
    ld hl, #0xC328
    call cpct_drawStringM0_asm

	ld iy, #back_menu_str
    ld hl, #0xDB80
	;;0xC3D0
    call cpct_drawStringM0_asm

	;;Here we draw the sprites to make the frame
	;;Left side
	ld hl, #_spr_intergame_frame_left_side
	ld de, #0xC1E5
	;Height, width
	ld b, #64
	ld c, #3
	call cpct_drawSprite_asm

	;;Right side
	ld hl, #_spr_intergame_frame_right_side
	ld de, #0xC228
	ld b, #64
	ld c, #3
	call cpct_drawSprite_asm

	;;Top left
	ld hl, #_spr_intergame_frame_top_left
	ld de, #0xC1E8
	ld b, #6
	ld c, #32
	call cpct_drawSprite_asm

	;;Top right
	ld hl, #_spr_intergame_frame_top_right
	ld de, #0xC208
	ld b, #6
	ld c, #32
	call cpct_drawSprite_asm

	;;Down left
	ld hl, #_spr_intergame_frame_down_left
	ld de, #0xD418
	ld b, #6
	ld c, #32
	call cpct_drawSprite_asm

	;;Down right
	ld hl, #_spr_intergame_frame_down_right
	ld de, #0xD438
	ld b, #6
	ld c, #32
	call cpct_drawSprite_asm
	
	;;Stop the music when someone dies
	call cpct_akp_stop_asm
	
	;;Check ESC and ENTER to reset to the game or menu in an infinite loop until a key is pressed 
	loop_to_reset:
		ld a, (#current_interruption)
		IS_EQUALS 1
   		jr nz, loop_to_reset

		ld hl, #Key_Space
		call cpct_isKeyPressed_asm
		jr nz, reset_to_the_game

		ld hl, #Joy0_Fire1
		call cpct_isKeyPressed_asm
		jr nz, reset_to_the_game

		ld hl, #Joy1_Fire1
		call cpct_isKeyPressed_asm
		jr nz, reset_to_the_game

		ld hl, #Key_Esc
		call cpct_isKeyPressed_asm
	jr z, loop_to_reset

	;;reset_to_the_menu
	ld hl, #jump_reset_to_menu
	jp (hl)

	reset_to_the_game:

	ld a, (#m_game_over)
	IS_EQUALS 1
	jr nz, game_is_not_over

	;;If our whole game is over we need to reset some variables
	call man_game_reset

	game_is_not_over:

	ld hl, #jump_reset_to_game
	jp (hl)

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;;		- IY: should contain the memory direction of the dead player
;; Objetive: Select what is the first part of the end screen of the game
;;			 Choose between YOU WIN.. YOU LOSE... PLAYER 1 WINS....
;; Modifies: DE, A, CB, HL
;; Returns:: IY: the str to draw
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_select_first_string_final_game:

	;;Check if multiplayer or single player
	ld a, (#m_gamemode)
	IS_EQUALS 0
	jr z, singleplayer_mode

	;;multiplayer_mode
		;;Lets check who won the game
		IS_ENTITY_GIVEN_TYPE_IY e_type_player1
		jr z, player1_won_string

		;;player2_won_string:
			ld iy, #player2_wins_str
			ret

		player1_won_string:
			ld iy, #player1_wins_str
			ret

	singleplayer_mode:

		ld a, (#m_game_over)
		IS_EQUALS 1
		jr z, game_is_over

		;;game_is_not_over
			IS_ENTITY_GIVEN_TYPE_IY e_type_player1
			jr nz, enemy_won_string

			;;player1_won_string:
			ld iy, #player1_wins_str
			ret

			enemy_won_string:
			ld iy, #ai_wins_str
			ret

		game_is_over:

			ld a, (#m_score_player1)
			IS_EQUALS 3
			jr z, player1_won_whole_game

			;;AI_won_whole_game
				ld hl, #_lose_screen_c_end
    			ld de, #0xFFFF
    			call cpct_zx7b_decrunch_s_asm
				SET_VARIABLE_VALUE m_should_draw_final_screen, 1
				ret

			player1_won_whole_game:
			    ld h, #HW_SKY_BLUE
				ld l, #0
				call cpct_setPALColour_asm
				ld hl, #_win_screen_c_end
    			ld de, #0xFFFF
    			call cpct_zx7b_decrunch_s_asm
				SET_VARIABLE_VALUE m_should_draw_final_screen, 1

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;		- 
;; Objetive: Select what is the second part of the end screen of the game
;;			 Choose between SPACE.NEXT ROUND.... NEXT ENEMY.. RESET GAME
;; Modifies: DE, A, CB, HL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_select_second_string_final_game:
	;;Check if multiplayer or single player
	ld a, (#m_gamemode)
	IS_EQUALS 0
	jr z, singleplayer_mode_2

	ld a, (#m_level_over)
	IS_EQUALS 1
	jr z, next_game_multiplayer

	ld a, (#m_game_over)
	IS_EQUALS 1
	jr z, next_game_multiplayer

	ld iy, #next_round_str
	ret

	next_game_multiplayer:
		ld iy, #next_game_str
	ret

	singleplayer_mode_2:

	ld a, (#m_game_over)
	IS_EQUALS 1
	jr z, game_over_second_str

	ld a, (#m_level_over)
	IS_EQUALS 1
	jr z, level_over_second_str

	;;round_over_second_str:
	ld iy, #next_round_str
	ret

	level_over_second_str:
	ld iy, #next_enemy_str
	ret

	game_over_second_str:
	ld iy, #reset_game_str

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;	- 
;; Objetive: Draw the current score of the match
;; Modifies: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_game_draw_score:

	;;First player score
	ld a, (#m_score_player1)
	call man_game_choose_player_score_sprite
	ld de, #0xE81D 

	call cpct_drawSprite_asm

	;;Separartion of both scores
	ld hl, #_spr_num_score_4
	ld de, #0xE824 
	ld  c, #5
	ld  b, #20
	call cpct_drawSprite_asm

	;;Second player score
	ld a, (#m_score_player2)
	call man_game_choose_player_score_sprite
	ld de, #0xE82B 

	call cpct_drawSprite_asm

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;	- A: shold contain the score of the current player
;; Objetive: Choose the sprite for the given score
;; Modifies: A
;; Returns: 
;;		- HL: the sprite to draw
;;		-  C: width of the sprite
;;		-  B: height of the sprite
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
score_sprites:
	.db 0
	.dw #_spr_num_score_0
	.db 1
	.dw #_spr_num_score_1
	.db 2
	.dw #_spr_num_score_2
	.db 3
	.dw #_spr_num_score_3
man_game_choose_player_score_sprite:

	;;ATTENCION!: The scores numbers H and W should be the game for all of them
	ld ix, #score_sprites - 3

	loop_scores:
	INCREMENT_REGISTER_2_BYTES ix, 3

	;;A already has the score
	cp (ix)
	jr nz, loop_scores

	;;The game level matchs
	ld l, 1(ix)
	ld h, 2(ix)	;; HL contains the sprite for the score for the game_level 

	ld c, #5
	ld b, #20

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre requirements
;		- 
;; Objetive: Draw the progress of the game in casea we are playing
;;			 on singleplayer mode. Draw the arrow in the current boss
;; Modifies: ?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
arrow_position_levels:
	.db 0	
	.dw #0xC053
	.db 1	
	.dw #0xC059
	.db 2	
	.dw #0xC05F
	.db 3	
	.dw #0xC065
man_game_draw_singleplayer_progress:
	ld ix, #arrow_position_levels - 3

	loop_progress_position:
	INCREMENT_REGISTER_2_BYTES ix, 3

	ld a, (#m_current_level)
	cp (ix)
	jr nz, loop_progress_position

	;:Draw the arrow
	ld hl, #_spr_progress_arrow
	
	ld e, 1(ix)
	ld d, 2(ix)

	ld a, (#m_current_level)
	IS_EQUALS 3
	jr z, not_update_arrow

	ld a, (#m_score_player1)
	add a, a
	add a, e
	ld e, a

	not_update_arrow:

	ld c, #4
	ld b, #4
	call cpct_drawSprite_asm

	;:Draw the progress line
	ld hl, #_spr_progress_line
	ld de, #0xC0A3
	ld c, #22
	ld b, #8
	call cpct_drawSprite_asm

ret