Author: Songhui Cao (caosh2022).
As CS110 is coming to an end, it's time to put the skills we've learned into practice.
In this project, you will code in C language and RISC-V assembly to implement a STG (Shooting Game). You will also use PlatformIO to cross-compile and generate a program for the Longan Nano development board.
While we do have a Reference Implementation, you are not required to fully replicate it. Once you have completed the basic requirements, you are free to add or modify more features according to your preferences.
We hope you enjoy playing with Longan Nano in this project.
Important Note 1: Project 4 this year is an individual project - one person, no teammate.
Important Note 2: We only score the STG, no Flappy Bird nor others. You may implement your own game for fun, but they are not scored.
Important Note 3: Start from Lab 11 Template.
Your implementation should look like the Reference Implementation, but we do not require them to be exactly identical. For unspecified requirements, please refer to the reference firmware for detail. If there are ambiguity, first check Piazza post @168, then post on Piazza.
The objective of Project 4 is to let you show all your techniques learnt in CS110. Therefore, the Grading Rubrics of Project 4 this year splits into 2 parts: Proof of Your Knowledge, and Proof of Work.
This is the basic part and focuses on your knowledge learnt in CS110.
Objective: In Lab 4 and Project 1.2, you have already learnt how to write RISC-V code with Venus emulator. Now, it is time to practice writing real RISC-V code. In this project, please show that you are capable of writing RISC-V code on real hardware with relatively comprehensive logics.
Task: Implement your scenario selection screen (with at least 3 choices) as a RISC-V function.
Note: In 1.1, handwritten assembly code is required, and the submission of assembly code generated by a compiler (e.g., from high-level languages like C) is prohibited.
(1.5 Point) 1.1.1 Meaningful RISC-V code.
Prerequisite: None.
Requirement:
LCD_ShowString
and input-related functions. You may implement your own input-related functions in C.Items 1-3 count as 1 point, and item 4 counts as 0.5 point.
(0.5 Point) 1.1.2 Parameter and return value passing.
Prerequisite: At least 1.0 point in 1.1.1.
In Lab 4, you have learnt the basic calling convention in RISC-V. Now, use it in real world.
Requirement: Your RISC-V code receives some parameters (such as the initial selection) from C, and returns some value to C. Using global variables will not grant you score for this part.
(0.5 Point) 1.1.3 Manipulating global variables.
Prerequisite: At least 1.0 point in 1.1.1.
Objective: Besides parameters and return values, RISC-V code can interact with C code using global variables. Let your RISC-V code read or write some global variables directly.
Requirement: Your RISC-V code modifies some global variables. Viable examples include but are not limited to receiving scenario list using global variables and returning selected scenario using global variables.
(0.5 Point) 1.1.4 Learn to use dis-assembler.
Prerequisite: None.
Objective:
In Project 3, you possibly have learnt to use profilers, but you may not be aware of what assembly code the compiler will generate when you write in C. However, a good C programmer should foresee the assembly code and CPU internal states through the C code. Therefore, learning to use dis-assembler is of significant importance for C programmers.
In this project, you will use the dis-assembler to convert compiler-generated binary file (.o
and .elf
) into assembly code.
We recommend that you use riscv-nuclei-elf-objdump
in the Longan development kit for CA1 (Link valid until June 20, 2025) as dis-assembler.
Requirement: Answer the following questions.
for
or while
loop in your C code, locate it in the assembly, and show its compiled result.(1 Point) 1.2.1 There are some pixels representing player on the screen and the player can move in response to keyboard input.
(1 Point) 1.2.2 Player can shoot. Whether or not the bullets are seeking towards the enemy does not matter.
(1 Point) 1.2.3 There are pixels representing enemies on the screen and the enemy can move.
(1 Point) 1.2.4 Enemies can shoot. However, we do not require that the player dies when being hit by the enemy's bullets. Therefore, you can safely ignore the hitbox of player (and create bullets in an insane density).
Prerequisite: At least 1.0 point in 1.1.1, or a showcase to prove the correctness of your algorithm.
The mechanical buttons inherently introduce noises or instabilities, i.e., when you press a physical button, the signal may not be continuous, possibly causing multiple triggers per press. The most straightforward way to address this issue is to read the input every fixed durations, but this workaround ignores short trigger that starts after a read and ends before the next read.
In this task, we require you to implement an algorithm that reads button input, and filters out noises or other instabilities. Specifically, if the user pressed key at time and this causes to be triggered, then cannot be triggered again before , while other keys can.
Prerequisite: At least 3.0 point in 1.2.
In Lecture 4, you have learnt the basics of C memory management. Lab 2 and Homework 3 highlighted the importance of memory management. Longan Nano have relatively rich RAM capacity (32 KB) amongst micro controllers, but it is still small compared to a personal computer (PC).
Therefore, memory safety is critical to this project. Make sure your implementation manages memory correctly so that your STG does not crush or stop responding during the entire check procedure.
Requirement: Your STG does not crush or stop responding during the entire check procedure.
Note: We encourage rigorous stress testing on your implementation prior to the final check, to ensure your memory safety.
Prerequisite: At least 3.0 point in 1.2.
Requirement: Your screen does not blink, and your peak frame per second (FPS) is above 25. Show your FPS or the sum of frame computation and rendering time on screen, so the TAs know your peak FPS.
The FPS counter may (not required) show the averaged result from 0.12-0.15 seconds consecutively to improve readability.
Note: The sample firmware in Lab 10 is an example of blinking. The phrase Your screen does not blink means your screen does not have visual blinking, or you update only necessary pixels instead of calling LCD_Clear
and its equivalents periodically.
Note: Piazza post @166 and @167 presents two optional bugfixes for the LCD library.
Prerequisite: 1.0 point in 1.5.
Keep minimal FPS (Frames Per Second) during normal gameplay above 30, and support at least 128 bullets (including the bullets shot by the player and the enemy) on the screen simultaneously. Show an entity counter on screen so we know how many bullets you support.
The FPS counter and entity counter should show the averaged result from 0.12-0.15 seconds consecutively to improve readability.
While keeping your minimal FPS above 30, your score for 2.1 is computed using the following table:
# of Bullets Supported | Score |
---|---|
1.5 | |
1.8 | |
2.0 |
Hint: The reference implementation customized the LCD library for maximum efficiency.
Prerequisite: At least 3.0 point in 1.2 Basic Gameplay Experience.
Requirement:
float
, because the compiler automatically inserts software floating point number library into your code. If you use float
in Project 4, select one float
-related operation, then show TA the complete code path of it in the assembly. Otherwise, prove that you are not using float
in Project 4.Note: Using float
in Project 4, especially in item 2.2, significantly reduces workload for you, so we add the second requirement here to balance the workload.
(1 Point) 2.3.1 Implement at least 3 types of bullets that is different in shape.
(1 Point) 2.3.2 Implement at least 3 types of bullets that is different in trajectory. Homing bullet does not count here.
(1 Point) 2.3.3 Implement at least 3 types of enemy with different shooting pattern.
(1 Point) 2.3.4 Integrate 2.3.1, 2.3.2 and 2.3.3 into one complete scenario with playable content of at least 1 minute.
Note: In 2.3.1, 2.3.2 and 2.3.3, shape or trajectory and is different from each other, if and only if there exists no way to turn into via arbitrary combination of scaling, translation, and rotation. We do not consider color difference in 2.3.