bouncy fpga game
www.youtube.com/watch?v=IiLWF3GbV7w
1-- ========================================================================
2-- Trail
3-- Stores 16 world-space positions (updated every 3 frames = ~0.8 s at 60 Hz).
4-- Combinationally checks each pixel against stored positions (radius 4 box).
5-- trail_on fires for any pixel within 4 world-pixels of any stored dot.
6-- ========================================================================
7
8library IEEE;
9use IEEE.STD_LOGIC_1164.all;
10use IEEE.STD_LOGIC_ARITH.all;
11use IEEE.STD_LOGIC_UNSIGNED.all;
12
13entity trail is
14 port(
15 vert_sync : in std_logic;
16 char_x : in std_logic_vector(10 downto 0);
17 char_y : in std_logic_vector(10 downto 0);
18 pixel_column : in std_logic_vector(9 downto 0);
19 pixel_row : in std_logic_vector(9 downto 0);
20 cam_x : in std_logic_vector(10 downto 0);
21 cam_y : in std_logic_vector(10 downto 0);
22 trail_on : out std_logic
23 );
24end trail;
25
26architecture behavior of trail is
27
28 constant TRAIL_LEN : integer := 16;
29 constant TRAIL_DIV : integer := 3; -- update once every 3 frames
30 constant TRAIL_RADIUS : integer := 4; -- Chebyshev radius in world-pixels
31
32 type pos_arr_t is array(0 to TRAIL_LEN-1) of std_logic_vector(10 downto 0);
33
34 signal tx : pos_arr_t := (others => (others => '0'));
35 signal ty : pos_arr_t := (others => (others => '0'));
36 signal trail_valid : std_logic_vector(TRAIL_LEN-1 downto 0) := (others => '0');
37 signal frame_ctr : integer range 0 to TRAIL_DIV-1 := 0;
38
39begin
40
41 -- Shift register: push new position every TRAIL_DIV frames
42 shift : process
43 begin
44 wait until vert_sync'event and vert_sync = '1';
45
46 if frame_ctr = TRAIL_DIV - 1 then
47 for i in TRAIL_LEN-1 downto 1 loop
48 tx(i) <= tx(i-1);
49 ty(i) <= ty(i-1);
50 trail_valid(i) <= trail_valid(i-1);
51 end loop;
52 tx(0) <= char_x;
53 ty(0) <= char_y;
54 trail_valid(0) <= '1';
55 frame_ctr <= 0;
56 else
57 frame_ctr <= frame_ctr + 1;
58 end if;
59 end process shift;
60
61 -- Pixel check: is current pixel within TRAIL_RADIUS of any valid trail dot?
62 check : process(pixel_column, pixel_row, cam_x, cam_y, tx, ty, trail_valid)
63 variable wci, wri : integer;
64 variable xi, yi : integer;
65 variable dx, dy : integer;
66 variable hit : std_logic;
67 begin
68 wci := CONV_INTEGER('0' & pixel_column) + CONV_INTEGER(cam_x);
69 wri := CONV_INTEGER('0' & pixel_row) + CONV_INTEGER(cam_y);
70 hit := '0';
71
72 for i in 0 to TRAIL_LEN-1 loop
73 if trail_valid(i) = '1' then
74 xi := CONV_INTEGER(tx(i));
75 yi := CONV_INTEGER(ty(i));
76 dx := wci - xi;
77 dy := wri - yi;
78 if dx < 0 then dx := -dx; end if;
79 if dy < 0 then dy := -dy; end if;
80 if dx <= TRAIL_RADIUS and dy <= TRAIL_RADIUS then
81 hit := '1';
82 end if;
83 end if;
84 end loop;
85
86 trail_on <= hit;
87 end process check;
88
89end behavior;