1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 666f4f3ced5003f24c048e6bacee8ffdb649a56e 166 lines 6.6 kB view raw
1-- ======================================================================== 2-- Renderer (scrolling world) 3-- world_col = pixel_column + cam_x 4-- world_row = pixel_row + cam_y 5-- All comparisons in world-space (11-bit). 6-- Obstacles imported from level package (use work.level.all). 7-- 8-- Color priority: 9-- Arrow = White (111) > Char = Red (100) > Obs = Yellow (110) 10-- > Ground/Ceil/Walls = Green (010) > Trail = Magenta (101) > Sky = Black (000) 11-- ======================================================================== 12 13library IEEE; 14use IEEE.STD_LOGIC_1164.all; 15use IEEE.STD_LOGIC_ARITH.all; 16use IEEE.STD_LOGIC_UNSIGNED.all; 17use work.level.all; 18 19entity renderer is 20 port( 21 pixel_row : in std_logic_vector(9 downto 0); 22 pixel_column : in std_logic_vector(9 downto 0); 23 char_x : in std_logic_vector(10 downto 0); 24 char_y : in std_logic_vector(10 downto 0); 25 char_width : in std_logic_vector(9 downto 0); 26 char_height : in std_logic_vector(9 downto 0); 27 cam_x : in std_logic_vector(10 downto 0); 28 cam_y : in std_logic_vector(10 downto 0); 29 vel_x_in : in std_logic_vector(9 downto 0); 30 vel_y_in : in std_logic_vector(9 downto 0); 31 trail_on_in : in std_logic; 32 red : out std_logic; 33 green : out std_logic; 34 blue : out std_logic 35 ); 36end renderer; 37 38architecture behavior of renderer is 39 40 -- World boundaries (11-bit) 41 constant GROUND_TOP : std_logic_vector(10 downto 0) := CONV_STD_LOGIC_VECTOR(1488, 11); 42 constant CEIL_BOT : std_logic_vector(10 downto 0) := CONV_STD_LOGIC_VECTOR(8, 11); 43 constant LEFT_WALL : std_logic_vector(10 downto 0) := CONV_STD_LOGIC_VECTOR(8, 11); 44 constant RIGHT_WALL : std_logic_vector(10 downto 0) := CONV_STD_LOGIC_VECTOR(1492, 11); 45 46 -- World-space pixel coordinates (shared between processes) 47 signal wc : std_logic_vector(10 downto 0); 48 signal wr : std_logic_vector(10 downto 0); 49 50 signal char_on, ground_on, wall_on, ceiling_on, obs_on, arrow_on : std_logic; 51 52begin 53 54 -- Convert screen coordinates to world coordinates 55 wc <= ('0' & pixel_column) + cam_x; 56 wr <= ('0' & pixel_row) + cam_y; 57 58 -- ---------------------------------------------------------------- 59 -- Scene geometry: character, world edges, obstacles 60 -- ---------------------------------------------------------------- 61 render : process(wc, wr, char_x, char_y, char_width, char_height) 62 begin 63 char_on <= '0'; 64 ground_on <= '0'; 65 wall_on <= '0'; 66 ceiling_on <= '0'; 67 obs_on <= '0'; 68 69 -- Character 70 if wc >= char_x - ('0' & char_width) and 71 wc <= char_x + ('0' & char_width) and 72 wr >= char_y - ('0' & char_height) and 73 wr <= char_y + ('0' & char_height) then 74 char_on <= '1'; 75 end if; 76 77 -- World edges 78 if wr >= GROUND_TOP then ground_on <= '1'; end if; 79 if wr <= CEIL_BOT then ceiling_on <= '1'; end if; 80 if wc < LEFT_WALL or wc > RIGHT_WALL then wall_on <= '1'; end if; 81 82 -- Obstacles (loop over level_pkg arrays) 83 for obs_i in 0 to OBS_COUNT-1 loop 84 if wc >= OBS_L(obs_i) and wc <= OBS_R(obs_i) and 85 wr >= OBS_T(obs_i) and wr <= OBS_B(obs_i) then 86 obs_on <= '1'; 87 end if; 88 end loop; 89 90 end process render; 91 92 -- ---------------------------------------------------------------- 93 -- Velocity vector arrow 94 -- Line from (char_x, char_y) to (char_x + 3*vx, char_y + 3*vy). 95 -- Uses cross-product line-segment test: 96 -- pixel on segment iff |dy*(px-x0) - dx*(py-y0)| <= max(|dx|,|dy|) 97 -- and dx*(px-x0) + dy*(py-y0) in [0, dx^2+dy^2] 98 -- ---------------------------------------------------------------- 99 arrow_proc : process(wc, wr, char_x, char_y, vel_x_in, vel_y_in) 100 variable wci, wri : integer; 101 variable cx, cy : integer; 102 variable vxi, vyi : integer; 103 variable dx, dy : integer; 104 variable cross : integer; 105 variable dot_p : integer; 106 variable len_sq : integer; 107 variable maxd : integer; 108 begin 109 wci := CONV_INTEGER(wc); 110 wri := CONV_INTEGER(wr); 111 cx := CONV_INTEGER(char_x); 112 cy := CONV_INTEGER(char_y); 113 114 -- Convert 10-bit 2's complement velocity to signed integer 115 if vel_x_in(9) = '1' then vxi := CONV_INTEGER(vel_x_in) - 1024; 116 else vxi := CONV_INTEGER(vel_x_in); end if; 117 if vel_y_in(9) = '1' then vyi := CONV_INTEGER(vel_y_in) - 1024; 118 else vyi := CONV_INTEGER(vel_y_in); end if; 119 120 -- Scale arrow by 3 for visibility 121 dx := vxi * 3; 122 dy := vyi * 3; 123 124 -- Precompute line metrics 125 cross := dy * (wci - cx) - dx * (wri - cy); 126 dot_p := dx * (wci - cx) + dy * (wri - cy); 127 len_sq := dx * dx + dy * dy; 128 129 -- Chebyshev thickness (~1-2 world-pixels wide) 130 maxd := dx; if maxd < 0 then maxd := -maxd; end if; 131 if dy > maxd then maxd := dy; 132 elsif -dy > maxd then maxd := -dy; end if; 133 134 arrow_on <= '0'; 135 if maxd > 4 then -- skip arrow when velocity is negligible 136 if cross >= -maxd and cross <= maxd and 137 dot_p >= 0 and dot_p <= len_sq then 138 arrow_on <= '1'; 139 end if; 140 end if; 141 end process arrow_proc; 142 143 -- ---------------------------------------------------------------- 144 -- Color output with priority 145 -- ---------------------------------------------------------------- 146 color : process(char_on, ground_on, wall_on, ceiling_on, 147 obs_on, arrow_on, trail_on_in) 148 begin 149 if arrow_on = '1' then 150 red <= '1'; green <= '1'; blue <= '1'; -- White 151 elsif char_on = '1' then 152 red <= '1'; green <= '0'; blue <= '0'; -- Red 153 elsif obs_on = '1' then 154 red <= '1'; green <= '1'; blue <= '0'; -- Yellow 155 elsif ground_on = '1' or ceiling_on = '1' then 156 red <= '0'; green <= '1'; blue <= '0'; -- Green 157 elsif wall_on = '1' then 158 red <= '0'; green <= '1'; blue <= '0'; -- Green 159 elsif trail_on_in = '1' then 160 red <= '1'; green <= '0'; blue <= '1'; -- Magenta 161 else 162 red <= '0'; green <= '0'; blue <= '0'; -- Black (sky) 163 end if; 164 end process color; 165 166end behavior;