note
	description: "An object which does all the image rendering on a GAME_WINDOW"
	author: "Louis Marchand"
	date: "Thu, 02 Apr 2015 02:40:10 +0000"
	revision: "2.0"

class 
	GAME_RENDERER

create {GAME_WINDOW_RENDERED}
	make,
	make_with_flags,
	make_with_renderer_driver

feature {NONE} -- Initialization

	default_create
			-- Process instances of classes with no creation clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	make (a_window: GAME_WINDOW_RENDERED)
			-- Initialization for Current targeting a_window and
			-- using the first {RENDERER_DRIVER} found
		do
			make_with_renderer_driver_and_flags (a_window, -1, 0)
		ensure
			is_created: has_error or exists
		end

	make_with_flags (a_window: GAME_WINDOW_RENDERED; a_must_support_target_texture, a_must_sync_update, a_must_be_software_rendering, a_must_be_hardware_accelerated: BOOLEAN)
			-- Initialization for Current. If a_must_support_target_texture is True,
			-- the rendering context must permit to target to a texture instead of Current.
			-- If a_must_sync_update is True, the present will wait for vsync before finishing.
			-- If a_must_be_software_rendering is True, the renderer will always
		local
			l_flags: NATURAL_32
		do
			l_flags := 0
			if a_must_be_software_rendering then
				l_flags := l_flags.bit_or ({GAME_SDL_EXTERNAL}.sdl_renderer_software)
			end
			if a_must_be_hardware_accelerated then
				l_flags := l_flags.bit_or ({GAME_SDL_EXTERNAL}.sdl_renderer_accelerated)
			end
			if a_must_support_target_texture then
				l_flags := l_flags.bit_or ({GAME_SDL_EXTERNAL}.sdl_renderer_targettexture)
			end
			if a_must_sync_update then
				l_flags := l_flags.bit_or ({GAME_SDL_EXTERNAL}.sdl_renderer_presentvsync)
			end
			make_with_renderer_driver_and_flags (a_window, -1, l_flags)
		ensure
			is_created: has_error or exists
		end

	make_with_renderer_driver (a_window: GAME_WINDOW_RENDERED; a_renderer_driver: GAME_RENDERER_DRIVER)
			-- Initialization for Current targeting a_window using a specific a_renderer_driver
		do
			make_with_renderer_driver_and_flags (a_window, a_renderer_driver.index, 0)
		ensure
			is_created: has_error or exists
		end

	make_with_renderer_driver_and_flags (a_window: GAME_WINDOW_RENDERED; a_renderer_driver_index: INTEGER_32; a_flags: NATURAL_32)
			-- Initialization for Current targeting a_window, using a specific a_renderer_driver_index if not -1
			-- and using internal C a_flags if some provided.
		do
			original_target := a_window
			target := a_window
			clear_error
			item := {GAME_SDL_EXTERNAL}.sdl_createrenderer (a_window.item, a_renderer_driver_index, a_flags)
			manage_error_pointer (item, "Error while creating rendering context.")
			is_dispose := False
		ensure
			is_created: has_error or exists
		end
	
feature -- Access

	clear
			-- Fill the target with
			-- the drawing_color
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderclear (item)
			manage_error_code (l_error, "An error occured while clearing the renderer.")
		end

	clip_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
			-- Indicate what rectangle must be drawed when a draw is
			-- use. Every drawing outside of the rectangle will be
			-- ignored
		require
			renderer_exists: exists
		local
			l_rect: POINTER
		do
			l_rect := l_rect.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.sdl_rendergetcliprect (item, l_rect)
			Result := [{GAME_SDL_EXTERNAL}.get_rect_struct_x (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_y (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_w (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_h (l_rect)];
			l_rect.memory_free
		end

	disable_blending
			-- Disable every blending mode to use for drawing operations.
			-- No blending mode:	dstRGBA = srcRGBA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		do
			set_blend_mode ({GAME_SDL_EXTERNAL}.sdl_blendmode_none)
		end

	disable_clip_rectangle
			-- Remove every clip rectangle from Current
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendersetcliprect (item, create {POINTER})
			manage_error_code (l_error, "Cannot disable renderer clip rectangle")
		end

	draw_connected_lines (a_points: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32]])
			-- Draw connected lines using all (x, y) in a_points
		require
			renderer_exists: exists
		local
			l_array_points, l_point: POINTER
			l_point_size, l_error: INTEGER_32
		do
			l_point_size := {GAME_SDL_EXTERNAL}.c_sizeof_sdl_point
			l_array_points := l_array_points.memory_alloc (l_point_size * a_points.count)
			l_point := l_array_points
			across
				a_points as la_points
			loop
				{GAME_SDL_EXTERNAL}.set_point_struct_x (l_point, la_points.item.x)
				{GAME_SDL_EXTERNAL}.set_point_struct_y (l_point, la_points.item.y)
				l_point := l_point.plus (l_point_size)
			end
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawlines (item, l_array_points, a_points.count)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_array_points.memory_free
		end

	draw_filled_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Drawing a filled rectangle of dimension
			-- a_widthxa_height that has it's left frontier at
			-- a_x, it's top frontier at a_y.
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
			l_rect: POINTER
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle := normalize_rectangle (a_x, a_y, a_width, a_height)
			l_rect := l_rect.memory_alloc ({GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect, l_normalized_rectangle.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect, l_normalized_rectangle.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect, l_normalized_rectangle.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect, l_normalized_rectangle.height)
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderfillrect (item, l_rect)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_rect.memory_free
		end

	draw_filled_rectangles (a_rectangles: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]])
			-- Drawing every wire rectangle in a_rectangles
			-- that has it's left frontier at
			-- x, it's top frontier at y, with
			-- dimension widthxheight
		require
			renderer_exists: exists
		local
			l_array_rectangles, l_rectangle: POINTER
			l_rectangle_size, l_error: INTEGER_32
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_rectangle_size := {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect
			l_array_rectangles := l_array_rectangles.memory_alloc (l_rectangle_size * a_rectangles.count)
			l_rectangle := l_array_rectangles
			across
				a_rectangles as la_rectangles
			loop
				l_normalized_rectangle := normalize_rectangle (la_rectangles.item.x, la_rectangles.item.y, la_rectangles.item.width, la_rectangles.item.height)
				{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rectangle, l_normalized_rectangle.x)
				{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rectangle, l_normalized_rectangle.y)
				{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rectangle, l_normalized_rectangle.width)
				{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rectangle, l_normalized_rectangle.height)
				l_rectangle := l_rectangle.plus (l_rectangle_size)
			end
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderfillrects (item, l_array_rectangles, a_rectangles.count)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_array_rectangles.memory_free
		end

	draw_line (a_x1, a_y1, a_x2, a_y2: INTEGER_32)
			-- Draw a line from (a_x1, a_y1) to (a_x2, a_y2)
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawline (item, a_x1, a_y1, a_x2, a_y2)
			manage_error_code (l_error, "An error occured while drawing on the renderer.")
		end

	draw_point (a_x, a_y: INTEGER_32)
			-- Draw a point at (a_x, a_y)
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawpoint (item, a_x, a_y)
			manage_error_code (l_error, "An error occured while drawing on the renderer.")
		end

	draw_points (a_points: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32]])
			-- Draw points using all (x, y) in a_points
		require
			renderer_exists: exists
		local
			l_array_points, l_point: POINTER
			l_point_size, l_error: INTEGER_32
		do
			l_point_size := {GAME_SDL_EXTERNAL}.c_sizeof_sdl_point
			l_array_points := l_array_points.memory_alloc (l_point_size * a_points.count)
			l_point := l_array_points
			across
				a_points as la_points
			loop
				{GAME_SDL_EXTERNAL}.set_point_struct_x (l_point, la_points.item.x)
				{GAME_SDL_EXTERNAL}.set_point_struct_y (l_point, la_points.item.y)
				l_point := l_point.plus (l_point_size)
			end
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawpoints (item, l_array_points, a_points.count)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_array_points.memory_free
		end

	draw_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Drawing a wire rectangle of dimension
			-- a_widthxa_height that has it's left frontier at
			-- a_x, it's top frontier at a_y.
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
			l_rect: POINTER
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle := normalize_rectangle (a_x, a_y, a_width, a_height)
			l_rect := l_rect.memory_alloc ({GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect, l_normalized_rectangle.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect, l_normalized_rectangle.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect, l_normalized_rectangle.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect, l_normalized_rectangle.height)
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawrect (item, l_rect)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_rect.memory_free
		end

	draw_rectangles (a_rectangles: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]])
			-- Drawing every wire rectangle in a_rectangles
			-- that has it's left frontier at
			-- x, it's top frontier at y, with
			-- dimension widthxheight
		require
			renderer_exists: exists
		local
			l_array_rectangles, l_rectangle: POINTER
			l_rectangle_size, l_error: INTEGER_32
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_rectangle_size := {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect
			l_array_rectangles := l_array_rectangles.memory_alloc (l_rectangle_size * a_rectangles.count)
			l_rectangle := l_array_rectangles
			across
				a_rectangles as la_rectangles
			loop
				l_normalized_rectangle := normalize_rectangle (la_rectangles.item.x, la_rectangles.item.y, la_rectangles.item.width, la_rectangles.item.height)
				{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rectangle, l_normalized_rectangle.x)
				{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rectangle, l_normalized_rectangle.y)
				{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rectangle, l_normalized_rectangle.width)
				{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rectangle, l_normalized_rectangle.height)
				l_rectangle := l_rectangle.plus (l_rectangle_size)
			end
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_renderdrawrects (item, l_array_rectangles, a_rectangles.count)
			manage_error_code (l_error, "An error occured while drawing on the renderer.");
			l_array_rectangles.memory_free
		end

	draw_sub_texture (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width, a_height, a_x_destination, a_y_destination: INTEGER_32)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_widthxa_height on Current at (a_x_destination,a_y_destination)
		require
			renderer_exists: exists
		do
			draw_sub_texture_with_scale (a_texture, a_x_source, a_y_source, a_width, a_height, a_x_destination, a_y_destination, a_width, a_height)
		end

	draw_sub_texture_with_mirror (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination: INTEGER_32; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, use a vertical mirror on the drawed image if a_vertical_mirror
			-- is True and an horizontal one if a_horizontal_mirror is True.
		require
			renderer_exists: exists
		do
			draw_sub_texture_with_scale_rotation_and_mirror (a_texture, a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_source, a_height_source, 0, 0, 0.0, a_vertical_mirror, a_horizontal_mirror)
		end

	draw_sub_texture_with_rotation (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, rotate the draw of a_rotation_angle degree using the rotation center
			-- (a_x_rotation_center,a_y_rotation_center)
		require
			renderer_exists: exists
		do
			draw_sub_texture_with_scale_rotation_and_mirror (a_texture, a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_source, a_height_source, a_x_rotation_center, a_y_rotation_center, a_rotation_angle, False, False)
		end

	draw_sub_texture_with_scale (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_destination, a_height_destination: INTEGER_32)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination
		require
			renderer_exists: exists
		local
			l_rect_src, l_rect_dst: POINTER
			l_error: INTEGER_32
			l_normalized_rectangle_source, l_normalized_rectangle_destination: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle_source := normalize_rectangle (a_x_source, a_y_source, a_width_source, a_height_source)
			l_normalized_rectangle_destination := normalize_rectangle (a_x_destination, a_y_destination, a_width_destination, a_height_destination)
			l_rect_src := l_rect_src.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			l_rect_dst := l_rect_dst.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect_src, l_normalized_rectangle_source.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect_src, l_normalized_rectangle_source.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect_src, l_normalized_rectangle_source.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect_src, l_normalized_rectangle_source.height)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect_dst, l_normalized_rectangle_destination.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect_dst, l_normalized_rectangle_destination.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect_dst, l_normalized_rectangle_destination.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect_dst, l_normalized_rectangle_destination.height)
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendercopy (item, a_texture.item, l_rect_src, l_rect_dst)
			manage_error_code (l_error, "An error occured while drawing texture to the renderer.");
			l_rect_dst.memory_free;
			l_rect_src.memory_free
		end

	draw_sub_texture_with_scale_rotation_and_mirror (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_destination, a_height_destination, a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, rotate the draw of a_rotation_angle degree using the rotation center
			-- (a_x_rotation_center,a_y_rotation_center). Finally, use a vertical mirror on
			-- the drawed image if a_vertical_mirror is True and an horizontal one if
			-- a_horizontal_mirror is True.
		require
			renderer_exists: exists
		local
			l_rect_src, l_rect_dst, l_center_point: POINTER
			l_error, l_flip: INTEGER_32
			l_normalized_rectangle_source, l_normalized_rectangle_destination: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle_source := normalize_rectangle (a_x_source, a_y_source, a_width_source, a_height_source)
			l_normalized_rectangle_destination := normalize_rectangle (a_x_destination, a_y_destination, a_width_destination, a_height_destination)
			l_rect_src := l_rect_src.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			l_rect_dst := l_rect_dst.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect_src, l_normalized_rectangle_source.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect_src, l_normalized_rectangle_source.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect_src, l_normalized_rectangle_source.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect_src, l_normalized_rectangle_source.height)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect_dst, l_normalized_rectangle_destination.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect_dst, l_normalized_rectangle_destination.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect_dst, l_normalized_rectangle_destination.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect_dst, l_normalized_rectangle_destination.height)
			l_center_point := l_center_point.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_point)
			{GAME_SDL_EXTERNAL}.set_point_struct_x (l_center_point, a_x_rotation_center)
			{GAME_SDL_EXTERNAL}.set_point_struct_y (l_center_point, a_y_rotation_center)
			if a_vertical_mirror or a_horizontal_mirror then
				l_flip := 0
				if a_vertical_mirror then
					l_flip := l_flip.bit_or ({GAME_SDL_EXTERNAL}.sdl_flip_vertical)
				end
				if a_horizontal_mirror then
					l_flip := l_flip.bit_or ({GAME_SDL_EXTERNAL}.sdl_flip_horizontal)
				end
			else
				l_flip := {GAME_SDL_EXTERNAL}.sdl_flip_none
			end
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendercopyex (item, a_texture.item, l_rect_src, l_rect_dst, a_rotation_angle, l_center_point, l_flip)
			manage_error_code (l_error, "An error occured while drawing texture to the renderer.");
			l_center_point.memory_free;
			l_rect_dst.memory_free;
			l_rect_src.memory_free
		end

	draw_texture (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32)
			-- Draw the whole a_texture on Current at (a_x,a_y)
		require
			renderer_exists: exists
		do
			draw_sub_texture (a_texture, 0, 0, a_texture.width, a_texture.height, a_x, a_y)
		end

	draw_texture_with_mirror (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the whole a_texture on Current at (a_x,a_y)
			-- Also, use a vertical mirror on the drawed image if a_vertical_mirror
			-- is True and an horizontal one if a_horizontal_mirror is True.
		require
			renderer_exists: exists
		do
			draw_sub_texture_with_mirror (a_texture, 0, 0, a_texture.width, a_texture.height, a_x, a_y, a_vertical_mirror, a_horizontal_mirror)
		end

	draw_texture_with_rotation (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32; a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64)
			-- Draw the whole a_texture on Current at (a_x,a_y) rotate
			-- of a_rotation_angle degree with the rotation center at
			-- (a_x_rotation_center,a_y_rotation_center)
		require
			renderer_exists: exists
		do
			draw_sub_texture_with_rotation (a_texture, 0, 0, a_texture.width, a_texture.height, a_x, a_y, a_x_rotation_center, a_y_rotation_center, a_rotation_angle)
		end

	drawing_color: GAME_COLOR_READABLE assign set_drawing_color
			-- All performed drawing on Current is done
			-- using this color (including clear)
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
			l_red, l_green, l_blue, l_alpha: NATURAL_8
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_getrenderdrawcolor (item, $l_red.to_pointer, $l_green.to_pointer, $l_blue.to_pointer, $l_alpha.to_pointer)
			if l_error < 0 then
				manage_error_code (l_error, "An error occured while retreiving the drawing color of the renderer.")
				create Result.make_rgb (0, 0, 0)
			else
				create Result.make (l_red, l_green, l_blue, l_alpha)
			end
		end

	driver: GAME_RENDERER_DRIVER
			-- The driver used to render Current
		do
			create Result.make_from_renderer (Current)
		end

	enable_additive_blending
			-- Set the additive blending mode to use for drawing operations.
			-- Additive blending:	dstRGB = (srcRGB * srcA) + dstRGB
			--						dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		do
			set_blend_mode ({GAME_SDL_EXTERNAL}.sdl_blendmode_add)
		end

	enable_alpha_blending
			-- Set the alpha blending mode to use for drawing operations.
			-- Alpha blending:	dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
			--					dstA = srcA + (dstA * (1-srcA))
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		do
			set_blend_mode ({GAME_SDL_EXTERNAL}.sdl_blendmode_blend)
		end

	enable_modulate_blending
			-- Set the color modulate blending mode to use for drawing operations.
			-- Color modulate:	dstRGB = srcRGB * dstRGB
			--					dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		do
			set_blend_mode ({GAME_SDL_EXTERNAL}.sdl_blendmode_mod)
		end

	exists: BOOLEAN
			-- Is item a valid pointer to be used as blenderable
		do
			Result := not item.is_default_pointer and not is_dispose
		end

	generating_type: TYPE [detachable GAME_RENDERER]
			-- Type of current object
			-- (type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generating_type_not_void: Result /= Void
		end

	generator: STRING_8
			-- Name of current object's generating class
			-- (base class of the type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generator_not_void: Result /= Void
			generator_not_empty: not Result.is_empty
		end

	has_error: BOOLEAN
			-- Is the library has generate an error
			-- (from GAME_ERROR_MANAGER)

	is_additive_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is additive blending.
			-- Additive blending:	dstRGB = (srcRGB * srcA) + dstRGB
			--						dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		local
			l_blending_mode: INTEGER_32
		do
			l_blending_mode := blend_mode
			if not has_error then
				Result := l_blending_mode = {GAME_SDL_EXTERNAL}.sdl_blendmode_add
			else
				Result := False
			end
		end

	is_alpha_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is alpha blending.
			-- Alpha blending:	dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
			--					dstA = srcA + (dstA * (1-srcA))
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		local
			l_blending_mode: INTEGER_32
		do
			l_blending_mode := blend_mode
			if not has_error then
				Result := l_blending_mode = {GAME_SDL_EXTERNAL}.sdl_blendmode_blend
			else
				Result := False
			end
		end

	is_blending_disabled: BOOLEAN
			-- True if no blending mode is used for drawing operations.
			-- No blending mode:	dstRGBA = srcRGBA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		local
			l_blending_mode: INTEGER_32
		do
			l_blending_mode := blend_mode
			if not has_error then
				Result := l_blending_mode = {GAME_SDL_EXTERNAL}.sdl_blendmode_none
			else
				Result := False
			end
		end

	is_modulate_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is color modulate blending.
			-- Color modulate:	dstRGB = srcRGB * dstRGB
			--					dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists
		local
			l_blending_mode: INTEGER_32
		do
			l_blending_mode := blend_mode
			if not has_error then
				Result := l_blending_mode = {GAME_SDL_EXTERNAL}.sdl_blendmode_mod
			else
				Result := False
			end
		end

	last_error: READABLE_STRING_GENERAL
			-- The last error generate by the library
			-- (from GAME_SDL_ANY)
		local
			l_string: C_STRING
		do
			if is_manual_error then
				Result := Precursor {GAME_ERROR_MANAGER}
			else
				create l_string.make_by_pointer ({GAME_SDL_EXTERNAL}.sdl_geterror)
				Result := l_string.string
			end
		end

	logical_size: TUPLE [width: INTEGER_32; height: INTEGER_32]
			-- Get the device independant logical size of the output of Current
			-- [0,0] if never set..
			-- Modifying this value may change the scale and viewport values.
		require
			renderer_exists: exists
		local
			l_width, l_height: INTEGER_32
		do
			{GAME_SDL_EXTERNAL}.sdl_rendergetlogicalsize (item, $l_width.to_pointer, $l_height.to_pointer)
			Result := [l_width, l_height]
		end

	original_target: GAME_WINDOW_RENDERED
			-- The window that will be targetted
			-- (if no set_target has been called)
			-- command

	output_size: TUPLE [width: INTEGER_32; height: INTEGER_32]
			-- Get the size of the output of Current
		require
			renderer_exists: exists
		local
			l_error, l_width, l_height: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_getrendereroutputsize (item, $l_width.to_pointer, $l_height.to_pointer)
			manage_error_code (l_error, "Cannot retreive the output of the renderer.")
			Result := [l_width, l_height]
		end

	present
			-- Show the last drawed modification
		require
			renderer_exists: exists
		do
			{GAME_SDL_EXTERNAL}.sdl_renderpresent (item)
		end

	scale: TUPLE [x: REAL_32; y: REAL_32]
			-- Get the scale x and y that Current have to do when drawing.
			-- Note: For better performance, use integer scaling factor
		require
			renderer_exists: exists
		local
			l_x, l_y: REAL_32
		do
			{GAME_SDL_EXTERNAL}.sdl_rendergetscale (item, $l_x.to_pointer, $l_y.to_pointer)
			Result := [l_x, l_y]
		end

	set_clip_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Assign clip_rectangle with the values of a_x, a_y,
			-- a_width and a_height
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
			l_rect: POINTER
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle := normalize_rectangle (a_x, a_y, a_width, a_height)
			clear_error
			l_rect := l_rect.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect, l_normalized_rectangle.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect, l_normalized_rectangle.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect, l_normalized_rectangle.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect, l_normalized_rectangle.height)
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendersetcliprect (item, l_rect);
			l_rect.memory_free
			manage_error_code (l_error, "Cannot set renderer clip rectangle")
		ensure
			is_set: (attached clip_rectangle as la_clip_rectangle and attached normalize_rectangle (a_x, a_y, a_width, a_height) as la_normalized_rectangle) implies (la_clip_rectangle.x = la_normalized_rectangle.x and la_clip_rectangle.y = la_normalized_rectangle.y and la_clip_rectangle.width = la_normalized_rectangle.width and la_clip_rectangle.height = la_normalized_rectangle.height)
		end

	set_drawing_color (a_drawing_color: GAME_COLOR_READABLE)
			-- Assign the value of the drawing_color
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_setrenderdrawcolor (item, a_drawing_color.red, a_drawing_color.green, a_drawing_color.blue, a_drawing_color.alpha)
			manage_error_code (l_error, "An error occured while setting the drawing color of the renderer.")
		end

	set_logical_size (a_width, a_height: INTEGER_32)
			-- Assign logical_size using values in a_width and a_height.
			-- Using this feature may change the scale and viewport values.
		require
			renderer_exists: exists
			width_valid: a_width > 0
			height_valid: a_height > 0
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendersetlogicalsize (item, a_width, a_height)
			manage_error_code (l_error, "Cannot set the output logical size of the renderer.")
		ensure
			is_set: attached logical_size as la_logical_size implies (la_logical_size.width = a_width and la_logical_size.height = a_height)
		end

	set_original_target
			-- Put back the original_target as
			-- the target
		require
			renderer_exists: exists
		do
			set_target (original_target)
		end

	set_scale (a_x, a_y: REAL_32)
			-- Assign scale using values in a_x and a_y
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendersetscale (item, a_x, a_y)
			manage_error_code (l_error, "Cannot set the scaling of the renderer.")
		ensure
			is_set: attached scale as la_scale implies (la_scale.x = a_x and la_scale.y = a_y)
		end

	set_target (a_target: GAME_RENDER_TARGET)
			-- Assign what GAME_RENDER_TARGET to use when using the present
			-- command
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
		do
			clear_error
			if attached {GAME_TEXTURE} a_target as la_target then
				l_error := {GAME_SDL_EXTERNAL}.sdl_setrendertarget (item, la_target.item)
				if l_error = 0 then
					target := la_target
				else
					manage_error_code (l_error, "An error occured while setting the Renderer's target to texture.")
				end
			else
				if a_target = original_target then
					l_error := {GAME_SDL_EXTERNAL}.sdl_setrendertarget (item, create {POINTER})
					if l_error = 0 then
						target := original_target
					else
						manage_error_code (l_error, "An error occured while setting the Renderer's target to window.")
					end
				else
					put_manual_error ("Render target error", "Cannot set another screen as render target.")
				end
			end
		ensure
			is_set: not has_error implies target = a_target
		end

	set_viewport (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Assign viewport using values in a_x, a_y, a_width
			-- and a_height. Note that depending on the scale values,
			-- the viewport may be round to another close value.
		require
			renderer_exists: exists
		local
			l_error: INTEGER_32
			l_rect: POINTER
			l_normalized_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
		do
			l_normalized_rectangle := normalize_rectangle (a_x, a_y, a_width, a_height)
			clear_error
			l_rect := l_rect.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.set_rect_struct_x (l_rect, l_normalized_rectangle.x)
			{GAME_SDL_EXTERNAL}.set_rect_struct_y (l_rect, l_normalized_rectangle.y)
			{GAME_SDL_EXTERNAL}.set_rect_struct_w (l_rect, l_normalized_rectangle.width)
			{GAME_SDL_EXTERNAL}.set_rect_struct_h (l_rect, l_normalized_rectangle.height)
			l_error := {GAME_SDL_EXTERNAL}.sdl_rendersetviewport (item, l_rect);
			l_rect.memory_free
			manage_error_code (l_error, "Cannot set the viewport of the renderer.")
		ensure
			is_set: (attached viewport as la_viewport and attached scale as la_scale and attached normalize_rectangle (a_x, a_y, a_width, a_height) as la_normalized_rectangle) implies (la_viewport.x.to_double >= la_normalized_rectangle.x.to_double - (1.0 / la_scale.x.to_double) and la_viewport.x.to_double <= la_normalized_rectangle.x.to_double + (1.0 / la_scale.x.to_double) and la_viewport.y.to_double >= la_normalized_rectangle.y.to_double - (1.0 / la_scale.y.to_double) and la_viewport.y.to_double <= la_normalized_rectangle.y.to_double + (1.0 / la_scale.y.to_double) and la_viewport.width.to_double >= la_normalized_rectangle.width.to_double - (1.0 / la_scale.x.to_double) and la_viewport.width.to_double <= la_normalized_rectangle.width.to_double + (1.0 / la_scale.x.to_double) and la_viewport.height.to_double >= la_normalized_rectangle.height.to_double - (1.0 / la_scale.y.to_double) and la_viewport.height.to_double <= la_normalized_rectangle.height.to_double + (1.0 / la_scale.y.to_double))
		end

	target: GAME_RENDER_TARGET assign set_target
			-- What GAME_RENDER_TARGET to use when using the present

	viewport: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
			-- The position and size of the drawing area in Current
		require
			renderer_exists: exists
		local
			l_rect: POINTER
		do
			l_rect := l_rect.memory_calloc (1, {GAME_SDL_EXTERNAL}.c_sizeof_sdl_rect)
			{GAME_SDL_EXTERNAL}.sdl_rendergetviewport (item, l_rect)
			Result := [{GAME_SDL_EXTERNAL}.get_rect_struct_x (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_y (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_w (l_rect), {GAME_SDL_EXTERNAL}.get_rect_struct_h (l_rect)];
			l_rect.memory_free
		end
	
feature -- Comparison

	frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void
			-- or attached to isomorphic object structures?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_deep_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			shallow_implies_deep: standard_equal (a, b) implies Result
			both_or_none_void: (a = Void) implies (Result = (b = Void))
			same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
			symmetric: Result implies deep_equal (b, a)
		end

	frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached
			-- to objects considered equal?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b))
		end

	frozen is_deep_equal alias "≡≡≡" (other: GAME_RENDERER): BOOLEAN
			-- Are Current and other attached to isomorphic object structures?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			shallow_implies_deep: standard_is_equal (other) implies Result
			same_type: Result implies same_type (other)
			symmetric: Result implies other.is_deep_equal (Current)
		end

	is_equal (other: GAME_RENDERER): BOOLEAN
			-- Is other attached to an object considered
			-- equal to current object?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			symmetric: Result implies other ~ Current
			consistent: standard_is_equal (other) implies Result
		end

	frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached to
			-- field-by-field identical objects of the same type?
			-- Always uses default object comparison criterion.
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.standard_is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b))
		end

	frozen standard_is_equal alias "≜" (other: GAME_RENDERER): BOOLEAN
			-- Is other attached to an object of the same type
			-- as current object, and field-by-field identical to it?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			same_type: Result implies same_type (other)
			symmetric: Result implies other.standard_is_equal (Current)
		end
	
feature -- Status report

	conforms_to (other: ANY): BOOLEAN
			-- Does type of current object conform to type
			-- of other (as per Eiffel: The Language, chapter 13)?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		end

	same_type (other: ANY): BOOLEAN
			-- Is type of current object identical to type of other?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			definition: Result = (conforms_to (other) and other.conforms_to (Current))
		end
	
feature -- Duplication

	frozen clone (other: detachable ANY): like other
		obsolete "Use `twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- equal to other
			--
			-- For non-void other, clone calls copy;
			-- to change copying/cloning semantics, redefine copy.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.twin
			end
		ensure -- from ANY
			instance_free: class
			equal: Result ~ other
		end

	copy (other: GAME_RENDERER)
			-- Update current object using fields of object attached
			-- to other, so as to yield equal objects.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_equal: Current ~ other
		end

	frozen deep_clone (other: detachable ANY): like other
		obsolete "Use `deep_twin' instead. [2017-05-31]"
			-- Void if other is void: otherwise, new object structure
			-- recursively duplicated from the one attached to other
			-- (from ANY)
		do
			if other /= Void then
				Result := other.deep_twin
			end
		ensure -- from ANY
			instance_free: class
			deep_equal: deep_equal (other, Result)
		end

	frozen deep_copy (other: GAME_RENDERER)
			-- Effect equivalent to that of:
			--		copy (other . deep_twin)
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		do
			copy (other.deep_twin)
		ensure -- from ANY
			deep_equal: deep_equal (Current, other)
		end

	frozen deep_twin: GAME_RENDERER
			-- New object structure recursively duplicated from Current.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			deep_twin_not_void: Result /= Void
			deep_equal: deep_equal (Current, Result)
		end

	frozen standard_clone (other: detachable ANY): like other
		obsolete "Use `standard_twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.standard_twin
			end
		ensure -- from ANY
			instance_free: class
			equal: standard_equal (Result, other)
		end

	frozen standard_copy (other: GAME_RENDERER)
			-- Copy every field of other onto corresponding field
			-- of current object.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_standard_equal: standard_is_equal (other)
		end

	frozen standard_twin: GAME_RENDERER
			-- New object field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			standard_twin_not_void: Result /= Void
			equal: standard_equal (Result, Current)
		end

	frozen twin: GAME_RENDERER
			-- New object equal to Current
			-- twin calls copy; to change copying/twinning semantics, redefine copy.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			twin_not_void: Result /= Void
			is_equal: Result ~ Current
		end
	
feature -- Basic operations

	frozen as_attached: attached GAME_RENDERER
		obsolete "Remove calls to this feature. [2017-05-31]"
			-- Attached version of Current.
			-- (Can be used during transitional period to convert
			-- non-void-safe classes to void-safe ones.)
			-- (from ANY)
		do
			Result := Current
		end

	frozen default: detachable GAME_RENDERER
			-- Default value of object's type
			-- (from ANY)
		do
		end

	frozen default_pointer: POINTER
			-- Default value of type POINTER
			-- (Avoid the need to write p.default for
			-- some p of type POINTER.)
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end

	default_rescue
			-- Process exception for routines with no Rescue clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	frozen do_nothing
			-- Execute a null action.
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end
	
feature {NONE} -- Implementation

	blend_mode: INTEGER_32 assign set_blend_mode
			-- The alpha blending mode of Current
			-- (from GAME_BLENDABLE)
		local
			l_error, l_blending_mode: INTEGER_32
		do
			clear_error
			l_error := c_get_blend_mode (item, $l_blending_mode.to_pointer)
			if l_error < 0 then
				manage_error_code (l_error, "An error occured while retrieving the blending mode.")
				Result := 0
			end
			Result := l_blending_mode
		end

	clear_error
			-- Remove error pending in Current
			-- (from GAME_SDL_ANY)
		require -- from  GAME_ERROR_MANAGER
			True
		do
			{GAME_SDL_EXTERNAL}.sdl_clearerror
			Precursor {GAME_ERROR_MANAGER}
			is_manual_error := False
		ensure -- from GAME_ERROR_MANAGER
			no_error: not has_error
		ensure then -- from GAME_SDL_ANY
			no_error: not is_manual_error
		end

	disable_print_on_error
			-- Desactive the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (False)
		end

	enable_print_on_error
			-- Active the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (True)
		end

	is_manual_error: BOOLEAN
			-- Is the current pending error is a manual error (using manual_error as message)
			-- (from GAME_SDL_ANY)

	manage_error_boolean (a_boolean: BOOLEAN; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_boolean is false.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if not a_boolean then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				not a_boolean implies has_error
		end

	manage_error_code (a_error_code: INTEGER_32; a_message: READABLE_STRING_GENERAL)
			-- If needed create an error depending of the error code a_code.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_error_code < 0 then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		end

	manage_error_pointer (a_pointer: POINTER; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_pointer is not valid.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_pointer.is_default_pointer then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				a_pointer.is_default_pointer implies has_error
		end

	manual_error: detachable READABLE_STRING_GENERAL
			-- The specific message for the last error
			-- (from GAME_ERROR_MANAGER)

	normalize_rectangle (a_x, a_y, a_width, a_height: INTEGER_32): TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
			-- Adjust the rectangle delimited started at (a_x,a_y) and having
			-- dimensions a_widthxa_height so that the resulting rectangle
			-- never have a negative width or height
			-- (from GAME_DRAWING_TOOLS)
		local
			l_x, l_y: INTEGER_32
		do
			if a_width < 0 then
				l_x := a_x + a_width
			else
				l_x := a_x
			end
			if a_height < 0 then
				l_y := a_y + a_height
			else
				l_y := a_y
			end
			Result := [l_x, l_y, a_width.abs, a_height.abs]
		end

	print_on_error: BOOLEAN
			-- When an error occured, the library will print
			-- informations about the error on the error console
			-- output (default is True).
			-- (from GAME_ERROR_MANAGER)
		do
			Result := Print_on_error_internal.item
		end

	Print_on_error_internal: CELL [BOOLEAN]
			-- True when an error occured,
			-- The library will print it right away.
			-- (from GAME_ERROR_MANAGER)
		once ("PROCESS")
			create Result.put (True)
		end

	put_manual_error (a_general_message, a_specific_error: READABLE_STRING_GENERAL)
			-- Create an error using a_general_error for the debug information
			-- and a_specific_error for the lasting information
			-- (from GAME_SDL_ANY)
		do
			is_manual_error := True
			Precursor {GAME_ERROR_MANAGER} (a_general_message, a_specific_error)
		ensure -- from GAME_ERROR_MANAGER
				has_error
		end

	set_blend_mode (a_blend_mode: INTEGER_32)
			-- The alpha blending mode of Current
			-- (from GAME_BLENDABLE)
		local
			l_error: INTEGER_32
		do
			clear_error
			l_error := c_set_blend_mode (item, a_blend_mode)
			manage_error_code (l_error, "An error occured while enabling color modulate blending on the renderer.")
		end

	set_print_on_error (a_value: BOOLEAN)
			-- Assign to print_on_error the value of a_value
			-- (from GAME_ERROR_MANAGER)
		do
			if a_value then
				enable_print_on_error
			else
				disable_print_on_error
			end
		ensure -- from GAME_ERROR_MANAGER
			is_assign: print_on_error ~ a_value
		end
	
feature {GAME_SDL_ANY} 

	item: POINTER
			-- Internal representation of Current
	
feature {GAME_WINDOW_RENDERED} 

	dispose
		do
			is_dispose := False
		end

	is_dispose: BOOLEAN
			-- As Current has been dispose
	
feature {NONE} -- External

	c_get_blend_mode (a_item, a_blend_mode: POINTER): INTEGER_32
			-- Internal getter for blend mode
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_getrenderdrawblendmode (a_item, a_blend_mode)
		end

	c_set_blend_mode (a_item: POINTER; a_blend_mode: INTEGER_32): INTEGER_32
			-- Internal setter for blend mode
		do
			Result := {GAME_SDL_EXTERNAL}.sdl_setrenderdrawblendmode (a_item, a_blend_mode)
		end
	
feature -- Output

	Io: STD_FILES
			-- Handle to standard file setup
			-- (from ANY)
		once
			create Result;
			Result.set_output_default
		ensure -- from ANY
			instance_free: class
			io_not_void: Result /= Void
		end

	out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		do
			Result := tagged_out
		ensure -- from ANY
			out_not_void: Result /= Void
		end

	print (o: detachable ANY)
			-- Write terse external representation of o
			-- on standard output.
			-- (from ANY)
		local
			s: READABLE_STRING_8
		do
			if attached o then
				s := o.out
				if attached {READABLE_STRING_32} s as s32 then
					Io.put_string_32 (s32)
				elseif attached {READABLE_STRING_8} s as s8 then
					Io.put_string (s8)
				else
					Io.put_string_32 (s.as_string_32)
				end
			end
		ensure -- from ANY
			instance_free: class
		end

	frozen tagged_out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			tagged_out_not_void: Result /= Void
		end
	
feature -- Platform

	Operating_environment: OPERATING_ENVIRONMENT
			-- Objects available from the operating system
			-- (from ANY)
		once
			create Result
		ensure -- from ANY
			instance_free: class
			operating_environment_not_void: Result /= Void
		end
	
feature {NONE} -- Retrieval

	frozen internal_correct_mismatch
			-- Called from runtime to perform a proper dynamic dispatch on correct_mismatch
			-- from MISMATCH_CORRECTOR.
			-- (from ANY)
		local
			l_msg: STRING_32
			l_exc: EXCEPTIONS
		do
			if attached {MISMATCH_CORRECTOR} Current as l_corrector then
				l_corrector.correct_mismatch
			else
				create l_msg.make_from_string ("Mismatch: ".as_string_32)
				create l_exc;
				l_msg.append (generating_type.name_32);
				l_exc.raise_retrieval_exception (l_msg)
			end
		end
	
invariant
		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class GAME_RENDERER

Generated by ISE EiffelStudio