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.
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 32x32 = 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 0xff0000
is 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 # $t1 stores the red colour code li $t2, 0x00ff00 # $t2 stores the green colour code li $t3, 0x0000ff # $t3 stores the blue colour code sw $t1, 0($t0) # paint the first (top-left) unit red. sw $t2, 4($t0) # paint the second unit on the first row green. Why $t0+4? 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.
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.
The following link has a list of the MIPS system calls that are available in the MARS simulator.
You will find some of the system calls useful (and necessary) for certain tasks such as sleeping for an interval (to control the frame rate), generating random numbers (for obstacle positions), and terminating the program. Read the doc and find what you need!
Here some general tips for the design of your program.
.data
" section (static data) of your code to declare
as many variables as you need.This assignment is worth 9 marks, which will be awarded according to the following five milestones.
2/9
): the Doodlers and the platforms are properly
drawn (statically) on the screen. 4/9
): the movement controls of the Doodler
and the platforms (by the keyboard and timers) are properly implemented.6/9
): a basic version of the game (similar to the one shown in
the video demo above) is properly implemented.8/9
): one or two of the approved additional
features (listed below) are properly implemented.9/9
): at least three of the approved additional
features (listed below) are properly implemented.Below is the list of approved additional features. ONLY features on this list will be considered valid additional features and given credit. If you would like to request adding a feature that is not on the list, please email the instructor. The list on this page will be updated if the requested feature is approved.
Note:
All requests regarding additional features must be sent
before 10:00 PM on March 31, 2021. We will freeze
the feature list and no longer accept new requests after this deadline.
j/k
" and one by "d/f
").The code you submit ("doodlejump.s
") MUST include a
preamble (with the format specified below) at the beginning of the file.
The preamble includes information of the group members, the
configuration of the bitmap display, and the features that are
implemented. This is necessary information for the TA to be able to mark
your submission.
Submissions without a proper preamble will NOT be marked and will receive 0 mark.
Below is an example/template of the preamble. Copy and paste it to your code and update the information accordingly.
##################################################################### # # CSC258H5S Winter 2021 Assembly Programming Project # University of Toronto Mississauga # # Group members: # - Student 1: Name, Student Number # - Student 2 (if any): Name, Student Number # # 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) # # Which milestone is reached in this submission? # (See the assignment handout for descriptions of the milestones) # - Milestone 1/2/3/4/5 (choose the one the applies) # # Which approved additional features have been implemented? # (See the assignment handout for the list of additional features) # 1. (fill in the feature, if any) # 2. (fill in the feature, if any) # 3. (fill in the feature, if any) # ... (add more if necessary) # # Any additional information that the TA needs to know: # - (write here, if any) # #####################################################################
You will submit your "doodlejump.s
" (only this one
file) by using the web submission interface of
MarkUs. You can submit the same filename multiple times and only the
latest version will be marked, so it is a good practice to submit
your first version well before the deadline and then submit a newer
version to overwrite when you make some more progress. It is also a
good idea to backup your code after completing each milestone or
additional feature, to avoid the possibility that the
completed work gets broken by later work. Again, make sure your code
has the required preamble as specified above.
Late submissions are penalized by 1% for every hour of lateness, rounded up, to a maximum of 24 hours. Submissions will no longer be accepted 24 hours past the deadline, except for documented unusual circumstances.
Please note that ALL submissions will be checked for plagiarism. Make sure to maintain your academic integrity carefully, and protect your own work. It is much better to take the hit on a lower assignment mark (just submit something functional, even if incomplete), than risking much worse consequences by committing an academic offence.