diff --git a/source/world.adb b/source/world.adb index 31e7791..700a44f 100644 --- a/source/world.adb +++ b/source/world.adb @@ -52,6 +52,275 @@ package body world is ------------------------------------------------------------------------------------------ + procedure draw_tiles (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for vertical in view_from.y .. view_from.y + view_to.y loop + exit when vertical > map.height - 1; + -- + for horizontal in view_from.x .. view_from.x + view_to.x loop + exit when horizontal > map.width - 1; + -- + if map.views (horizontal, vertical) then + core.draw (data => tiles (map.kind), + x => offset.x + (horizontal - core.camera.x) * core.base * core.zoom, + y => offset.y + (vertical - core.camera.y) * core.base * core.zoom, + u => core.base * map.tiles (horizontal, vertical), + v => core.base * (core.animation_time mod tiles (map.kind).frames), + width => core.base, + height => core.base, + ignore => true); + -- + core.increment (drawn_tiles); + -- + if core.cursor.x > offset.x + (horizontal - core.camera.x ) * core.base * core.zoom - 6 + and core.cursor.x < offset.x + (horizontal - core.camera.x + 1) * core.base * core.zoom + 6 + and core.cursor.y > offset.y + (vertical - core.camera.y ) * core.base * core.zoom - 6 + and core.cursor.y < offset.y + (vertical - core.camera.y + 1) * core.base * core.zoom + 6 + and core.cursor_mode = core.cursor_left + and not ui.prioritize then + map.chads (1).x := horizontal; + map.chads (1).y := vertical; + core.cursor_mode := core.cursor_none; + end if; + end if; + end loop; + end loop; + -- + if core.animation_time = 0 then draw_tiles_timer := core.time - time; end if; + end draw_tiles; + + ------------------------------------------------------------------------------------------ + + procedure compute_world_visibility_grid (offset : in core.vector) is + begin + for vertical in 0 .. map.height - 1 loop + exit when offset.y + (vertical - core.camera.y) * core.base * core.zoom > core.window_height; + -- + for horizontal in 0 .. map.width - 1 loop + exit when offset.x + (horizontal - core.camera.x) * core.base * core.zoom > core.window_width; + -- + if not ((horizontal - core.camera.x) ** 2 + (vertical - core.camera.y) ** 2 > view_reach * 2) then + map.views (horizontal, vertical) := true; + end if; + end loop; + end loop; + end compute_world_visibility_grid; + + ------------------------------------------------------------------------------------------ + + procedure compute_world_frame (offset : in core.vector) is + x : constant integer := core.base * core.zoom * (-1 - core.camera.x) + offset.x; + y : constant integer := core.base * core.zoom * (-1 - core.camera.y) + offset.y; + width : constant integer := core.base * core.zoom * (map.width + 2); + height : constant integer := core.base * core.zoom * (map.height + 2); + begin + core.draw_horizontally (border_upper, x + core.base * core.zoom, y, width - 2 * core.base * core.zoom, core.zoom); + core.draw_horizontally (border_lower, x + core.base * core.zoom, y - core.base * core.zoom + height, width - 2 * core.base * core.zoom, core.zoom); + core.draw_vertically (border_left, x, y + core.base * core.zoom, height - 2 * core.base * core.zoom, core.zoom); + core.draw_vertically (border_right, x - core.base * core.zoom + width, y + core.base * core.zoom, height - 2 * core.base * core.zoom, core.zoom); + -- + core.draw (corner_upper_left, x, y, factor => core.zoom); + core.draw (corner_upper_right, x - core.base * core.zoom + width, y, factor => core.zoom); + core.draw (corner_lower_left, x, y - core.base * core.zoom + height, factor => core.zoom); + core.draw (corner_lower_right, x - core.base * core.zoom + width, y - core.base * core.zoom + height, factor => core.zoom); + end compute_world_frame; + + ------------------------------------------------------------------------------------------ + + procedure draw_landmarks (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for index in 1 .. landmark_limit loop + if map.views (map.landmarks (index).x, map.landmarks (index).y) + and map.landmarks (index).x > view_from.x and map.landmarks (index).x < view_from.x + view_to.x + and map.landmarks (index).y > view_from.y and map.landmarks (index).y < view_from.y + view_to.y then + core.draw (data => landmarks (landmark_index'val (map.landmarks (index).index)), + x => offset.x + (map.landmarks (index).x - core.camera.x) * core.base * core.zoom, + y => offset.y + (map.landmarks (index).y - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_landmarks); + -- + if core.cursor_inside (x => offset.x + (map.landmarks (index).x - core.camera.x) * core.base * core.zoom, + y => offset.y + (map.landmarks (index).y - core.camera.y) * core.base * core.zoom, + width => landmarks (landmark_index'val (map.landmarks (index).index)).width, + height => landmarks (landmark_index'val (map.landmarks (index).index)).height) + and core.cursor_mode = core.cursor_middle + and not ui.prioritize then + core.write_text_box (landmark_trait (landmark_index'val (map.landmarks (index).index)).name); + end if; + end if; + end loop; + -- + if core.animation_time = 0 then draw_landmarks_timer := core.time - time; end if; + end draw_landmarks; + + ------------------------------------------------------------------------------------------ + + procedure draw_locations (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for index in 1 .. location_limit loop + if map.views (map.locations (index).x, map.locations (index).y) + and map.locations (index).x > view_from.x and map.locations (index).x < view_from.x + view_to.x + and map.locations (index).y > view_from.y and map.locations (index).y < view_from.y + view_to.y then + core.draw (data => locations (location_index'val (map.locations (index).index)), + x => offset.x + (map.locations (index).x - core.camera.x) * core.base * core.zoom, + y => offset.y + (map.locations (index).y - core.camera.y) * core.base * core.zoom, + state => core.animation'val (map.locations (index).state)); + -- + core.increment (drawn_locations); + -- + if core.cursor_inside (x => offset.x + (map.locations (index).x - core.camera.x) * core.base * core.zoom, + y => offset.y + (map.locations (index).y - core.camera.y) * core.base * core.zoom, + width => locations (location_index'val (map.locations (index).index)).width, + height => locations (location_index'val (map.locations (index).index)).height) + and core.cursor_mode = core.cursor_middle + and not ui.prioritize then + core.write_text_box (location_trait (location_index'val (map.locations (index).index)).name); + end if; + end if; + -- + if map.locations (index).state = 1 and core.animation_time = 0 then + map.locations (index).state := 2; + end if; + -- + if core.camera.x > map.locations (index).x - 2 + and core.camera.x < map.locations (index).x + 1 + locations (location_index'val (map.locations (index).index)).width / core.base + and core.camera.y > map.locations (index).y - 2 + and core.camera.y < map.locations (index).y + 1 + locations (location_index'val (map.locations (index).index)).height / core.base + and map.locations (index).state = 0 + and core.signal_code'pos (core.signal_mode) = core.signal_code'pos (core.signal_e) + and not ui.prioritize then + effect.apply (location_trait (location_index'val (map.locations (index).index)).evoke); + -- + map.locations (index).state := 1; + end if; + end loop; + -- + if core.animation_time = 0 then draw_locations_timer := core.time - time; end if; + end draw_locations; + + ------------------------------------------------------------------------------------------ + + procedure draw_constructions (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for index in 1 .. construction_limit loop + if map.views (map.constructions (index).x, map.constructions (index).y) + and map.constructions (index).x > view_from.x and map.constructions (index).x < view_from.x + view_to.x + and map.constructions (index).y > view_from.y and map.constructions (index).y < view_from.y + view_to.y then + construction.draw_plus (construction.enumeration'val (map.constructions (index).index), + offset.x + (map.constructions (index).x - core.camera.x) * core.base * core.zoom, + offset.y + (map.constructions (index).y - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_constructions); + end if; + end loop; + -- + if core.animation_time = 0 then draw_constructions_timer := core.time - time; end if; + end draw_constructions; + + ------------------------------------------------------------------------------------------ + + procedure draw_equipments (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for index in 1 .. equipment_limit loop + if map.views (map.equipments (index).x, map.equipments (index).y) + and map.equipments (index).x > view_from.x and map.equipments (index).x < view_from.x + view_to.x + and map.equipments (index).y > view_from.y and map.equipments (index).y < view_from.y + view_to.y then + equipment.draw_plus (equipment.enumeration'val (map.equipments (index).index), + core.idle, + offset.x + (map.equipments (index).x - core.camera.x) * core.base * core.zoom, + offset.y + (map.equipments (index).y - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_equipments); + end if; + -- + if map.equipments (index).x = core.camera.x + and map.equipments (index).y = core.camera.y + and core.signal_code'pos (core.signal_mode) = core.signal_code'pos (core.signal_e) then + if chad.take_equipment_item (map.chads (1), equipment.enumeration'val (map.equipments (index).index)) then + map.equipments (index).index := equipment.enumeration'pos (equipment.none); + end if; + end if; + end loop; + -- + if core.animation_time = 0 then draw_equipments_timer := core.time - time; end if; + end draw_equipments; + + ------------------------------------------------------------------------------------------ + + procedure draw_units (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for index in 1 .. unit_limit loop + if map.views (map.units (index).x, map.units (index).y) + and map.units (index).x > view_from.x and map.units (index).x < view_from.x + view_to.x + and map.units (index).y > view_from.y and map.units (index).y < view_from.y + view_to.y then + unit.draw (unit.enumeration'val (map.units (index).index), + core.animation'val (map.units (index).state), + offset.x + (map.units (index).x - core.camera.x) * core.base * core.zoom, + offset.y + (map.units (index).y - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_units); + end if; + end loop; + -- + for index in 1 .. map.chad_count loop + if map.views (map.chads (index).x, map.chads (index).y) then + chad.draw (map.chads (index), + offset.x + (map.chads (index).x - core.camera.x) * core.base * core.zoom, + offset.y + (map.chads (index).y - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_units); + end if; + end loop; + -- + if core.animation_time = 0 then draw_units_timer := core.time - time; end if; + end draw_units; + + ------------------------------------------------------------------------------------------ + + procedure darken_map (offset, view_from, view_to : in core.vector) is + time : float := 0.0; + begin + time := core.time; + -- + for vertical in view_from.y .. view_from.y + view_to.y loop + exit when vertical > map.height - 1; + -- + for horizontal in view_from.x .. view_from.x + view_to.x loop + exit when horizontal > map.width - 1; + -- + if (horizontal - core.camera.x) ** 2 + (vertical - core.camera.y) ** 2 > view_reach then + core.draw (data => dark, + x => offset.x + (horizontal - core.camera.x) * core.base * core.zoom, + y => offset.y + (vertical - core.camera.y) * core.base * core.zoom); + -- + core.increment (drawn_views); + end if; + end loop; + end loop; + -- + if core.animation_time = 0 then draw_views_timer := core.time - time; end if; + end darken_map; + + ------------------------------------------------------------------------------------------ + procedure compute_earth_to_water_transition is matrix : array (0 .. 1, 0 .. 1) of natural; begin @@ -355,15 +624,13 @@ package body world is ------------------------------------------------------------------------------------------ procedure draw is - offset : core.vector := ((core.window_width - core.base) / 2, (core.window_height - core.base) / 2); + offset : core.vector := ((core.window_width - core.base) / 2, (core.window_height - core.base) / 2); view_from : core.vector := (core.camera.x - core.window_width / core.base / core.zoom / 2, core.camera.y - core.window_height / core.base / core.zoom / 2); view_to : core.vector := (core.window_width / core.base / core.zoom, core.window_height / core.base / core.zoom); -- - time_0 : float := 0.0; - time_1 : float := 0.0; + time : float := 0.0; begin - time_0 := core.time; - time_1 := core.time; + time := core.time; -- drawn_tiles := 0; drawn_views := 0; @@ -378,214 +645,18 @@ package body world is view_to.x := core.clip (view_to.x, 0, map.width - 1); view_to.y := core.clip (view_to.y, 0, map.height - 1); -- - for vertical in 0 .. map.height - 1 loop - exit when offset.y + (vertical - core.camera.y) * core.base * core.zoom > core.window_height; - -- - for horizontal in 0 .. map.width - 1 loop - exit when offset.x + (horizontal - core.camera.x) * core.base * core.zoom > core.window_width; - -- - if not ((horizontal - core.camera.x) ** 2 + (vertical - core.camera.y) ** 2 > view_reach * 2) then - map.views (horizontal, vertical) := true; - end if; - end loop; - end loop; + compute_world_visibility_grid (offset); + compute_world_frame (offset); -- - declare x : constant integer := core.base * core.zoom * (-1 - core.camera.x) + offset.x; - y : constant integer := core.base * core.zoom * (-1 - core.camera.y) + offset.y; - width : constant integer := core.base * core.zoom * (map.width + 2); - height : constant integer := core.base * core.zoom * (map.height + 2); - begin - core.draw_horizontally (border_upper, x + core.base * core.zoom, y, width - 2 * core.base * core.zoom, core.zoom); - core.draw_horizontally (border_lower, x + core.base * core.zoom, y - core.base * core.zoom + height, width - 2 * core.base * core.zoom, core.zoom); - core.draw_vertically (border_left, x, y + core.base * core.zoom, height - 2 * core.base * core.zoom, core.zoom); - core.draw_vertically (border_right, x - core.base * core.zoom + width, y + core.base * core.zoom, height - 2 * core.base * core.zoom, core.zoom); - -- - core.draw (corner_upper_left, x, y, factor => core.zoom); - core.draw (corner_upper_right, x - core.base * core.zoom + width, y, factor => core.zoom); - core.draw (corner_lower_left, x, y - core.base * core.zoom + height, factor => core.zoom); - core.draw (corner_lower_right, x - core.base * core.zoom + width, y - core.base * core.zoom + height, factor => core.zoom); - end; + draw_tiles (offset, view_from, view_to); + draw_landmarks (offset, view_from, view_to); + draw_locations (offset, view_from, view_to); + draw_constructions (offset, view_from, view_to); + draw_equipments (offset, view_from, view_to); + draw_units (offset, view_from, view_to); + darken_map (offset, view_from, view_to); -- - for vertical in view_from.y .. view_from.y + view_to.y loop - exit when vertical > map.height - 1; - -- - for horizontal in view_from.x .. view_from.x + view_to.x loop - exit when horizontal > map.width - 1; - -- - if map.views (horizontal, vertical) then - core.draw (data => tiles (map.kind), - x => offset.x + (horizontal - core.camera.x) * core.base * core.zoom, - y => offset.y + (vertical - core.camera.y) * core.base * core.zoom, - u => core.base * map.tiles (horizontal, vertical), - v => core.base * (core.animation_time mod tiles (map.kind).frames), - width => core.base, - height => core.base, - ignore => true); - -- - core.increment (drawn_tiles); - -- - if core.cursor.x > offset.x + (horizontal - core.camera.x ) * core.base * core.zoom - 6 - and core.cursor.x < offset.x + (horizontal - core.camera.x + 1) * core.base * core.zoom + 6 - and core.cursor.y > offset.y + (vertical - core.camera.y ) * core.base * core.zoom - 6 - and core.cursor.y < offset.y + (vertical - core.camera.y + 1) * core.base * core.zoom + 6 - and core.cursor_mode = core.cursor_left - and not ui.prioritize then - map.chads (1).x := horizontal; - map.chads (1).y := vertical; - core.cursor_mode := core.cursor_none; - end if; - end if; - end loop; - end loop; - -- - if core.animation_time = 0 then draw_tiles_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. landmark_limit loop - if map.views (map.landmarks (index).x, map.landmarks (index).y) - and map.landmarks (index).x > view_from.x and map.landmarks (index).x < view_from.x + view_to.x - and map.landmarks (index).y > view_from.y and map.landmarks (index).y < view_from.y + view_to.y then - core.draw (data => landmarks (landmark_index'val (map.landmarks (index).index)), - x => offset.x + (map.landmarks (index).x - core.camera.x) * core.base * core.zoom, - y => offset.y + (map.landmarks (index).y - core.camera.y) * core.base * core.zoom); - -- - core.increment (drawn_landmarks); - -- - if core.cursor_inside (x => offset.x + (map.landmarks (index).x - core.camera.x) * core.base * core.zoom, - y => offset.y + (map.landmarks (index).y - core.camera.y) * core.base * core.zoom, - width => landmarks (landmark_index'val (map.landmarks (index).index)).width, - height => landmarks (landmark_index'val (map.landmarks (index).index)).height) - and core.cursor_mode = core.cursor_middle - and not ui.prioritize then - core.write_text_box (landmark_trait (landmark_index'val (map.landmarks (index).index)).name); - end if; - end if; - end loop; - -- - if core.animation_time = 0 then draw_landmarks_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. location_limit loop - if map.views (map.locations (index).x, map.locations (index).y) - and map.locations (index).x > view_from.x and map.locations (index).x < view_from.x + view_to.x - and map.locations (index).y > view_from.y and map.locations (index).y < view_from.y + view_to.y then - core.draw (data => locations (location_index'val (map.locations (index).index)), - x => offset.x + (map.locations (index).x - core.camera.x) * core.base * core.zoom, - y => offset.y + (map.locations (index).y - core.camera.y) * core.base * core.zoom, - state => core.animation'val (map.locations (index).state)); - -- - core.increment (drawn_locations); - -- - if core.cursor_inside (x => offset.x + (map.locations (index).x - core.camera.x) * core.base * core.zoom, - y => offset.y + (map.locations (index).y - core.camera.y) * core.base * core.zoom, - width => locations (location_index'val (map.locations (index).index)).width, - height => locations (location_index'val (map.locations (index).index)).height) - and core.cursor_mode = core.cursor_middle - and not ui.prioritize then - core.write_text_box (location_trait (location_index'val (map.locations (index).index)).name); - end if; - end if; - -- - if map.locations (index).state = 1 and core.animation_time = 0 then - map.locations (index).state := 2; - end if; - -- - if core.camera.x > map.locations (index).x - 2 - and core.camera.x < map.locations (index).x + 1 + locations (location_index'val (map.locations (index).index)).width / core.base - and core.camera.y > map.locations (index).y - 2 - and core.camera.y < map.locations (index).y + 1 + locations (location_index'val (map.locations (index).index)).height / core.base - and map.locations (index).state = 0 - and core.signal_code'pos (core.signal_mode) = core.signal_code'pos (core.signal_e) - and not ui.prioritize then - effect.apply (location_trait (location_index'val (map.locations (index).index)).evoke); - -- - map.locations (index).state := 1; - end if; - end loop; - -- - if core.animation_time = 0 then draw_locations_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. construction_limit loop - if map.views (map.constructions (index).x, map.constructions (index).y) - and map.constructions (index).x > view_from.x and map.constructions (index).x < view_from.x + view_to.x - and map.constructions (index).y > view_from.y and map.constructions (index).y < view_from.y + view_to.y then - construction.draw_plus (construction.enumeration'val (map.constructions (index).index), - offset.x + (map.constructions (index).x - core.camera.x) * core.base * core.zoom, - offset.y + (map.constructions (index).y - core.camera.y) * core.base * core.zoom); - -- - core.increment (drawn_constructions); - end if; - end loop; - -- - if core.animation_time = 0 then draw_constructions_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. equipment_limit loop - if map.views (map.equipments (index).x, map.equipments (index).y) - and map.equipments (index).x > view_from.x and map.equipments (index).x < view_from.x + view_to.x - and map.equipments (index).y > view_from.y and map.equipments (index).y < view_from.y + view_to.y then - equipment.draw_plus (equipment.enumeration'val (map.equipments (index).index), - core.idle, - offset.x + (map.equipments (index).x - core.camera.x) * core.base * core.zoom, - offset.y + (map.equipments (index).y - core.camera.y) * core.base * core.zoom); - -- - core.increment (drawn_equipments); - end if; - -- - if map.equipments (index).x = core.camera.x - and map.equipments (index).y = core.camera.y - and core.signal_code'pos (core.signal_mode) = core.signal_code'pos (core.signal_e) then - if chad.take_equipment_item (map.chads (1), equipment.enumeration'val (map.equipments (index).index)) then - map.equipments (index).index := equipment.enumeration'pos (equipment.none); - end if; - end if; - end loop; - -- - if core.animation_time = 0 then draw_equipments_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. unit_limit loop - if map.views (map.units (index).x, map.units (index).y) - and map.units (index).x > view_from.x and map.units (index).x < view_from.x + view_to.x - and map.units (index).y > view_from.y and map.units (index).y < view_from.y + view_to.y then - unit.draw (unit.enumeration'val (map.units (index).index), - core.animation'val (map.units (index).state), - offset.x + (map.units (index).x - core.camera.x) * core.base * core.zoom, - offset.y + (map.units (index).y - core.camera.y) * core.base * core.zoom); - -- - core.increment (drawn_units); - end if; - end loop; - -- - if core.animation_time = 0 then draw_units_timer := core.time - time_0; time_0 := core.time; end if; - -- - for index in 1 .. map.chad_count loop - if map.views (map.chads (index).x, map.chads (index).y) then - chad.draw (map.chads (index), - offset.x + (map.chads (index).x - core.camera.x) * core.base * core.zoom, - offset.y + (map.chads (index).y - core.camera.y) * core.base * core.zoom); - end if; - end loop; - -- - for vertical in view_from.y .. view_from.y + view_to.y loop - exit when vertical > map.height - 1; - -- - for horizontal in view_from.x .. view_from.x + view_to.x loop - exit when horizontal > map.width - 1; - --~for vertical in 0 .. map.height - 1 loop - --~exit when offset.y + (vertical - core.camera.y) * core.base * core.zoom > core.window_height; - --~-- - --~for horizontal in 0 .. map.width - 1 loop - --~exit when offset.x + (horizontal - core.camera.x) * core.base * core.zoom > core.window_width; - -- - if (horizontal - core.camera.x) ** 2 + (vertical - core.camera.y) ** 2 > view_reach then - core.draw (data => dark, - x => offset.x + (horizontal - core.camera.x) * core.base * core.zoom, - y => offset.y + (vertical - core.camera.y) * core.base * core.zoom); - -- - core.increment (drawn_views); - end if; - end loop; - end loop; - -- - if core.animation_time = 0 then draw_views_timer := core.time - time_0; end if; - if core.animation_time = 0 then draw_world_timer := core.time - time_1; end if; + if core.animation_time = 0 then draw_world_timer := core.time - time; end if; end draw; ------------------------------------------------------------------------------------------