By: Ryan Smith (rcs258)
∑ Brief overview
I have created a 2-player Tetris game with one NTSC TV, a Mega 1284 microcontroller, 2 keypads, and many lines of C code
∑ Reasoning Behind Project
After completing the video game lab in class, I realized I wanted to make my own video game using the NTSC TV.† I wanted to make a 2 player Tetris game mostly because itís one of my favorite video games.† Also because while browsing the lab projects and seeing that while Tetris has been implemented, there was no 2 player Tetris game that I came across.† I wanted to implement gray scale into the project, but didnít have the time as the software took an incredible amount of time.
High Level Design
The project consisted of the hardware design and the software design.† The hardware design was fairly simple while the software design included thousands of lines of code.
The hardware design was very similar to the hardware for the video game lab (lab 3).† I had a 3 resistor DAC that modified the video signal and sent it to the NTSC TV.† Because I didnít have time to make a more complicated DAC to implement grayscale, the DAC I used only implements black and white.† I also have 2 keypads that are attached to all A ports and B ports.† The keypad holds 16 number pads.† I only use 6 of them for the game.
The software design, which took the majority of the time, was the most important part of my project.† It was able to continuously draw the Tetris pieces while taking input from the players keypads by use of debouncing.
The hardware consisted of an NTSC TV, a 12V power supply for the TV, An ATMega1284p microcontroller, a 9V power supply for the microcontroller, 330Ω, 1KΩ, and 75Ω resistors for the DAC, two 8-pin, 16 number pad keypads, 3 breadboards, and about 16 wires (for the keypad connection).
The video signal was sent out of the D.1 port while the sync was sent from the D.0.† The video and sync signal were sent through the 330Ω and 1KΩ resistors respectively.† The 75Ω resistor was set to ground.† As the picture below shows, the 3 resistors were in parallel.† The modified signal is then sent to the NTSC TV.
The keypads are attached to the A ports and the B ports.† The first keypad (the one with the red wires),† uses the number 4 for moving left, 5 for moving down, 6 for moving right, 1 for rotating the piece counter-clockwise, 3 for rotating the piece clockwise, and 2 for storing the current piece to save it for later.† This keypad is connected to the A ports.† The second keypad (the one with the blue wires),† uses the number 5† for moving left, 6 for moving down, B for moving right, 2 for rotating the piece counter-clockwise, A for rotating the piece clockwise, and 3 for storing the current piece to save it for later.† This keypad is connected to the A ports.
The software was implemented in a step by step procedure.† I used the demo code from the video game lab as a basis for my project.† It uses two interrupt service routines. The TIMER1_COMPA ISR updates the Line_Count and continuously sends data from the ATMega1284p to the NTSC TV. The TIMER1_COMPB ISR puts the CPU to sleep just before the TIMER1_COMPA ISR goes off.
Coming into this lab, I knew I wanted to implement the software first using the simple DAC used in the video game lab.† I first compiled the demo code and made sure I was able to send a complete video signal to the NTSC TV.† Also, I first implemented a one-player tetris game before attempting two player.
I then began to test drawing different pieces.† I drew a simple 4X1 piece by drawing 4 different lines.† However, realizing that it may be difficult for the player to see the board as really a grid, I instead made the piece by drawing four different small squares.† The draw_square function takes a coordinate and draws a 6X6 square (10X10 for one player) with the coordinate in the top left corner of the square.† Each piece calls this function 4 times with different coordinates. For example, the 4X1 piece would call draw_square for the coordinates (x,y) (x+1,y) (x+2,y) and (x+3,y).†
After I was able to draw the pieces, I tried to move the pieces down the screen.† I first developed a random number generator that chooses a random number between 1 and 7.† This number will determine what piece to draw.† I had a variable called update_piece that would be incremented every time the TV redraws the screen.† Once update_piece hits 100, I delete the current piece by drawing over it with black and redraw the piece with the y cooridinate incremented by one.† The pieces move faster as the game goes on.† This process continues until the current y-coordinate hit the bottom of the playing grid.† Once that happens, the random number generator picks a new number and then draws the specified piece back at the top.
I then had to find a way to make sure the pieces would stack on top of each other. This was one of the hardest parts of the lab.† After a couple misfires, I came up with an idea of creating a matrix that represents the playing grid.† It is initialized to hold zeros.† Each piece created is contained in a struct called shape. That struct holds a 4X2 matrix that holds the coordinates the piece takes up with its four squares.† Once the first piece hits the bottom, the matrix is updated. The matrix coordinates that match up with the pieces struct matrix are changed from zeros to ones.† Now, whenever a piece moves, it checks if the matrix has a one where it is about to move.† If it does, the piece must stop and a new piece is created.
After the pieces were stacking on top of one another, I implemented the keypad.† While implementing the right, left, and down was simple, the rotating was rather difficult. I created a ďspinĒ variable that would jump through the numbers 0, 1, 2, and 3.† When you click the clockwise or counter-clockwise, the spin variable is incremented or decremented respectively.† This number determines which way we drew the current shape. I had to add much more implementation to my shape drawing functions.† Each shape (besides the 2X2 shape since itís the same no matter how you rotate it) had to add ways of drawing the shape. For example, if we wanted to rotate the 4X1 piece that has the coordinates mentioned above, the piece would need to now have the coordinates (x,y) (x,y+1) (x,y+2) and (x,y+3).
After implementing the keypad and debouncing, I determined how to delete lines.† I check whether or not a full line of the board matrix is filled with ones after a piece hits the bottom. If thatís the case, I delete the corresponding lines, move the grid down the amount of lines deleted, and continue the game.† Once I implemented 2 player, I updated the opponents grid as well by creating ďnon-deletableĒ below their grid which pushes their board closer to the top.
I wasnít able to reach the initial goal of grayscale.† Nor did I implement sending a bad piece to the opponent once we clear a line.† But other than that, everything else works very well.† The pieces flow very well, the picture is very clear with no noticeable noise, and the video game plays just like a normal tetris game.† The debouncing isnít perfect.† Sometimes the keypad will think you clicked a button twice when you only meant to click it once.† But it isnít incredibly damaging the overall gameplay.
The software took up a lot more time than I expected.† The hardest part of the software was probably coming up with a way to have the pieces stack on top of each other.† Debouncing was also tedious.† I had trouble finding a good frequency of polling the keypad that would perfectly debounce the system.
I reached my goal of making a two player Tetris game that accurately implemented all of the normal gameplay of a Tetris game as well as some rules that I added.† I was unable to add grayscale to my project.
The video code follows the NTSC standards.† Our screen refresh rate is 60 frames per second and 262 lines per frame.† ANSI C standards were followed when writing code for the project.
I re-used some of Dr. Bruce Landís Debouncing code from Lab 2: Cricker Call Generator and his video signal code from Lab 3: Video Game.
We, the members of the IEEE, in recognition of the importance of our technologies in affecting the quality of life throughout the world, and in accepting a personal obligation to our profession, its members and the communities we serve, do hereby commit ourselves to the highest ethical and professional conduct and agree:
I can see no safety hazards in my project.†
There are no perceived conflicts of interest
his project is honest in stating claims or estimates
No bribery was offered to me during the making of this porject
I explain the technology and software of my design in heavy detail.†
6. to maintain and improve our technical competence and to undertake technological tasks for others only if qualified by training or experience, or after full disclosure of pertinent limitations;
This project gave me more of a grasp on problem solving through programming
I had a few of my friends play the game with me and they gave me helpful criticism.† Thank you to Dr. Bruce Land for the debouncing and video signal code.
No one was treated poorly during this project.
No one was injured during this project
Appendix A: Cost Details
∑ 3 White Breadboards = $7.50
∑ Mega1284 Microcontroller = $5.00
∑ 2 Keypads = $12.00
∑ 12V power supply = $5.00
∑ 9V power supply = $5.00
∑ NTSC TV = $5.00
Appendix B: Code
Click link for software:
Appendix C: Schematics
Row 1 2 3 A
Row 4 5 6 B
Row 7 8 9 C
Row * 0 # D
Col 1 4 7 *
Col 2 5 8 0
Col 3 6 9 #
Col A B C D
Appendix D: Code References
Dr. Bruce Landís Video Generation Webpage and Code
Dr. Bruce Lands Debouncing Code