-------------------------------------------------------------------------------
--
-- VGA display main code
-- Author: Xin Zhang xz2270@columbia.edu
--		   Chenxi Liu cl2985@columbia.edu
--  	   Shengzhen Li sl3356@columbia.edu
-- Acknowledgement: Stephen A. Edwards sedwards@cs.columbia.edu
-- 
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity de2_vga_raster is
  
  port (
    reset : in std_logic;
    clk   : in std_logic;            -- Should be 25.125 MHz

    VGA_CLK,                         -- Clock
    VGA_HS,                          -- H_SYNC
    VGA_VS,                          -- V_SYNC
    VGA_BLANK,                       -- BLANK
    VGA_SYNC : out std_logic;        -- SYNC
    VGA_R,                           -- Red[9:0]
    VGA_G,                           -- Green[9:0]
    VGA_B : out std_logic_vector(9 downto 0); -- Blue[9:0]

    read       : in  std_logic;
    write      : in  std_logic;
    chipselect : in  std_logic;
    address    : in  unsigned(4 downto 0);
    readdata   : out signed(15 downto 0);
    writedata  : in  signed(15 downto 0)
);   

end de2_vga_raster;

architecture rtl of de2_vga_raster is

-- components declaration for frog, item, number, background, frogming
component item_controller 
  port(
clk50   : in std_logic;
clk25   : in std_logic;    
address: in unsigned (3 downto 0);
phase : in integer;
vertical: in integer;
horizontal: in integer;
itemflag : out std_logic;
pixel_R: out unsigned(3 downto 0);
pixel_G: out unsigned(3 downto 0);
pixel_B: out unsigned(3 downto 0)
  );
end component;

component frog_controller 
  port(
clk50   : in std_logic;
clk25   : in std_logic;    
address: in unsigned (1 downto 0);
frog_alive : in unsigned (1 downto 0);
direction: in integer;
vertical: in integer;
horizontal: in integer;
frogflag : out std_logic;
pixel_R: out unsigned(3 downto 0);
pixel_G: out unsigned(3 downto 0);
pixel_B: out unsigned(3 downto 0)
  );
end component;

component number_controller is
  port(
clk50   : in std_logic;
clk25   : in std_logic;    
address: in unsigned (5 downto 0);
vertical: in integer;
horizontal: in integer;
numflag : out std_logic;
charc : out unsigned (9 downto 0)
  );
end component;

component background_controller is
  port(
clk50   : in std_logic;
clk25   : in std_logic;    
address: in unsigned (4 downto 0);
vertical: in integer;
horizontal: in integer;
backflag : out std_logic;
pixel_R: out unsigned (3 downto 0);
pixel_G: out unsigned (3 downto 0);
pixel_B: out unsigned (3 downto 0)
  );
end  component;

component frogming_controller is
  port(
clk50   : in std_logic;
clk25   : in std_logic;    
address: in unsigned (1 downto 0);
vertical: in integer;
horizontal: in integer;
smallflag : out std_logic;
pixel_R: out unsigned (3 downto 0);
pixel_G: out unsigned (3 downto 0);
pixel_B: out unsigned (3 downto 0)
  );
end  component;

  -- Video parameters
  
  constant HTOTAL       : integer := 800;
  constant HSYNC        : integer := 96;
  constant HBACK_PORCH  : integer := 48;
  constant HACTIVE      : integer := 640;
  constant HFRONT_PORCH : integer := 16;
  
  constant VTOTAL       : integer := 525;
  constant VSYNC        : integer := 2;
  constant VBACK_PORCH  : integer := 33;
  constant VACTIVE      : integer := 480;
  constant VFRONT_PORCH : integer := 10;


  -- Horizontal and vertical signals for the video controller
  signal Hcount : unsigned(9 downto 0);  -- Horizontal position (0-800)
  signal Vcount : unsigned(9 downto 0);  -- Vertical position (0-524)
  signal EndOfLine, EndOfField : std_logic;
  signal Hscreen : integer;
  signal Vscreen : integer;
  signal time_vertical : integer;
  signal time_horizontal : integer;
  signal Htime : integer;
  signal Vtime : integer;
  signal hpile : integer := 0;
  signal vpile : integer := 0;
  signal num_horizontal : integer;
  signal num_vertical : integer;
  signal horizontal : integer;
  signal vertical : integer;
  signal frog_horizontal : integer;
  signal frog_vertical : integer;
  signal frog_x : integer := 224;
  signal frog_y : integer := 416;
  signal Hnumber : integer;  
  signal Vnumber : integer;
  signal Hback : integer;
  signal vga_hblank, vga_hsync,
    vga_vblank, vga_vsync : std_logic;  -- Sync. signals

  -- Signals for display items
  -- different flags for display
  signal frogflag : std_logic ;
  signal itemflag : std_logic ;
  signal backflag : std_logic ;
  signal numflag : std_logic;
  signal deadflag : std_logic := '0';
  signal smallflag : std_logic := '0';
  signal timeflag : std_logic := '0';
  signal jiamingflag : std_logic := '0';

  -- different color parameters as outputs from different ROMs
  signal color_R : unsigned(3 downto 0);
  signal color_G : unsigned(3 downto 0);
  signal color_B : unsigned(3 downto 0);

  signal frog_R : unsigned(3 downto 0);
  signal frog_G : unsigned(3 downto 0);
  signal frog_B : unsigned(3 downto 0);

  signal icolor_R : integer;
  signal icolor_G : integer;
  signal icolor_B : integer;

  signal back_R : unsigned(3 downto 0);
  signal back_G : unsigned(3 downto 0);
  signal back_B : unsigned(3 downto 0);

  signal small_R : unsigned(3 downto 0);
  signal small_G : unsigned(3 downto 0);
  signal small_B : unsigned(3 downto 0);

  signal charc : unsigned(9 downto 0);

  -- pattern number of different matrices
  signal patternNum : integer := 0; 
  signal back_num : integer;
  signal small_num : integer;

  -- corresponding input addresses to controllers
  signal sel_addr : unsigned (3 downto 0);
  signal sel_frog : unsigned (1 downto 0);
  signal sel_back : unsigned (4 downto 0);
  signal sel_small : unsigned (1 downto 0); 
  signal sel_num_addr : unsigned (5 downto 0);

  -- declaration of different tile matrices
  type pattern_offset is array (0 to 14) of integer;
  type pattern is array(integer range 0 to 14, integer range 0 to 15) of integer; 
  type scorepattern is array(integer range 0 to 1, integer range 0 to 10) of integer;
  type timepattern is array(0 to 7) of integer;

  signal offset : pattern_offset := (0,32,0,0,0,0,0,0,0,0,0,0,0,0,0);
  signal frog_offset : pattern_offset := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  signal speed : pattern_offset := (1,1,20,-4,60,-3,3,1,-3,4,-3,3,-4,1,1);

 constant river_pattern: pattern := (
( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
( 4,3,3,3,2,4,3,3,3,3,2,4,3,3,3,2), 
( 0,5,5,0,0,0,5,5,5,0,0,5,5,5,0,0), 
( 0,0,0,0,4,3,3,2,0,0,0,4,3,3,2,0), 
( 0,0,0,5,5,5,0,0,0,0,0,5,5,5,0,0), 
( 4,2,0,0,0,4,3,2,0,0,0,4,3,2,0,0), 
( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
( 0,0,9,10,0,0,0,9,10,0,0,0,9,10,0,0), 
( 0,8,0,0,0,8,0,0,0,0,0,8,0,0,0,0), 
( 7,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0), 
( 0,0,6,0,0,0,0,0,0,6,0,0,0,0,6,0), 
( 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0), 
( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) 
);

 signal background: pattern := (
( 20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21),
( 12,14,16,12,14,16,12,14,16,12,14,16,12,14,16,12),
( 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11), 
( 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11), 
( 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11), 
( 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11), 
( 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11), 
( 8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9), 
( 6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7), 
( 4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5),
( 4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5),
( 4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5), 
( 2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3), 
( 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1), 
( 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30)
);


----characters mapping to pattern numbers
----A   B  C  D  E  F  G  H  I  J K  L  M  N  O  P  Q  R  S  T  U  V  W   X  Y  Z
----10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

signal score_matrix : scorepattern := (
(36, 34, 24, 30, 27, 36, 28, 12, 24, 27, 14),
(36, 36, 36,  0,  0,  0,  0,  0, 36, 36, 36)
);

signal high_matrix : scorepattern := (
(36, 17, 18, 16, 17, 36, 28, 12, 24, 27, 14),
(36, 36, 36,  0,  0,  0,  0,  0, 36, 36, 36)
);

signal life_left : timepattern := (
(36, 36, 36, 21, 18, 15, 14, 36)
);
----------------------------------------
signal frogming : scorepattern := (
(0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2),
(0, 0, 0,  0,  0,  0,  0,  0, 0, 0, 0)
);
----------------------------------------
signal time_left : timepattern := (
36, 36, 29, 18, 22, 14, 36, 36
);

signal start_matrix : scorepattern := (
(36, 36, 36, 25, 27, 14, 28, 28, 36, 36, 36),
(36, 36, 36, 28, 25, 10, 12, 14, 36, 36, 36)
);

signal level_matrix : scorepattern :=(
(36, 36, 36, 21, 14, 31, 14, 21, 36, 36, 36),
(36, 36, 36, 36, 36, 0, 36, 36, 36, 36, 36)
);



  -- clk signals and count parameters
  signal clk25 : std_logic;
  signal clk_move : std_logic;
  signal counter : integer := 0;
  signal countermax : integer := 125000;
  signal count : integer := 0;
  signal i : integer;
  signal j : integer :=2;
  signal k : integer :=1;
  signal q : integer :=1;
  signal phase : integer := 1;
  signal pause : integer := 1;

  -- signals for frog actions
  signal frog_direction : integer := 1;
  signal frog_alive : unsigned (1 downto 0) := "00";
  signal frog_action : integer := 0;

  -- signals for game status
  signal timerange : integer := 300;
  signal frog_life : integer := 5;
  signal score_number : integer;
  signal score : integer := 0;
  signal winnum : integer := 0;
  signal highscore : integer := 0;

begin

  -- controller mapping
  ROM : item_controller port map (clk,clk25, sel_addr,phase,vertical,horizontal,itemflag,color_R,color_G,color_B);
  frog_ROM : frog_controller port map (clk,clk25, sel_frog,frog_alive,frog_direction,frog_vertical,frog_horizontal,frogflag,frog_R,frog_G,frog_B);
  number_ROM : number_controller port map (clk, clk25, sel_num_addr, num_vertical, num_horizontal, numflag,charc);
  back : background_controller port map (clk, clk25, sel_back, vertical, Hback, backflag, back_R, back_G, back_B);
  ming : frogming_controller port map (clk, clk25, sel_small, num_vertical, num_horizontal, smallflag, small_R, small_G, small_B);

  -- 25MHz generation
  process (clk)
  begin
    if rising_edge(clk) then
      clk25 <= not clk25;
    end if;
  end process; 
  
 -- counter for clk-move generation in order to control item movement
  process (clk25)
  begin
	if rising_edge (clk25) then
	  if counter  >= countermax - 30000 * (winnum/5) then
		counter <= 0;
		clk_move <= not clk_move;
	  else
		counter <= counter + 1;
	  end if;
	end if;
  end process;
	 
-- bottom time bar count down
Timecount: process (clk) 
	begin
		if rising_edge (clk) then
			if pause = 0 then
		    if frog_alive = "11" then
				count <= 1;
				timeflag <= '0';
			elsif count = 2500000 then
				count <= 1;
				timeflag <= '1';
			else
				timeflag <= '0';
				count <= count + 1;
			end if;
			end if;
		end if;
end process Timecount;
			
-- communication between hardware and software via Avalon bus
  Key: process (clk)
   begin
	if rising_edge(clk) then
		if chipselect = '1'  then
			if write = '1' then
				-- send current position, direction, action of the frog
				if to_integer(address) = 20  then
					frog_x <= to_integer(writedata) - frog_offset(frog_y/32);				
				elsif to_integer(address) = 21  then
					frog_y <= to_integer(writedata);
				elsif to_integer(address) = 22  then
					frog_direction <= to_integer(writedata);
				elsif to_integer(address) = 23  then
					frog_action <= to_integer(writedata);
			    -- receive pause signal
				elsif to_integer(address) = 25  then
					pause <= to_integer(writedata);
				-- display the score
				elsif to_integer(address) = 26 then
					score <= to_integer(writedata);
					score_matrix(1, 7) <= score mod 10;
					score_matrix(1, 6) <= (score mod 100)/10;
					score_matrix(1, 5) <= (score mod 1000)/100;
					score_matrix(1, 4) <= (score mod 10000)/1000;
					if score >= highscore then
						highscore <= score;
						high_matrix(1, 7) <= score_matrix(1, 7);
						high_matrix(1, 6) <= score_matrix(1, 6);
						high_matrix(1, 5) <= score_matrix(1, 5);
						high_matrix(1, 4) <= score_matrix(1, 4);				
					end if;
 				--detect whether the frog goes home, and the background matrix may change
				elsif to_integer(address) = 28  then
					if background(1, (to_integer(writedata)+16)/32) = 14 then
						background(1, (to_integer(writedata)+16)/32) <= 18;
						winnum <= winnum + 1;
						timerange <= 300;				
						if ((winnum + 1) mod 5) = 0 then
							background(1, 1) <= 14;
							background(1, 4) <= 14;
							background(1, 7) <= 14;
							background(1, 10) <= 14;
							background(1, 13) <= 14;
							jiamingflag <= '1';
						end if;
						frog_x <= 224;
						frog_y <= 416;
						frog_direction <= 1;
						frog_action <= 0;
					else
						deadflag <= '1';
						frog_action <= 0;
					end if;
				elsif to_integer(address) = 29  then
					if to_integer(writedata) = 1 then
						background(1, 1) <= 14;
						background(1, 4) <= 14;
						background(1, 7) <= 14;
						background(1, 10) <= 14;
						background(1, 13) <= 14;
						winnum <= 0;
						timerange <= 300;						
					end if;
				end if;
			elsif read = '1' then
				if to_integer(address) = 20 then
					readdata <= to_signed((frog_x + frog_offset(frog_y/32)), 16);
				elsif to_integer(address) = 21 then
					readdata <= to_signed(frog_y, 16);
				elsif to_integer(address) = 24 then
					readdata <= to_signed(to_integer(frog_alive), 16);
				elsif to_integer(address) = 25 then
					readdata <= to_signed(pause, 16);
				elsif to_integer(address) = 27 then
					readdata <= to_signed(frog_life, 16);	
				end if;
			end if;
		elsif frog_alive = "11" then
			frog_x <= 224;
			frog_y <= 416;
			frog_direction <= 1;
			deadflag <= '0';
			timerange <= 300;
			if frog_life = 0 then
				pause <= 1;
			end if;	
		elsif frog_alive = "00" then
			if timeflag = '1' then
				if timerange > 0 then
					timerange <= timerange - 1;
				end if;
			end if;
			if jiamingflag = '1' then
				jiamingflag <= '0';
			end if;
		end if;
	end if;
  end process Key;

  -- Horizontal and vertical counters

  HCounter : process (clk25)
  begin
    if rising_edge(clk25) then      
      if reset = '0' then
        Hcount <= (others => '0');
      elsif EndOfLine = '1' then
        Hcount <= (others => '0');
      else
        Hcount <= Hcount + 1;
      end if;      
    end if;
  end process HCounter;

  EndOfLine <= '1' when Hcount = HTOTAL - 1 else '0';
  
  VCounter: process (clk25)
  begin
    if rising_edge(clk25) then      
      if reset = '0' then
        Vcount <= (others => '0');
      elsif EndOfLine = '1' then
        if EndOfField = '1' then
          Vcount <= (others => '0');
        else
          Vcount <= Vcount + 1;
        end if;
      end if;
    end if;
  end process VCounter;

  EndOfField <= '1' when Vcount = VTOTAL - 1 else '0';

  -- State machines to generate HSYNC, VSYNC, HBLANK, and VBLANK

  HSyncGen : process (clk25)
  begin
    if rising_edge(clk25) then     
      if reset = '0' or EndOfLine = '1' then
        vga_hsync <= '1';
      elsif Hcount = HSYNC - 1 then
        vga_hsync <= '0';
      end if;
    end if;
  end process HSyncGen;
  
  HBlankGen : process (clk25)
  begin
    if rising_edge(clk25) then
      if reset = '0' then
        vga_hblank <= '1';
      elsif Hcount = HSYNC + HBACK_PORCH then
        vga_hblank <= '0';
      elsif Hcount = HSYNC + HBACK_PORCH + HACTIVE then
        vga_hblank <= '1';
      end if;      
    end if;
  end process HBlankGen;

  VSyncGen : process (clk25)
  begin
    if rising_edge(clk25) then
      if reset = '0' then
        vga_vsync <= '1';
      elsif EndOfLine ='1' then
        if EndOfField = '1' then
          vga_vsync <= '1';
        elsif Vcount = VSYNC - 1 then
          vga_vsync <= '0';

        end if;
      end if;      
    end if;
  end process VSyncGen;

  VBlankGen : process (clk25)
  begin
    if rising_edge(clk25) then    
      if reset = '0' then
        vga_vblank <= '1';
      elsif EndOfLine = '1' then
        if Vcount = VSYNC + VBACK_PORCH - 1 then
          vga_vblank <= '0';
        elsif Vcount = VSYNC + VBACK_PORCH + VACTIVE - 1 then
          vga_vblank <= '1';
        end if;
      end if;
    end if;
  end process VBlankGen;
  -- items generator
  
 -- item movement logic
  Move_item : process (clk_move)
  begin
	if rising_edge(clk_move) then
	if pause=0 then
	  if k = 30 then 
		if phase = 3 then phase <= 1;
	    else phase <= phase + 1;
	    end if;
	    k <= 1;
	  else k<= k+1;
	  end if;
	  if j = 5 then	j <= 2;		
	  else j <= j+1;
	  end if;
	  for i in 0 to 14 loop
	    if (abs(speed(i)) mod j) = 0 then
		  if speed(i) > 0 then
			offset(i) <= (offset(i)+1) mod 512;
		  else
			offset(i) <= (offset(i)-1) mod 512;
		  end if;
		end if;
	  end loop;
	  
		if frog_y mod 32 = 0 then
		  for i in 0 to 14 loop
			if i = frog_y/32 then
			  if (abs(speed(i)) mod j) = 0 then
				if frog_x + frog_offset(i) + speed(i)/(abs(speed(i))) >= 0 and frog_x + frog_offset(i) + speed(i)/(abs(speed(i))) < 480 and frog_y >= 0 and frog_y < 224 then
					if speed(i) > 0 then
					  frog_offset(i) <= frog_offset(i) + 1;
					else
					  frog_offset(i) <= frog_offset(i) - 1;
					end if;
				end if;
		      end if;
			else
				frog_offset(i) <= 0;
			end if;
		  end loop;
		end if;
	end if;  
	end if;
  end process Move_item;

 -- frog action logic
  Logic : process (clk)
  begin 
	if rising_edge (clk) then
	level_matrix(1, 5) <= winnum/5 + 1;
	if pause = 0 then
		start_matrix <= ((36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36),
						(36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36)
						);	
	if frog_action = 0 then
	case frog_alive is
	when "00" => --alive
	  if jiamingflag = '1' then
		  frog_life <= frog_life + 1;
		  if frog_life + 1 > 5 then
			 frogming(1, 2 * (frog_life - 4)) <= 2;
			 frogming(1, 2 * (frog_life - 4)- 1) <= 1;
		  else
			 frogming(0, 2 * (frog_life + 1)) <= 2;
			 frogming(0, 2 * (frog_life + 1)- 1) <= 1;	
		  end if;		 
	  elsif deadflag = '1' or timerange <= 0 then
	      frog_alive <= "01";
		  frog_life <= frog_life - 1;	
		  if frog_life > 5 then
			 frogming(1, 2 * (frog_life - 5)) <= 0;
			 frogming(1, 2 * (frog_life - 5)- 1) <= 0;
		  else
			 frogming(0, 2 * frog_life) <= 0;
			 frogming(0, 2 * frog_life - 1) <= 0;
		  end if;		  
	  elsif frog_y >= 224 then
  	    if river_pattern (frog_y/32,((frog_x + 4 + frog_offset(frog_y/32) + 1 - offset(frog_y/32)) mod 512)/32) = 0 and river_pattern (frog_y/32,((frog_x + 28 + frog_offset(frog_y/32) + 1 - offset(frog_y/32)) mod 512)/32) = 0 then
  		  frog_alive <= "00";
	    else
		  frog_alive <= "01";
		  frog_life <= frog_life - 1;
		  if frog_life > 5 then
			 frogming(1, 2 * (frog_life - 5)) <= 0;
			 frogming(1, 2 * (frog_life - 5)- 1) <= 0;
		  else
			 frogming(0, 2 * frog_life) <= 0;
			 frogming(0, 2 * frog_life - 1) <= 0;
	      end if;
	    end if;
	  elsif frog_y >=64 then
		if river_pattern (frog_y/32,((frog_x + 16 + frog_offset(frog_y/32) + 1 - offset(frog_y/32)) mod 512)/32) > 0 then
		  frog_alive <= "00";
		else
		  frog_alive <= "01";
		  frog_life <= frog_life - 1;
		  if frog_life > 5 then
			 frogming(1, 2 * (frog_life - 5)) <= 0;
			 frogming(1, 2 * (frog_life - 5)- 1) <= 0;
		  else
			 frogming(0, 2 * frog_life) <= 0;
			 frogming(0, 2 * frog_life - 1) <= 0;
		  end if;
		end if;
	  end if;
	
	when "01" => --dead
	      if q = 15000000 then
	        q <= 1;
	        frog_alive <= "10";
	      else
			q <= q + 1;
		  end if;
	when "10" =>
		  if q = 15000000 then
	        q <= 1;
	        frog_alive <= "11";
	      else
			q <= q + 1;
		  end if;
	when "11" =>
		 if frog_life = 0 then
			frog_life <= 5;
			frogming(0,1) <= 1;
			frogming(0,3) <= 1;
			frogming(0,5) <= 1;
			frogming(0,7) <= 1;
			frogming(0,9) <= 1;
			frogming(0,2) <= 2;
			frogming(0,4) <= 2;
			frogming(0,6) <= 2;
			frogming(0,8) <= 2;
			frogming(0,10) <= 2;					
		end if;
	      frog_alive <= "00";
	end case;		  
	end if;
	else
		start_matrix <= ((36, 36, 36, 25, 27, 14, 28, 28, 36, 36, 36),
						(36, 36, 36, 28, 25, 10, 12, 14, 36, 36, 36)
						);
	end if;
	end if;
  end process Logic;

 -- bakcground, item, frog display
  Display_item : process (clk25)
  begin
    if rising_edge(clk25) then 
	  Hscreen <= to_integer(Hcount) - HBACK_PORCH  - HSYNC + 1 ;
	  Vscreen <= to_integer(Vcount) - VBACK_PORCH - VSYNC  ;

	  if Hscreen >= 0 and Hscreen < 512 and Vscreen >=0 and Vscreen < 480 then
        patternNum <= river_pattern (Vscreen/32,((Hscreen-offset(Vscreen/32)) mod 512)/32);
		if Vscreen >= 64 then
			back_num <= background(Vscreen/32,(Hscreen + 1)/32);
		else
			back_num <= background(Vscreen/32,(Hscreen)/32);
		end if;

		horizontal <= (Hscreen - offset(Vscreen/32)) mod 32;
		vertical <= Vscreen mod 32;
	    Hback <= Hscreen mod 32;
	    sel_addr <= to_unsigned(patternNum,4);
		sel_back <= to_unsigned(back_num,5);
		
		--draw frog
		if  Hscreen >= (frog_x + frog_offset(frog_y/32)) and Hscreen < ((frog_x + frog_offset(frog_y/32)) + 32)  and Vscreen >= frog_y and Vscreen < frog_y + 32 then
		  frog_horizontal <= Hscreen - (frog_x + frog_offset(frog_y/32)) ;
		  frog_vertical   <= Vscreen - frog_y;
		
		case frog_action is
		  when 0 =>
		    sel_frog <= "01"; --static
		  when 1 =>
			sel_frog <= "11"; --jump
		  when others =>
			sel_frog <= "00"; --frogflag = '0'
		end case;
		else
		  sel_frog <= "00";
		end if;
	  else 
	    sel_addr <= "0000";
	    sel_frog <= "00";
		sel_back <= "11111";
	  end if;
	end if;	
  end process Display_item;

-- scoreboard pattern setting
Display_number: process(clk25)
begin
 if rising_edge(clk25) then
	Hnumber <= to_integer(Hcount) - HBACK_PORCH  - HSYNC - 512 - 8;
	Vnumber <= to_integer(Vcount) - VBACK_PORCH - VSYNC;
	--display score on the screen
	if Hnumber >= 0 and Hnumber < 88 and Vnumber >= 36 and Vnumber < 492 then
		num_horizontal <= Hnumber mod 8;
		if Vnumber >= 36 and Vnumber < 68 then
			score_number <= score_matrix((Vnumber - 36)/16, (Hnumber + 2)/8);
			num_vertical <= (Vnumber - 36) mod 16;
		elsif Vnumber >= 120 and Vnumber < 152 then
			score_number <= high_matrix((Vnumber - 120)/16, (Hnumber + 2)/8);
			num_vertical <= (Vnumber - 120) mod 16;		
		elsif Vnumber >= 210 and Vnumber < 226 then
			score_number <= life_left((Hnumber + 2)/8);
			num_vertical <= (Vnumber - 210) mod 16;
		elsif Vnumber >= 226 and Vnumber < 258 then
			small_num <= frogming((Vnumber - 226)/16, (Hnumber)/8);
			num_vertical <= (Vnumber - 226) mod 16;
		elsif Vnumber >= 318 and Vnumber < 350 then
			score_number <= level_matrix((Vnumber - 318)/16, (Hnumber + 2)/8);
			num_vertical <= (Vnumber - 318) mod 16;
		elsif Vnumber >= 410 and Vnumber < 442 then
			score_number <= start_matrix((Vnumber - 410)/16, (Hnumber + 2)/8);
			num_vertical <= (Vnumber - 410) mod 16;
		end if;
	elsif Hscreen >= 0 and Hscreen < 64 and Vnumber >= 456 and Vnumber < 472 then
		score_number <= time_left((Hscreen + 2)/8);
		num_vertical <= (Vnumber - 456) mod 16;
		num_horizontal <= Hscreen mod 8;
	else
		score_number <= 36;		--set score_number to display nothing
		small_num <= 3;
	end if;
	case small_num is
		when 0 => sel_small <= "00";
		when 1 => sel_small <= "01";
		when 2 => sel_small <= "10";
		when others => sel_small <= "11";
	end case;
	sel_num_addr <= to_unsigned(score_number,6);  
 end if;
end process Display_number;

-- video out rules
  VideoOut : process(clk25,reset)
  begin
	if reset = '0' then
      VGA_R <= "0000000000";
      VGA_G <= "0000000000";
      VGA_B <= "0000000000";
    elsif clk25'event and clk25 = '1' then
        if frogflag = '1' then
          VGA_R <= std_logic_vector(frog_R & "000000");
          VGA_G <= std_logic_vector(frog_G & "000000");
          VGA_B <= std_logic_vector(frog_B & "000000");
	    elsif itemflag = '1' then
          VGA_R <= std_logic_vector(color_R & "000000");
          VGA_G <= std_logic_vector(color_G & "000000");
          VGA_B <= std_logic_vector(color_B & "000000");
		elsif backflag = '1' then
          VGA_R <= std_logic_vector(back_R & "000000");
          VGA_G <= std_logic_vector(back_G & "000000");
          VGA_B <= std_logic_vector(back_B & "000000");
		elsif numflag = '1' and Hnumber <= 89 then  
		  VGA_R <= std_logic_vector(charc);
          VGA_G <= std_logic_vector(charc);
          VGA_B <= std_logic_vector(charc);
		elsif smallflag = '1' then
          VGA_R <= std_logic_vector(small_R & "000000");
          VGA_G <= std_logic_vector(small_G & "000000");
          VGA_B <= std_logic_vector(small_B & "000000");		  
		elsif (Hcount - HSYNC - HBACK_PORCH >= 128) and (Hcount - HSYNC - HBACK_PORCH <= 128 + timerange) and (Vcount - VSYNC - VBACK_PORCH >= 456) and (Vcount - VSYNC - VBACK_PORCH < 472) then
			if timerange > 75 then
			  VGA_R <= "0000000000";
			  VGA_G <= "1111111111";
			  VGA_B <= "0000000000";
			else
				-- times up warning
				if (timerange mod 5) = 0 then
					VGA_R <= "0000000000";
					VGA_G <= "1111111111";
					VGA_B <= "0000000000";
				else
					VGA_R <= "1111111111";
					VGA_G <= "0000000000";
					VGA_B <= "0000000000";
				end if;
			end if;
		elsif vga_hblank = '0' and vga_vblank ='0' then
          VGA_R <= "0000000000";
          VGA_G <= "0000000000";
          VGA_B <= "0000000000";
		else
		  VGA_R <= "0000000000";
          VGA_G <= "0000000000";
          VGA_B <= "0000000000";  
		end if;   
    end if;
  end process VideoOut;
  

  VGA_CLK <= clk25;
  VGA_HS <= not vga_hsync;
  VGA_VS <= not vga_vsync;
  VGA_SYNC <= '0';
  VGA_BLANK <= not (vga_hsync or vga_vsync);

end rtl;