The control and game flow logic is completely coded in C. The main program must be able to display all the in-game graphics correctly on the TV screen without any artifacts. Additionally, the program must control the logic flow of the entire game. For instance, if the player punches the computer, how should the computer react? Finally, the program must also interface our hardware with the software, so appropriate actions are taken when the hardware is in used. In order to simplify our program design, we first designed the following flow chart:
The video code was based on Professor Land’s TV generation code, which we used in Lab 4 – Lunar Lander. The Timer1 interrupt is used to read a line of the 128x100 pixel video buffer and write it to the TV screen. In the main program, a while loop is being run continuously but stalled by an idle sleep command which makes the entry into the Timer1 interrupt service routine. However, it is very critical to finish all the code in the main program loop before the ISR is triggered in order to prevent artifacts.
Top Level Logics
The game is practically a huge state machine following the flow of the state diagram shown above. Of course, the state diagram only provides a brief description of the game while there are details that are included. For example, there are a couple of “Pause States” inserted to stall the program. Additionally, we implemented difficulty levels into the game itself. It is important to note how we determine the difficulty levels.
First of all, the ability for computer to dodge your punch is calculated by a randomized result. We also only allow certain amount of time for the player to dodge the computer’s punch. The differences in difficulty levels are implemented here. In easy mode, the computer could dodge 25% of the player’s punches, and the player has 3 seconds to dodge the computer’s attack. In medium difficulty, the computer dodges 50% of the player’s punches and the player has only 2 seconds to react against the computer. Finally, in hard difficulty, the computer dodges 75% of the player’s attack while the player only has 1 second to react against the computer’s punches. These logics are initialized in the INITIAL state of the state machine depending on the difficulty the player chooses. Moreover, the test conditions of these parameters are implemented in the COMP_PUNCH and RDM_RESULT states.
In order to make this game more difficult and more versatile, we implemented three different types of punches that the computer can throw. The computer could attack with left hook, right hook, and straight punches. Different types of punches require different styles of avoidance. The punches are also randomized, and each style has 33% chance of appearing when it is the computer’s term. These logics are implemented in the COMP_PUNCH state of the state machine.
Our scorekeeping system is based on Kalim Moghul and Kevin Oh’s Nova Strike game, which is made in Spring 2004.
The graphics of this game is one of the most challenging parts. Although our graphics are not extremely complex, but our game requires erasing the entire screen and redraw the graphics fairly often. Additionally, the TV routine limits all our calculation all within 1/60 of a second, or when LineCount hits 231. If our calculations and graphics drawing take too long, then artifacts would appear on the screen.
We implemented many different ways to approach this problem. First, since human eyes could not really detect any refreshing fewer than 4 frames on the TV, we divide up some complex erasing and drawing into 4 different frames. Although it takes 4 frames to completely redraw the graphics, human eyes cannot detect this trickery. Furthermore, we tried to limit redrawing the graphics as much as possible. Hence, we write special routines to erase the eyes and mouth of the computer character specifically when the computer is hit. This way, we do not have to redraw the entire face. For the messages on the bottom of the screen, such as Game Over, You Win, etc. We have found it is the easiest to just overwrite the messages with another video_putsmalls command while using “spaces” to cover up additional unwanted characters.
We have implemented special effects for our game. When the player strikes the computer or when the computer lands a hit at the player, we “shake” the screen intentionally. This effect is produced by disabling and re-enabling the timer interrupt. Assembly command, #asm ("cli"), is used to disable the interrupt. While assemblies command, #asm ("sei"), is used to re-enable the interrupt.
The most challenging aspect of this design is to be able to do complex calculations, drawings, erasing of screens, in the very limited time allotted. If we were not able to compute and draw fast enough, artifacts would form on our TV screen. We have learned to use flags and counters to make this part of the design simpler. We broke complex graphics drawings into 4 different frames by using a counter. Furthermore, it was also difficult to link our state machine with the main program, which is in charge of drawing. Since both routines are being executed simultaneously, it is very important to have the timing correctly when the two routines are communicating with each other. We used global flags to ensure these two routines are communicating correctly.