Racing
Racing
-- Final Report
6 Conclusion .............................................................................................................................................. 16
7.1.6 Car1_Medium_Left_Sprite.sv............................................................................................ 68
7.1.9 audio_effects.sv.................................................................................................................. 75
7.1.10 Audio_Top.sv................................................................................................................... 78
7.1.12 i2c_controller.sv............................................................................................................... 84
Label
Rank Timer
Score
Opponents
Speed
Player
Software
Avalon Bus
Hardware
Sprite Audio
Controller Controller
3 Display Modules
3.1 Sprite
The core of our video game display technology is Sprite, which utilizes small size of
different elements to produce repeatedly pattern of pictures, minimizing the requirement for
large screen pixels RGB information. The Sprite use multiple layers to overlap the pictures and
generate a movement effect by control the movement of small elements in different layers, by
this way obtain a video game display function.
The following Figure 3 shows the layers we use in our Car Racing Game, and the rank of
layers, the layer whose priority is higher will be displayed top over those with lower priority.
Figure 3 Sprite Merging (the priority ranks from low to high from left to right)
Each layer stands for one or several Sprite picture cluster, Figure 4 demonstrates several
Sprite Element that we use.
Three sizes of Cloud (32*32, 48*48, 64*64) Three sizes of Tree (16*32, 24*48, 32*64)
Sprite ROM
Address hcount, vcount
Cloud
Sprite
Tree VGA
Controller
Flag (X, Y) coordinate for each object (From Game Logic Controller)
Avalon Bus
Figure 5 The Sprite Controller Module
The VGA module is the same as Lab 3. The Sprite Controller Module merges the different
Sprites to generate the final RGB information for displaying on the screen.
On the Linux side, the software generates the coordinate (X, Y) of different Sprites and
passes coordinates to the Avalon Bus through the Kernel Driver. Then these data accompanied
with address information in update the register file related to the specific Spite, the Sprite
Controller fetches the RGB information from specific Sprite picture ROM, which finally merges
all the pictures according to the priority and send to VGA module. The picture is finally showed
on the screen. To make the Sprite move, the software just update the (X, Y) coordinate register
file continuously.
○
1
A(X,Y)
.
Width
○
2 ○
2
○
3
B ○ 4
○ C
..
4
.
D Figure 6 The Background Sprite
E.
The rendering algorithm of this background is based on the coordinate of point A, B, C, D,
E and F as well as the Width. Using the geometrical knowledge, we can simply divide the screen
into 4 regions, which is demonstrates in Figure 6. Every pixel above Y horizon is set to Blue
because it is Sky Region. All pixels within Triangle ABC are set to Gray, because they belong to
the Road Region. The rest pixels are set to Green, because they belong to the Grass Region.
3.4 Challenge and Solution
I think the most difficult part in Sprite Module that I have concurred is how to debug in
hardware, especially debug the SystemVerilog code. Because Hardware Description Language is
totally different from other language that I have learned like C or Java, and the Quartus doesn’t
have anything like Debug Step by Step, this confuses me a lot at the beginning of programing for
this project, I seems lost every time my code doesn’t run as I expected, and I have no idea what
is going wrong. Then I learn from other experienced classmates and searching in the Internet to
find some hardware debug methodologies, I learned that the debug in hardware is not like in the
C or Java, it’s mainly about the timing analysis, you should use the test bench code to generate
the exact test signal to test how your designed module will react to your test signals, and using
the waveform function to have a virtual picture for debug. This method help me a lot when I
designed the Sprite Module, I use the test bench to debug every small modules and see how these
modules response to my clock, check every clock if the output signals is right, it’s very tedious
but it’s also powerful to find what is going wrong in your module. After I have learned this
method, it accelerates my progress dramatically.
4 Audio Modules
4.1 Audio Files Preparation
In the audio design, one background music, and two sound effects namely acceleration and
crashing are included in this project. All the three audio files are configured with sample rate of
44100 Hz and 16 bits quantization to ensure the sound quality. In order to store the sound files
in the on-chip ROM, we have to prepare MIF files with sizes small enough so that the audio files
do not consume too much memory of the on-chip ROM.
The first step is find appropriate sound files. The acceleration and crashing sound effects
were downloaded in .wav format online. But the original files cannot be implemented directly in
this project due to the fact that the files’ sizes are much larger than expected. So we modified
the .wav format files using MATLAB. We plotted the sample data of the two original files, and
picked representative pieces from the plots. Next, we reassembled the selected pieces to create
new sample data sets to represent acceleration and crashing sound effects. Then we tested the
new sound effects by simulating the looping playback environment in MATLAB, and sounded
the files. Finally, we chose the version that performed best in this quality and data size tradeoff.
In the next step, we converted the modified sample data into MIF using MATLAB. The codes
for generating “accelerate.mif” and “crash.mif” files are in the MATLAB Code section of this
report.
The background music was found in the files of the Columbia University in the City of New
York Spring 2014 CSEE4840 Embedded System Design Project “NUNY: Ninja University in
the City of New York” contributed by Kshitij Bhardwaj, Van Bui, Vinti Vinti, and Kuangya Zhai.
The “city.mif” file was proved to be in good quality and suitable size for this project, so we
quoted this file and renamed it “background.mif” in this project.
Finally, the well prepared background music, acceleration, and crashing sound effects files
were loaded to the on-chip ROM, taking 65536 words (word=16bits) memory in total.
In this project, the Audio Controller is mainly consisted of four components, namely Audio
ROM blocks, Audio Effect block, Audio Codec Interface, and Audio Codec Configuration
Interface. The figure below is the function block diagram of the Audio Controller.
1. Audio ROM blocks. The audio data are well prepared in advance to take as little on-chip
ROM space as possible, while preserving the sound quality. The acceleration sound
(“accelerate.mif”), crashing sound (“crash.mif”), and background music (“background.mif”)
files are used to create ROM audio data blocks using MegaWizard Plug-in Manager. The
background music takes 32768 words (word=16bits) memory, while each of the acceleration
and crashing sound effects takes 16384 words (word=16bits) memory. In total, 65536 16-bit
ROM space are taken for the audio data.
2. Audio Effect block. This block operates at 50 MHz clock rate and receives the control
signals passed from the software. When a valid control signal is passed to this block, the
corresponding audio data will be fetched from the Audio Data blocks, and then passed to the
SSM2603 Audio Codec through Audio Codec Interface.
3. Audio Codec Interface. This interface operates at 50 MHz clock rate. It sends the audio data
to the SSM2603 Audio Codec using shift registers.
4. Audio Codec Configuration Interface. This interface is used to configure the SSM2603
Audio Codec parameters, such as 44100Hz sampling rate and so on, using the 𝐼 2 𝐶 protocol.
The two wires in the 𝐼 2 𝐶 protocol are labeled SDAT and SCLK for Serial Data and Serial
Clock respectively. In 𝐼 2 𝐶 , data is sent a bit at a time over the SDAT wire, with the
separation between bits determined by clock cycles on the SCLK wire. In this project, the
FPGA is the master and the audio codec in slave mode.
When the game is on, the software pass control signal “0” to the Audio Controller, and the
background music will be played. When acceleration happens in the game, control signal “1”
will be passed to the Audio Controller, and the acceleration sound effect will take place
repeatedly until the acceleration period ends. When there is a crash on either the boundaries or
the other competitors, control signal “2” will be passed to the Audio Controller, and the crashing
sound effect will take place. Each sound effect is played individually in this project, and we do
not support concurrent sounding in this game.
No Rightkey No No No
Leftkey pressed Upkey pressed Hit coin
pressed
No Score ++
No Yes Yes No
Collision Collision Score >= 5
Yes
Player’s car
Player’s car move Player’s car
position reset
left move right
Speed slow down
Speed up
Yes
Yes
Yes
End Pass
Road margin
Car2(x,y)
Car1(x,y) Car1(x,y)
Surpass
To be able to know when the player’s car is passing the opponent cars or when it is being
passed by the opponent cars, we keep track of how far each car has travelled by three
variables “car1_dist”, “car2_dist” and “car3_dist”. These three variables keep increasing
based on their different speeds – “car1_speed”, “car2_speed” and “car3_speed”. In this way
we are able to know two cars’ distance by subtracting two distance variables. And we set a
passing range so that when two cars’ distance is within the range, there is a passing event.
The player’s car can only be passing the opponent cars during speed up and their distance is
within the passing range, where its speed is faster than the opponent cars’ speeds. And the
opponent cars can pass the player’s car if the player’s car is not speeding up and their
distance is within the passing range. During the process of speeding up, all the cars’ speeds
are set so that the player’s car’s speed is the fastest. If a collision happens, the player’s car’s
speed will be set to zero during the process of reset. The rank will be displayed based on
their distances travelled.
Timer
We used a variable “gametimer” to keep track of the time elapsed. We increase
“gametimer” by an increment of 1 with frame rate and then divide it by the number of how
many frames per second to get the correct time.
6 Conclusion
From this project, we improved our skills in programming both hardware language and
software language.
In the Sprite Display Module design, we have gone through programing, testing, modifying
and assembling. We adopt Top-Down Design Methodology, divide the big project into several
small task and modules, design general port interface. By this way, we improve our progress and
make our project easy to locate where the problems are because we use small modules to limit
the bug region. We believe the most valuable lesson we have learned in this project is how to
debug in hardware and how to locate the bug. The bugs and problems we encountered through
this project help us to enhance our knowledge of hardware design.
During the audio design in this project, we have learnt that the physical on-chip ROM limit
should always be kept in mind during hardware design, and all the data designed to be loaded on
board should be modified to the correct format beforehand. When preparing the proper audio
file, rather than repeatedly loading different testing audio files into the system and compiling the
whole program every time we change the audio files, we can simulate the looping playback
environment using MATLAB, and then load the qualified audio file version on board for further
testing. The simulation strategy is much more efficient. Before integrating the audio module
into the whole game logic program, we should test the audio module by sending the expected
signals to examine whether the audio system can output correctly. Following such procedure, we
can save a lot of debugging, because we have divided the whole design and testing procedure
into multiple subsections which make it easier and faster to locate the error locations.
We used the software to implement the game logic and hardware to display graphics and
audio sounds and communicated each other with software-hardware interface. During this
procedure, we’ve encountered a lot of problems in implementing the game logic and keyboard
control but we were finally able to solve all of them though we still have a lot to improve.
7 Major Codes
7.1 Hardware Part
C = zeros(1,row*colum);
for i = 1:row
for j = 1:colum
C(colum*(i-1)+j) = bitshift(int32(B1(i,j)),16) +
bitshift(int32(B2(i,j)),8) + int32(B3(i,j));
% C(64*(i-1)+j) = B1(i,j)*2^(16) + B2(i,j)*2^(8) + B3(i,j);
end
end
widths = 24;%?????24?
fidc = fopen('light_green.mif','wt');
fprintf(fidc,'DATA_RADIX = UNS;\n');
fprintf(fidc,'CONTENT BEGIN\n');
for x = 1 : depth
fprintf(fidc,'%d:%d;\n',x-1,C(x));
end
fprintf(fidc, 'END;');
fclose(fidc);
7.1.2 VGA_Sprite.sv
input chipselect,
input AUD_ADCDAT,
// Audio Control
// Car1_Ahead parameter
logic car1_ahead_valid;
// Car1_Left parameter
logic car1_left_valid;
// Car1_Right parameter
logic car1_right_valid;
// Car1_Medium_Ahead parameter
logic [15:0] car1_medium_ahead_x, car1_medium_ahead_y;
logic car1_medium_ahead_valid;
// Car1_Medium_Left parameter
logic car1_medium_left_valid;
// Car1__Medium_Right parameter
logic car1_medium_right_valid;
// Car1_Small_Ahead parameter
logic car1_small_ahead_valid;
// Car1_Small_Left parameter
logic car1_small_left_valid;
// Car1_Small_Right parameter
logic car1_small_right_valid;
// Car2_Ahead parameter
logic car2_ahead_valid;
// Car2_Left parameter
logic car2_left_valid;
// Car2_Right parameter
logic car2_right_valid;
// Car2_Medium_Ahead parameter
logic car2_medium_ahead_valid;
// Car2_Medium_Left parameter
logic car2_medium_left_valid;
// Car2__Medium_Right parameter
logic car2_medium_right_valid;
// Car2_Small_Ahead parameter
logic car2_small_ahead_valid;
// Car2_Small_Left parameter
// Car2_Small_Right parameter
logic car2_small_right_valid;
// Car3_Ahead parameter
logic car3_ahead_valid;
// Car3_Left parameter
logic car3_left_valid;
// Car3_Right parameter
logic car3_right_valid;
// Car3_Medium_Ahead parameter
logic car3_medium_ahead_valid;
// Car3_Medium_Left parameter
logic car3_medium_left_valid;
// Car3__Medium_Right parameter
logic car3_medium_right_valid;
// Car3_Small_Ahead parameter
logic car3_small_ahead_valid;
// Car3_Small_Left parameter
logic car3_small_left_valid;
// Car3_Small_Right parameter
logic car3_small_right_valid;
// Tree1_Big parameter
logic tree1_valid;
// Tree_Medium parameter
logic tree2_valid;
// Tree_Small parameter
logic tree3_valid;
// Cloud_Big parameter
logic cloud1_valid;
// Cloud_Small parameter
logic cloud2_valid;
//Light parameter
logic light_valid;
//Numbers parameters
logic numbers_valid;
logic flag_valid;
logic coin1_valid;
logic coin2_valid;
logic score_label_valid;
logic mph_label_valid;
//left_arrow_small parameter
logic left_arrow_small_valid;
//left_arrow_big parameter
logic left_arrow_big_valid;
//right_arrow_small parameter
logic [15:0] right_arrow_small_x, right_arrow_small_y;
logic right_arrow_small_valid;
//right_arrow_big parameter
logic right_arrow_big_valid;
// audio module
// Car1_Sprite car1_sprite(.*);
//////////////////////////////////////////////
/////////////////////////////////////////////
Car1_Small_Ahead_Sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(car1_small_ahead_x), .car1_y(car1_s
mall_ahead_y), .car1_r(car1_small_ahead_r), .car1_g(car1_small_ahead_g), .car1_b(car1_small_ahead_
b), .car1_valid(car1_small_ahead_valid));
//////////////////////////
Tree1_Sprite
tree1_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(tree1_x), .tree1_y(tree1_y), .tree2_x(tree4_x), .tree2_y(tr
ee4_y), .tree1_r(tree1_r), .tree1_g(tree1_g), .tree1_b(tree1_b), .tree_valid(tree1_valid));
Tree_Medium_Sprite
tree2_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(tree2_x), .tree1_y(tree2_y), .tree2_x(tree5_x), .tree2_y(tr
ee5_y), .tree1_r(tree2_r), .tree1_g(tree2_g), .tree1_b(tree2_b), .tree_valid(tree2_valid));
Tree_Small_Sprite
tree3_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(tree3_x), .tree1_y(tree3_y), .tree2_x(tree6_x), .tree2_y(tr
ee6_y), .tree1_r(tree3_r), .tree1_g(tree3_g), .tree1_b(tree3_b), .tree_valid(tree3_valid));
Cloud_Big_Sprite
cloud_big_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(cloud1_x), .tree1_y(cloud1_y),.tree2_x(cloud3_x), .tr
ee2_y(cloud3_y), .tree1_r(cloud1_r), .tree1_g(cloud1_g), .tree1_b(cloud1_b), .tree_valid(cloud1_valid));
Cloud_Small_Sprite
cloud_small_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(cloud2_x), .tree1_y(cloud2_y), .tree2_x(cloud4_x), .
tree2_y(cloud4_y), .tree1_r(cloud2_r), .tree1_g(cloud2_g), .tree1_b(cloud2_b), .tree_valid(cloud2_valid)
);
Light_Sprite
light_sprite(.clk(clk), .hc(hc), .vc(vc), .tree1_x(light_x), .tree1_y(light_y), .light_signal(light_signal), .tree1
_r(light_r), .tree1_g(light_g), .tree1_b(light_b), .tree_valid(light_valid));
Numbers_Sprite numbers_sprite(.*);
Finish_Flag_Sprite
finish_flag_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(flag_x), .car1_y(flag_y), .car1_r(flag_r), .car1_g(flag_g)
, .car1_b(flag_b), .car1_valid(flag_valid));
Coin_Big_Sprite
coin_big_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(coin1_x), .car1_y(coin1_y), .car1_r(coin1_r), .car1_g(coi
n1_g), .car1_b(coin1_b), .car1_valid(coin1_valid));
Coin_Small_Sprite
coin_small_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(coin2_x), .car1_y(coin2_y), .car1_r(coin2_r), .car1_g(c
oin2_g), .car1_b(coin2_b), .car1_valid(coin2_valid));
Score_Label_Sprite
score_label_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(score_label_x), .car1_y(score_label_y), .car1_r(score
_label_r), .car1_g(score_label_g), .car1_b(score_label_b), .car1_valid(score_label_valid));
Mph_Label_Sprite
mph_label_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(mph_label_x), .car1_y(mph_label_y), .car1_r(mph_la
bel_r), .car1_g(mph_label_g), .car1_b(mph_label_b), .car1_valid(mph_label_valid));
//////////////////////////////////
Left_Arrow_Small_Sprite
left_arrow_small_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(left_arrow_small_x), .car1_y(left_arrow_small_
y), .car1_r(left_arrow_small_r), .car1_g(left_arrow_small_g), .car1_b(left_arrow_small_b), .car1_valid(le
ft_arrow_small_valid));
Left_Arrow_Big_Sprite
left_arrow_big_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(left_arrow_big_x), .car1_y(left_arrow_big_y), .car
1_r(left_arrow_big_r), .car1_g(left_arrow_big_g), .car1_b(left_arrow_big_b), .car1_valid(left_arrow_big
_valid));
Right_Arrow_Small_Sprite
right_arrow_small_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(right_arrow_small_x), .car1_y(right_arrow_s
mall_y), .car1_r(right_arrow_small_r), .car1_g(right_arrow_small_g), .car1_b(right_arrow_small_b), .car
1_valid(right_arrow_small_valid));
Right_Arrow_Big_Sprite
right_arrow_big_sprite(.clk(clk), .hc(hc), .vc(vc), .car1_x(right_arrow_big_x), .car1_y(right_arrow_big_y),
.car1_r(right_arrow_big_r), .car1_g(right_arrow_big_g), .car1_b(right_arrow_big_b), .car1_valid(right_a
rrow_big_valid));
if (reset) begin
case (address)
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
endcase
end
// assign x = centerX;
// assign y = centerY;
assign hc = posX;
assign vc = posY;
always begin
is_red = color_flag;
is_red = ~color_flag;
is_red = color_flag;
is_red = ~color_flag;
is_red = color_flag;
is_red = ~color_flag;
is_red = color_flag;
end
if (tree3_y[5])
else
end
/*
always_comb begin
if (road_flag)
is_red = color_flag;
else
is_red = ~color_flag;
end
*/
always_comb begin
VGA_R = numbers_r;
VGA_G = numbers_g;
VGA_B = numbers_b;
end
else if (flag_valid && (flag_r != 8'hff) && (flag_g != 8'hff) && (flag_b != 8'hff)) begin
VGA_R = flag_r;
VGA_G = flag_g;
VGA_B = flag_b;
end
VGA_R = score_label_r;
VGA_G = score_label_g;
VGA_B = score_label_b;
end
VGA_R = mph_label_r;
VGA_G = mph_label_g;
VGA_B = mph_label_b;
end
else if (light_valid && (light_r != 8'h00) && (light_g != 8'h00) && (light_b != 8'h00)) begin
VGA_R = light_r;
VGA_G = light_g;
VGA_B = light_b;
end
VGA_R = car1_ahead_r;
VGA_G = car1_ahead_g;
VGA_B = car1_ahead_b;
end
VGA_R = car1_left_r;
VGA_G = car1_left_g;
VGA_B = car1_left_b;
end
VGA_R = car1_right_r;
VGA_G = car1_right_g;
VGA_B = car1_right_b;
end
/////////////////////////////////////////////////////////////////
VGA_R = car2_ahead_r;
VGA_G = car2_ahead_g;
VGA_B = car2_ahead_b;
end
VGA_R = car2_left_r;
VGA_G = car2_left_g;
VGA_B = car2_left_b;
end
VGA_R = car2_right_r;
VGA_G = car2_right_g;
VGA_B = car2_right_b;
end
///////////////////////////////////////////////////////////////////////
VGA_R = car3_ahead_r;
VGA_G = car3_ahead_g;
VGA_B = car3_ahead_b;
end
VGA_R = car3_left_r;
VGA_G = car3_left_g;
VGA_B = car3_left_b;
end
VGA_R = car3_right_r;
VGA_G = car3_right_g;
VGA_B = car3_right_b;
end
///////////medium///////////////////////
VGA_R = car1_medium_ahead_r;
VGA_G = car1_medium_ahead_g;
VGA_B = car1_medium_ahead_b;
end
VGA_R = car1_medium_left_r;
VGA_G = car1_medium_left_g;
VGA_B = car1_medium_left_b;
end
VGA_R = car1_medium_right_r;
VGA_G = car1_medium_right_g;
VGA_B = car1_medium_right_b;
end
VGA_R = car2_medium_ahead_r;
VGA_G = car2_medium_ahead_g;
VGA_B = car2_medium_ahead_b;
end
else if (car2_medium_left_valid && (car2_medium_left_r != 8'hff) &&
(car2_medium_left_g != 8'hff) && (car2_medium_left_b != 8'hff)) begin
VGA_R = car2_medium_left_r;
VGA_G = car2_medium_left_g;
VGA_B = car2_medium_left_b;
end
VGA_R = car2_medium_right_r;
VGA_G = car2_medium_right_g;
VGA_B = car2_medium_right_b;
end
VGA_R = car3_medium_ahead_r;
VGA_G = car3_medium_ahead_g;
VGA_B = car3_medium_ahead_b;
end
VGA_R = car3_medium_left_r;
VGA_G = car3_medium_left_g;
VGA_B = car3_medium_left_b;
end
VGA_R = car3_medium_right_r;
VGA_G = car3_medium_right_g;
VGA_B = car3_medium_right_b;
end
/////////////medium/////////////////
//////////////////car small/////////////////////
VGA_R = car1_small_ahead_r;
VGA_G = car1_small_ahead_g;
VGA_B = car1_small_ahead_b;
end
VGA_R = car1_small_left_r;
VGA_G = car1_small_left_g;
VGA_B = car1_small_left_b;
end
VGA_R = car1_small_right_r;
VGA_G = car1_small_right_g;
VGA_B = car1_small_right_b;
end
/////////////////////////////////////////////////////////////////
VGA_R = car2_small_ahead_r;
VGA_G = car2_small_ahead_g;
VGA_B = car2_small_ahead_b;
end
VGA_R = car2_small_left_r;
VGA_G = car2_small_left_g;
VGA_B = car2_small_left_b;
end
VGA_R = car2_small_right_r;
VGA_G = car2_small_right_g;
VGA_B = car2_small_right_b;
end
///////////////////////////////////////////////////////////////////////
VGA_R = car3_small_ahead_r;
VGA_G = car3_small_ahead_g;
VGA_B = car3_small_ahead_b;
end
VGA_R = car3_small_left_r;
VGA_G = car3_small_left_g;
VGA_B = car3_small_left_b;
end
VGA_G = car3_small_right_g;
VGA_B = car3_small_right_b;
end
//////////////////car small/////////////////////////
else if (coin1_valid && (coin1_r != 8'hff) && (coin1_g != 8'hff) && (coin1_b != 8'hff))
begin
VGA_R = coin1_r;
VGA_G = coin1_g;
VGA_B = coin1_b;
end
else if (coin2_valid && (coin2_r != 8'hff) && (coin2_g != 8'hff) && (coin2_b != 8'hff))
begin
VGA_R = coin2_r;
VGA_G = coin2_g;
VGA_B = coin2_b;
end
////////////////////////////medium/////////////////////////////////////////////////////
////////////////////////////medium////////////////////////////////////////////////////
else if (tree1_valid && (tree1_r != 8'hff) && (tree1_g != 8'hff) && (tree1_b != 8'hff))
begin
VGA_R = tree1_r;
VGA_G = tree1_g;
VGA_B = tree1_b;
end
else if (tree2_valid && (tree2_r != 8'hff) && (tree2_g != 8'hff) && (tree2_b != 8'hff))
begin
VGA_R = tree2_r;
VGA_G = tree2_g;
VGA_B = tree2_b;
end
else if (tree3_valid && (tree3_r != 8'hff) && (tree3_g != 8'hff) && (tree3_b != 8'hff))
begin
VGA_R = tree3_r;
VGA_G = tree3_g;
VGA_B = tree3_b;
end
////////////////////////////////////////////////////
else if (cloud1_valid && (cloud1_r != 8'h00) && (cloud1_g != 8'h00) && (cloud1_b !=
8'h00)) begin
VGA_R = cloud1_r;
VGA_G = cloud1_g;
VGA_B = cloud1_b;
end
else if (cloud2_valid && (cloud2_r != 8'h00) && (cloud2_g != 8'h00) && (cloud2_b !=
8'h00)) begin
VGA_R = cloud2_r;
VGA_G = cloud2_g;
VGA_B = cloud2_b;
end
VGA_R = left_arrow_big_r;
VGA_G = left_arrow_big_g;
VGA_B = left_arrow_big_b;
end
else if (left_arrow_small_valid && (left_arrow_small_r != 8'h00) &&
(left_arrow_small_g != 8'h00) && (left_arrow_small_b != 8'h00)) begin
VGA_R = left_arrow_small_r;
VGA_G = left_arrow_small_g;
VGA_B = left_arrow_small_b;
end
VGA_R = right_arrow_big_r;
VGA_G = right_arrow_big_g;
VGA_B = right_arrow_big_b;
end
VGA_R = right_arrow_small_r;
VGA_G = right_arrow_small_g;
VGA_B = right_arrow_small_b;
end
//////////////////////////////////////////////////////
VGA_R = 8'h5c;
VGA_G = 8'hac;
VGA_B = 8'hee;
end
VGA_R = 8'hff;
VGA_G = 8'hcc;
VGA_B = 8'h99;
end
if (is_red) begin
VGA_R = 8'hff;
VGA_G = 8'h00;
VGA_B = 8'h00;
end
else begin
VGA_R = 8'hff;
VGA_G = 8'hff;
VGA_B = 8'hff;
end
end
VGA_R = 8'he0;
VGA_G = 8'he0;
VGA_B = 8'he0;
end
if (is_red) begin
VGA_R = 8'hff;
VGA_G = 8'h00;
VGA_B = 8'h00;
end
else begin
VGA_R = 8'hff;
VGA_G = 8'hff;
VGA_B = 8'hff;
end
end
else begin
VGA_R = 8'hff;
VGA_G = 8'hcc;
VGA_B = 8'h99;
end
VGA_R = 8'h5c;
VGA_G = 8'hac;
VGA_B = 8'hee;
end
VGA_R = 8'he0;
VGA_G = 8'he0;
VGA_B = 8'he0;
end
else begin
VGA_R = 8'hff;
VGA_G = 8'hcc;
VGA_B = 8'h99;
end
*/
VGA_R = 8'he0;
VGA_G = 8'he0;
VGA_B = 8'he0;
end
else begin
VGA_R = 8'hff;
VGA_G = 8'hcc;
VGA_B = 8'h99;
end
*/
end
endmodule
7.1.3 VGA_Sprite_Emulator.sv
module VGA_BALL_Emulator(
// input logic [7:0] hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7,
// input chipselect,
/*
* 640 X 480 VGA timing for a 50 MHz clock: one pixel every other cycle
* _______________ ________
* _______________________ _____________
*/
VSYNC = 10'd 2,
logic endOfLine;
// Vertical counter
logic endOfField;
else if (endOfLine)
assign VGA_SYNC_n = 1; // For adding sync to video signals; not used for VGA
// Horizontal active: 0 to 1279 Vertical active: 0 to 479
/* VGA_CLK is 25 MHz
* __ __ __
* _____ __
* hcount[0]__| |_____|
*/
/*
always_comb begin
else
end
*/
endmodule // VGA_LED_Emulator
7.1.4 Car1_Medium_Right_Sprite.sv
module Car1_Medium_Right_Sprite(
always begin
car1_valid1 = 1'b 1;
end
else begin
car1_valid1 = 1'b 0;
end
end
else if ((vc >= car1_y - HEIGHT/2) && (vc < car1_y + HEIGHT/2)) begin
car1_valid1 = 1'b 1;
end
else begin
car1_valid1 = 1'b 0;
end
end
always begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
else begin if ((hc >= car1_x - WIDTH/2) && (hc < car1_x + WIDTH/2)) begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
end
/*
always_comb begin
car1_valid = 1'b0;
car1_valid = 1'b0;
else
car1_valid = 1'b1;
end
*/
/*
always_comb begin
if (rgb == 24'hffffff)
car1_valid3 = 1'b 0;
else
car1_valid3 = 1'b 1;
end
*/
always_comb begin
if (car1_valid)
else
address = 16'h0000;
end
endmodule
7.1.5 Car1_Medium_Ahead_Sprite.sv
module Car1_Medium_Ahead_Sprite(
always begin
car1_valid1 = 1'b 1;
end
else begin
car1_valid1 = 1'b 0;
end
end
else if ((vc >= car1_y - HEIGHT/2) && (vc < car1_y + HEIGHT/2)) begin
car1_valid1 = 1'b 1;
end
else begin
car1_valid1 = 1'b 0;
end
end
always begin
if (car1_x < WIDTH/2) begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
else begin if ((hc >= car1_x - WIDTH/2) && (hc < car1_x + WIDTH/2)) begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
end
/*
always_comb begin
car1_valid = 1'b0;
car1_valid = 1'b0;
else
car1_valid = 1'b1;
end
*/
/*
always_comb begin
if (rgb == 24'hffffff)
car1_valid3 = 1'b 0;
else
car1_valid3 = 1'b 1;
end
*/
always_comb begin
if (car1_valid)
else
address = 16'h0000;
end
endmodule
7.1.6 Car1_Medium_Left_Sprite.sv
module Car1_Medium_Left_Sprite(
always begin
car1_valid1 = 1'b 1;
end
else begin
car1_valid1 = 1'b 0;
end
end
else if ((vc >= car1_y - HEIGHT/2) && (vc < car1_y + HEIGHT/2)) begin
car1_valid1 = 1'b 1;
else begin
car1_valid1 = 1'b 0;
end
end
always begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
else begin if ((hc >= car1_x - WIDTH/2) && (hc < car1_x + WIDTH/2)) begin
car1_valid2 = 1'b 1;
end
else
car1_valid2 = 1'b 0;
end
end
/*
always_comb begin
car1_valid = 1'b0;
car1_valid = 1'b0;
else
car1_valid = 1'b1;
end
*/
/*
always_comb begin
if (rgb == 24'hffffff)
car1_valid3 = 1'b 0;
else
car1_valid3 = 1'b 1;
end
*/
always_comb begin
if (car1_valid)
else
address = 16'h0000;
end
c=[y1;y2;y3];
c1=c(1000:3000);
c2=c(20000:23000);
c3=c(31000:33000);
c4=c(43000:52000);
c=[c1;c2;c3;c4];
c=c*65536;
z=typecast(int16(c),'uint16');
7.1.8 audio_codec.sv
//Audio codec interface
module audio_codec (
input clk, //audio clock
input reset,
output [1:0] sample_end, //end of sample
output [1:0] sample_req, //request new sample
input [15:0] audio_output, //audio output sent to audio codec
input [1:0] channel_sel, //select channel
output AUD_ADCLRCK, //ADC channel clock
input AUD_ADCDAT,
output AUD_DACLRCK, //DAC channel clock
output AUD_DACDAT,
output AUD_BCLK //Bit clock
);
// divided by 256 clock for the LRC clock, one clock is oen audio frame
reg [7:0] lrck_divider;
endmodule
7.1.9 audio_effects.sv
module audio_effects (
input logic clk, //audio clock
input logic sample_end, //sample ends
input logic sample_req, //request new sample
//input logic [15:0] audio_sample, //get audio sample from audio codec interface, not
needed here
output logic [15:0] audio_output, //sends audio sample to audio codec
input logic [15:0] M_city, //city sound ROM data
output logic [14:0] addr_city,
input logic [15:0] accelerate, //acceleration ROM data
output logic [14:0] addr_accelerate,
input logic [15:0] crash, //crash sound ROM data
output logic [14:0] addr_crash,
input logic [3:0] ctl //control signal
);
if (sample_req) begin
case(ctl)
4'b0000: begin
dat<=M_city;
if (index_city == 15'd22049)
index_city <= 15'd0;
else
index_city <= index_city +1'b1; //increment
city index
end
4'b0001: begin
dat<=accelerate;
if (index_accelerate == 15'd16003)
index_accelerate <= 15'd0;
else
index_accelerate <= index_accelerate +1'b1;
//increment accelerate index
end
4'b0010: begin
dat<=crash;
if (index_crash == 15'd15999)
index_crash <= 15'd0;
else
index_crash <= index_crash +1'b1;
//increment crash index
end
endcase
end
end
endmodule
7.1.10 Audio_Top.sv
module Audio_Top (
input OSC_50_B8A,
inout AUD_ADCLRCK, AUD_DACLRCK,AUD_BCLK, AUD_I2C_SDAT,
input AUD_ADCDAT,
output AUD_DACDAT, AUD_XCK, AUD_I2C_SCLK, AUD_MUTE,
input [3:0] KEY,
input [3:0] SW,
output [3:0] LED
);
.AUD_ADCLRCK (AUD_ADCLRCK),
.AUD_ADCDAT (AUD_ADCDAT),
.AUD_DACLRCK (AUD_DACLRCK),
.AUD_DACDAT (AUD_DACDAT),
.AUD_BCLK (AUD_BCLK)
);
audio_effects ae (
.clk (audio_clk),
.sample_end (sample_end[1]),
.sample_req (sample_req[1]),
.audio_output (audio_output),
//.audio_sample (audio_sample),
.addr_city(addr_city),
.M_city(M_city),
.addr_accelerate(addr_accelerate),
.accelerate(accelerate),
.addr_crash(addr_crash),
.crash(crash),
.ctl(SW)
);
endmodule
7.1.11 i2c_av_config.sv
module i2c_av_config (
input clk,
input reset,
7.1.12 i2c_controller.sv
module i2c_controller (
input clk,
input start,
output done,
output ack,
if (stage != LAST_STAGE)
stage <= stage + 1'b1;
case (stage)
// after start
5'd0: clock_en <= 1'b1;
// receive acks
5'd9: acks[0] <= i2c_sdat;
5'd18: acks[1] <= i2c_sdat;
5'd27: acks[2] <= i2c_sdat;
// before stop
5'd28: clock_en <= 1'b0;
endcase
end else
sclk_divider <= sclk_divider + 1'b1;
if (midlow) begin
case (stage)
// start
5'd0: sdat <= 1'b0;
// byte 1
5'd1: sdat <= data[23];
5'd2: sdat <= data[22];
5'd3: sdat <= data[21];
5'd4: sdat <= data[20];
5'd5: sdat <= data[19];
5'd6: sdat <= data[18];
5'd7: sdat <= data[17];
5'd8: sdat <= data[16];
// ack 1
5'd9: sdat <= 1'b1;
// byte 2
5'd10: sdat <= data[15];
5'd11: sdat <= data[14];
5'd12: sdat <= data[13];
5'd13: sdat <= data[12];
5'd14: sdat <= data[11];
5'd15: sdat <= data[10];
5'd16: sdat <= data[9];
5'd17: sdat <= data[8];
// ack 2
5'd18: sdat <= 1'b1;
// byte 3
5'd19: sdat <= data[7];
5'd20: sdat <= data[6];
5'd21: sdat <= data[5];
5'd22: sdat <= data[4];
5'd23: sdat <= data[3];
5'd24: sdat <= data[2];
5'd25: sdat <= data[1];
5'd26: sdat <= data[0];
// ack 3
5'd27: sdat <= 1'b1;
// stop
5'd28: sdat <= 1'b0;
5'd29: sdat <= 1'b1;
endcase
end
end
end
endmodule
7.2.1 hello.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "vga_ball.h"
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "usbkeyboard.h"
#include <math.h>
#include <time.h>
uint8_t endpoint_address;
pthread_t network_thread;
#define R_MAX 50
#define R_MIN 20
int vga_ball_fd;
void print_segment_info() {
vga_ball_arg_t vla;
int i;
vla.digit = i;
perror("ioctl(VGA_LED_READ_DIGIT) failed");
return;
printf("\n");
vga_ball_arg_t vla;
int i;
vla.digit = i;
vla.segments = segs[i];
perror("ioctl(VGA_LED_WRITE_DIGIT) failed");
return;
vga_ball_arg_t vla;
vla.digit = address;
vla.segments = value;
perror("ioctl(VGA_LED_WRITE_DIGIT) failed");
return;
int score_remainder;
write_register(car_score, 96);
write_register(0, 95);
write_register(car_score%10, 96);
write_register(car_score/10, 95);
write_register(0, 94);
score_remainder = car_score%100;
write_register(score_remainder%10, 96);
write_register(score_remainder/10, 95);
write_register(car_score/100, 94);
}
}
int time_reminder;
write_register(gametime, 90);
write_register(gametime%10, 90);
write_register(gametime/10, 89);
write_register(gametime/60, 88);
write_register(time_reminder%10, 90);
write_register(time_reminder/10, 89);
write_register(gametime/600, 87);
write_register(time_reminder/60, 88);
write_register((time_reminder%60)%10, 90);
write_register((time_reminder%60)/10, 89);
int speed_remainder;
write_register(0, 92);
write_register(0, 91);
write_register(speed%10, 93);
write_register(speed/10, 92);
write_register(0, 91);
speed_remainder = speed%100;
write_register(speed_remainder%10, 93);
write_register(speed_remainder/10, 92);
write_register(speed/100, 91);
//car1 x position
int boost_time = 0;
int boost_num = 0;
int car_score = 0;
int left_right_key = 0;
int corner = 0;
int collide_slowtime = 0;
int transferred;
char keystate[12];
int stop = 0;
randomnum = rand();
randomnum = randomnum%66 + 1;
return randomnum;
write_register(x, addr);
write_register(x>>8, addr+1);
write_register(y, addr+2);
write_register(y>>8, addr+3);
int main(){
vga_ball_arg_t vla;
int i;
int j;
int count_car2;
float tree_location_incre = 1;
int count_coin;
int twinkle = 0;
int coin_count = 0;
int gametimer = 0;
int car1_speed = 1;
int car2_speed = 2;
int car3_speed = 3;
int car1_dist = 0;
int car2_dist = 0;
int car3_dist = 0;
int boost_dist = 0;
int pass_car2 = 0;
int pass_car3 = 0;
int speed = 0;
int speed_fast = 0;
/*
int transferred;
char keystate[12];
// unsigned char R, G, B;
center_x = WIDTH/2;
center_y = HEIGHT/2;
r = 1;
dr = 1;
v_x = 2;
v_y = 4;
//score
score_uni = 0;
score_ten = 0;
score_hund = 0;
smallrx = 400;
smallry = 220;
mediumrx = 480;
mediumry = 264;
largerx = 572;
largery = 317;
smalllx = 240;
smallly = 220;
mediumlx = 160;
mediumly = 264;
largelx = 68;
largely = 317;
//clouds
cloud1x = 520;
cloud1y = 110;
cloud2x = 400;
cloud2y = 150;
cloud3x = 120;
cloud3y = 110;
cloud4x = 240;
cloud4y = 150;
ltree_smallx = 60;
ltree_smally = 220;
ltree_mediumx = 305;
ltree_mediumy = 290;
ltree_largex = 545;
ltree_largey = 360;
//car2_x = 330;
//car2_y = 265;
car2_x = 430;
car2_y = 400;
car3_x = 210;
car3_y = 400;
// car2_medium_x = 370;
// car2_medium_y = 330;
// car2_large_x = 420;
// car2_large_y = 400;
//coin_small initialization
coin_small_x = 320;
coin_small_y = 250;
//car1_x = 320;
rgb = 0xff0000;
count_car2 = 1;
count_coin = 1;
// static unsigned char message[8] = { 0x20, 0x01, 0xf0, 0x00, 0x1e, 0x00, 0xff, 0x00 };
*/
return -1;
print_segment_info();
printf("current state: ");
print_segment_info();
/*
// message[VGA_BALL_DIGITS - 1] = c0;
write_segments(message);
usleep(400000);
*/
write_register(0, 96);
write_register(0, 95);
write_register(0, 94);
while(1){
//background music
write_register(0,207);
write_register(50, 189);
write_register(50>>8, 190);
starttimer++;
usleep(10000);
//score label
place_sprite(580,50,109);
//initial speed
speed_display(0);
//initial time
write_register(0, 90);
write_register(0, 89);
write_register(0, 88);
write_register(0, 87);
place_sprite(320,240,0);
//mph sign
place_sprite(610,432,113);
//inital position
write_register(3, 85);
write_register(3, 86);
place_sprite(mediumrx,mediumry,56);
place_sprite(largerx,largery,52);
place_sprite(smalllx,smallly,48);
place_sprite(mediumlx,mediumly,44);
place_sprite(largelx,largely,40);
//clouds
place_sprite(520,110,64);
place_sprite(400,150,68);
place_sprite(120,110,72);
place_sprite(240,150,76);
//cars
place_sprite(320,400,4); //car1ahead
place_sprite(car2_x,car2_y,16);//car2ahead
place_sprite(car3_x,car3_y,28);//car3ahead
place_sprite(700,200,8); //car1left
place_sprite(700,200,12);//car1right
place_sprite(700,200,20);
place_sprite(700,200,24);
place_sprite(700,200,32);
place_sprite(700,200,36);
place_sprite(700,200,117);
place_sprite(700,200,121);
place_sprite(700,200,125);
place_sprite(700,200,129);
place_sprite(700,200,133);
place_sprite(700,200,137);
place_sprite(700,200,141);
place_sprite(700,200,145);
place_sprite(700,200,149);
place_sprite(700,200,153);
place_sprite(700,200,157);
place_sprite(700,200,161);
place_sprite(700,200,165);
place_sprite(700,200,169);
place_sprite(700,200,173);
place_sprite(700,200,177);
place_sprite(700,200,181);
place_sprite(700,200,185);
//coins disappear
place_sprite(700,240,101);
place_sprite(700,240,105);
//flag disappear
place_sprite(700,240,97);
//arrow disappear
place_sprite(800,200,191);
place_sprite(800,200,195);
place_sprite(800,200,199);
place_sprite(800,200,203);
place_sprite(320,200,80);
place_sprite(320,220,80);
place_sprite(320,240,80);
}
if(starttimer >=400){
place_sprite(700,240,80);
write_register(0,84);
car1_dist+=car1_speed ;
car2_dist+=car2_speed ;
car3_dist+=car3_speed ;
//background music
write_register(0,207);
usleep(50000);
gametimer+=2;
time_display(gametimer/40);
speed_display(80);
speed_fast = 0;
usleep(25000);
boost_time += 1;
car1_speed = 8;
car2_speed = 1;
car3_speed = 2;
gametimer += 1;
time_display(gametimer/40);
if (speed_fast<=100){
speed_fast+=1;
speed_display(80+speed_fast);
else{
usleep(100000);
gametimer+=4;
time_display(gametimer/40);
car1_speed = 0;
car2_speed = 2;
car3_speed = 3;
speed_display(0);
write_register(0,207);
if(boost_time == 150)
boost = 0;
boost_time = 0;
car1_speed = 1;
car2_speed = 2;
car3_speed = 3;
//printf("%i\n", car1_dist);
//player_car1
if(collide_slowtime == 1)
place_sprite(700,400,8);
place_sprite(700,400,12);
twinkle++;
if(twinkle%10 < 5)
place_sprite(car1_x,400,4);
else
place_sprite(700,400,4);
if(twinkle == 50)
twinkle = 0;
collide_slowtime = 0;
boost = 0;
}
//collide with other cars
if((abs(car2_x - car1_x) < 45 && abs(car2_y - car1_y) < 45) || (abs(car3_x - car1_x) < 45 &&
abs(car3_y - car1_y) < 45))
collide_slowtime = 1;
car1_x = 320;
if (car1_x < ((center_x / (480 - center_y)) * 80 + 64) || car1_x > (640 - ((640 - center_x)/(480 -
center_y)) * 80 - 64)) {
car1_x = 320;
collide_slowtime = 1;
place_sprite(arrowl_x,arrowl_y,191);
if (arrowl_y == 300)
place_sprite(arrowl_x,arrowl_y,195);
place_sprite(700,400,191);
place_sprite(arrowr_x,arrowr_y,199);
if (arrowr_y == 300)
place_sprite(arrowr_x,arrowr_y,203);
place_sprite(700,400,199);
place_sprite(center_x,center_y,0);
car1_x += 6;
if (gametimer % 22 == 0)
{
center_x -= center_incre;
if(center_x == 0)
center_incre = - center_incre;
corner = 1;
car1_x -= 6;
if (gametimer % 22 == 0)
center_x -= center_incre;
if(center_x == 640)
center_incre = - center_incre;
corner = 2;
else
center_x = WIDTH/2;
corner = 0;
}
//Tree moving increment
rx_incre = (640 - center_x) / sqrt((640 - center_x) * (640 - center_x) + (480 - center_y) * (480 -
center_y));
ry_incre = (480 - center_y) / sqrt((640 - center_x) * (640 - center_x) + (480 - center_y) * (480 -
center_y));
smallly = 220;
mediumly = 264;
largely = 317;
//printf("%f\n",smallry_y);
//Tree moving
place_sprite(smallrx_x,smallry_y,60);
place_sprite(mediumrx_x,mediumry_y,56);
place_sprite(largerx_x,largery_y,52);
place_sprite(smalllx_x,smallly_y,48);
//medium tree on the left
place_sprite(mediumlx_x,mediumly_y,44);
place_sprite(largelx_x,largely_y,40);
smallrx_x = smallrx;
mediumrx_x = mediumrx;
largerx_x = largerx;
smalllx_x = smalllx;
smallly_y = smallly;
mediumlx_x = mediumlx;
mediumly_y = mediumly;
largelx_x = largelx;
largely_y = largely;
tree_location_incre = 0;
place_sprite(700,400,4);
place_sprite(700,400,12);
place_sprite(car1_x,400,8);
place_sprite(car1_x,400,4);
place_sprite(700,400,8);
place_sprite(700,400,4);
place_sprite(700,400,8);
place_sprite(car1_x,400,12);
place_sprite(car1_x,400,4);
place_sprite(700,400,12);
}
left_right_key = 0;
/////////////////////////////////////////
//place_sprite(700,400,12);
place_sprite(700,400,20);
///////////////////////////////////////
//Cloud moving
//cloud1x = cloud1x + 5;
//cloud1y = cloud1y + 5;
cloud2x = cloud2x + 5;
cloud2y = cloud2y - 2;
//cloud3x = cloud3x - 5;
//cloud3y = cloud3y
cloud4x = cloud4x - 5;
cloud4y = cloud4y - 2;
//cloud 1 large
place_sprite(cloud2x,cloud2y,64);
place_sprite(700,cloud2y,68);
place_sprite(cloud4x,cloud4y,72);
place_sprite(700,cloud4y,76);
place_sprite(750,cloud2y,64);
place_sprite(750,cloud4y,72);
//cloud 2 small
place_sprite(cloud2x,cloud2y,68);
//cloud 3 large
write_register(cloud4x, 72);
write_register(cloud4x>>8, 73);
write_register(cloud4y, 74);
write_register(cloud4y>>8, 75);
write_register(700, 76);
write_register(700>>8, 77);
write_register(cloud4y, 78);
write_register(cloud4y>>8, 79);
*/
//cloud 4 small
place_sprite(cloud4x,cloud4y,76);
if (cloud2x == 640){
// cloud1x = 520;
//cloud1y = 110;
cloud2x = 400;
cloud2y = 150;
//cloud3x = 120;
//cloud3y = 110;
cloud4x = 240;
cloud4y = 150;
//speed
speed++;
if(speed<=80) speed_display(speed);
place_sprite(car2_x,car2_y,16);
place_sprite(700,700,16);
place_sprite(car2_x,car2_y,129);
}
place_sprite(700,700,129);
place_sprite(700,700,16);
place_sprite(car2_x,car2_y,165);
if(car2_y <265){
place_sprite(700,700,16);
place_sprite(700,car2_y,165);
car2_x = car2_x - 2;
car2_y = car2_y - 3;
place_sprite(car3_x,car3_y,28);
place_sprite(700,700,28);
place_sprite(car3_x,car3_y,141);
place_sprite(700,700,28);
place_sprite(car3_x,car3_y,177);
if(car3_y <265){
place_sprite(700,700,28);
place_sprite(700,car3_y,177);
car3_x = car3_x + 2;
car3_y = car3_y - 3;
car2_x = -330;
car2_y = 265;
car3_x = -310;
car3_y = 265;
if(gametimer >312){
//car1 and car2 position relation
pass_car2 = 1;
if(pass_car2 == 1){
if(car2_y<=265){
place_sprite(700,car2_y,129);
place_sprite(700,car2_y,16);
place_sprite(700,car2_y,165);
place_sprite(car2_x,car2_y,165);
place_sprite(700,car2_y,129);
place_sprite(700,car2_y,16);
place_sprite(car2_x,car2_y,129);
place_sprite(700,car2_y,16);
place_sprite(700,car2_y,165);
place_sprite(700,car2_y,129);
place_sprite(700,car2_y,165);
if(car2_y>=530){
place_sprite(700,car2_y,129);
place_sprite(700,car2_y,16);
place_sprite(700,car2_y,165);
car2_x = abs(car2_x) - 2;
car2_y = car2_y - 3;
car2_y = 265;
pass_car2 = 0;
car2_x = abs(car2_x) + 2;
car2_y = car2_y + 3;
car2_y = 512;
pass_car2 = 0;
}
pass_car3 = 1;
if(pass_car3==1){
if(car3_y<=265){
place_sprite(700,car3_y,141);
place_sprite(700,car3_y,28);
place_sprite(700,car3_y,177);
place_sprite(car3_x,car3_y,177);
place_sprite(700,car3_y,141);
place_sprite(700,car3_y,28);
place_sprite(car3_x,car3_y,141);
place_sprite(700,car3_y,28);
place_sprite(700,car3_y,177);
}
place_sprite(car3_x,car3_y,28);
place_sprite(700,car3_y,141);
place_sprite(700,car3_y,177);
if(car3_y>=530){
place_sprite(700,car3_y,141);
place_sprite(700,car3_y,28);
place_sprite(700,car3_y,177);
car3_x = abs(car3_x) + 2;
car3_y = car3_y - 3;
car3_y = 265;
pass_car3 = 0;
car3_x = abs(car3_x) - 2;
car3_y = car3_y + 3;
pass_car3 = 0;
//coin
int a = 0;
int coin_flag;
while(a<100000){
if(coin_count == a){
coin_small_y = 250;
coin_small_x = random_number();
coin_flag=1;
a = a+850;
place_sprite(coin_small_x,coin_small_y,105);
place_sprite(700,700,105);
place_sprite(coin_small_x,coin_small_y,101);
coin_small_x -= 4;
place_sprite(coin_small_x,coin_small_y,105);
place_sprite(700,700,105);
place_sprite(coin_small_x,coin_small_y,101);
coin_small_x += 4;
place_sprite(coin_small_x,coin_small_y,105);
place_sprite(700,700,105);
place_sprite(coin_small_x,coin_small_y,101);
if (coin_small_y == 504){
coin_flag = 0;
coin_small_y = 700;
place_sprite(700,700,105);
place_sprite(700,coin_small_y,101);
car_score++;
if ((abs(coin_small_x - car2_x) < 48 && abs(coin_small_y - car2_y) < 48) || (abs(coin_small_x - car3_x) <
48 && abs(coin_small_y - car3_y) < 48))
coin_small_y = 700;
place_sprite(700,coin_small_y,105);
place_sprite(700,coin_small_y,101);
score_display(car_score);
boost_num = car_score / 5;
if(score_decre == 1){
boost_num--;
car_score = car_score - 5;
score_decre = 0;
//car3smallright
place_sprite(700,700,185);
//light signal
place_sprite(700,700,80);
write_register((j++)%2, 84);
//End of game
if(gametimer>2400){
flagy+=10;
place_sprite(flagx,flagy,97);
if(flagy == 450)
write_register(0,207);
break;
if(stop == 1)
break;
pthread_cancel(network_thread);
pthread_join(network_thread, NULL);
printf("VGA LED Userspace program terminating\n");
// printf("%d\n",&());
return 0;
for (;;) {
libusb_interrupt_transfer(keyboard, endpoint_address,
&transferred, 50);
stop = 1;
break;
//left_arrow
if (packet.keycode[0] == 0x50) {
// place_sprite(car1_x,400,8);
// place_sprite(700,400,4);
left_right_key = 1;
//right_arrow
if (packet.keycode[0] == 0x4f) {
// place_sprite(700,400,4);
left_right_key = 2;
//up_arrow
if (packet.keycode[0] == 0x52) {
boost = 1;
boost_time = 0;
score_decre = 1;
//down arrow
//ESC
/* if (packet.keycode[0] == 0x29) {
break;
} */
return NULL;