CSC258 Assembly Programming Project: Doodle Jump
Due: Friday, April 9, 2021, 10:00 PM. In groups of up to 2 students.
In this project, we will implement the popular mobile game Doodle Jump using MIPS assembly. You may play a version of the original game at this link.
Since we don’t have access to a physical computer with a MIPS processor, we will test our implementation in a simulated environment within MARS, i.e., a simulated bitmap display and a simulated keyboard input. The video below is the demonstration of a basic version of the game running in the simulator. As you can see in the keyboard-input window at the bottom of the screen, the player presses the key “j” to make the Doodler move to the left and pressed the key “k” move to the right, When no key is pressed, the Doodler falls straight down until it hits a platform or the bottom of the screen. If it hits a platform, the Doodler bounces up high into the air, but if the Doodler hits the bottom of the screen, the game ends. Your task in this project is to implement something similar to this demo, but better.
Note: what’s in the video is just a basic version of the game. Implementing exactly this will NOT get you the full credit in this assignment. You will need to add some additional features to it (more details below).
You may work on this project in individually or in a group of two. Before you start, find a partner (there is a “Search for Teammates” post on the discussion board) or decide to work individually. If you work in a group, create a group on MarkUs and invite your partner.
You will create an assembly program named “doodlejump.s”. There is no starter code. You’ll design your program from scratch. Below are a few tips that will help you get started.
Drive the Bitmap Display
To open and connect the bitmap display in MARS, click on “Tools” in the menu bar then select “Bitmap Display”. In the opened window, choose the appropriate configuration values (e.g., the values shown in the video above), and click on “Connect to MIPS” to plug the display into your simulated MIPS computer.
The display is essentially an array of “units” stored in memory (starting at the chosen “base address of display” and indexed with row-major ordering). Each unit consists of a group of pixels (as defined in “unit width/height in pixels” in the configuration). The size of the array is the total number of units in the display. For example, with the configuration in the above video demo, each unit is 8
pixels x 8 pixels and there are 32×32 = 1024 units on the display (since 256/8 = 32). Each unit is a 4-byte value which is the colour code of the unit. For example, 0x000000 is black and 0xff0000is red. To paint a specific unit on the display with a specific colour, you just need to store the right colour code at the right memory address (perhaps using the sw instruction). Tip: Do NOT use the base location of “.data” (static data) as the “base address for display” since it may cause the display data to overlap with the static data that you define in your program and cause interesting bugs.
Tip: Google “colour picker”, and you’ll find a tool to help you pick any colours you like for your game. Pick a few key colors (sky, bird, pipe) and consider storing them in specific registers so that it’s easy to put the colors into memory.
To help you get started, below is a short demo that paints a few units at different locations with different colours. Try to understand this demo first and make it work in MARS.
# Demo for painting # # Bitmap Display Configuration: # - Unit width in pixels: 8 # - Unit height in pixels: 8 # - Display width in pixels: 256 # - Display height in pixels: 256 # - Base Address for Display: 0x10008000 ($gp) # .data
displayAddress: .word 0x10008000 .text
lw $t0, displayAddress # $t0 stores the base address for display
li $t1, 0xff0000 li $t2, 0x00ff00 li $t3, 0x0000ff
# $t1 stores the red colour code # $t2 stores the green colour code # $t3 stores the blue colour code
# paint the first (top-left) unit red. # paint the second unit on the first row green. Why $t0+4?
sw $t1, 0($t0) sw $t2, 4($t0) sw $t3, 128($t0) # paint the first unit on the second row blue. Why +128?
Exit: li $v0, 10 # terminate the program gracefully syscall
The most common way to create animation is to periodically repaint the whole screen. When an object is painted at a new location, it gives the illusion that the object moved. To control the rate of repaints, i.e., the number of frames per second (FPS), you want the program to sleep for a certain amount of time after each repaint. See the “System Calls” section below to see how to do that. Tip: choose your display size and frame rate pragmatically. The simulated MIPS processor isn’t super fast. If you have too many pixels on the display and too high a frame rate, the processor will have trouble keeping up with the computation. That’s why in the demo video the game screen is fairly small. If you want to have a large display and fancy graphics in your game, you might consider
optimizing your way of repainting the screen so that it does incremental updates instead of redrawing the whole screen; however, that will be quite a challenge.
Receive Keyboard Inputs
To connect the keyboard in MARS, click on “Tools” in the menu bar and select “Keyboard and Display MMIO Simulator”. Then, click on the “Connect to MIPS” button on the bottom-left to plug in the simulated keyboard.
With memory-mapped I/O (MMIO), the data of the keyboard events are stored at a specific memory location. There are two values that we need to check. The first value is a 4-byte value that indicates whether there is a keystroke event — it is 0 if and only if there is no keystroke event happening. The second value is a 4-byte value that stores the ASCII code of the key that has been pressed
(given that there is a keystroke event). With the default keyboard configuration, the first value is stored at the memory address 0xffff0000 and the second value is stored at 0xffff0004. Look up the ASCII code of the lowercase letter “f” to see what value you should look for.