How to Make: a Canyon Flight Simulation Game
by SalCortes in Craft > Digital Graphics
1502 Views, 5 Favorites, 0 Comments
How to Make: a Canyon Flight Simulation Game
Introduction: Cal Poly Computer Engineering 233
For our CPE 233 final project we decide to make a game, called The Canyon Flight Simulator using our RAT Microcontroller that we designed during the span of seven weeks. In addition to also learning RAT Assembly language. For our final project we complemented both skills to create our Canyon Flight Simulator game.
Our game consist of a Plane represented by a pink pixel on the VGA screen and a green map that represents canyon walls. The objective of out game is to avoid hitting the canyon walls (green side walls). As you navigate through the map you score will increase. The score is then displayed on the seven segment display. To move left you simply have to turn on switch 3 to go right and switch 0 to go right. The highest score possible is 255 and once that score is reached the game starts over.
Gather Your Parts and Material
1. Xilinx Vivado 2016.2 https://www.xilinx.com/support/download/index.htm
2. Basys 3 FPGA Board https://www.xilinx.com/support/download/index.htm
3. Micro USB cable
4. VGA to VGA video cable
5. VGA Monitor
6. RAT Assembler
Design a Flow Chart
The first step to creating your Canyon Flight Simulation game is to design a flowchart, this step is crucial since flow chart will serve as a guide.
- The flow chart shown above consist of an overview of the game. The game will begin by displaying START on the screen. It will stay idle in this screen until the user presses the start button or flips a switch. Once the user presses the button the game will begin. A previous determined map will be displayed on the screen, as well as a one pixel plane and the distance counter will begin counting.
- As the user progresses through the map the the map flow speed will increase. At the same time a process is keeping track of any button and switches presses and most importantly a different process will check to see if the plane has crashed. This process will end the game if the plane has crashed, a black screen will appear displaying game over.
- Finally if the plane has not crashed and the maximum distance has been reached the game will end.
This flow chart will come in handy when programming the game in the RAT Assembler.
Write Your RAT Assembly Program
Note: The following code omits the START display screen code for simplicity. Attached is the complete RAT Assembly Code, including the START display screen code.
.DSEG .ORG 0x00<br>
;---------------------Initialize your Map pattern .DB 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x08 .DB 0x0A, 0x0C, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 .DB 0x14, 0x15, 0x17, 0x019, 0x017, 0x15, 0x13, 0x11 .DB 0x10, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E
.CSEG .ORG 0x94
.EQU FB_HADD = 0x90 .EQU FB_LADD = 0x91 .EQU FB_COLOR = 0x92 .EQU CHECK_COLOR = 0x93 .EQU SSEG = 0x81 .EQU LEDS = 0x40 .EQU SWITCHES = 0x20 .EQU INSIDE_FOR_COUNT = 0xB4 .EQU MIDDLE_FOR_COUNT = 0xCA .EQU OUTSIDE_FOR_COUNT = 0x4A
INIT: ;-----------------INIT FOR MAP---------------------------- MOV R7, 0x00 ;y = 00 STARTING MOV R8, 0x00 ;x = 00 STARTING MOV R4, R7 ;y coordin MOV R5, R8 ;x coordin MOV R6, 0x0F ;SOME COLOR GREEN MOV R2, 0x00 ;counter for black path MOV R1, 0x0E ;COUNTER TO DRAW HORIZANTALLY COLORED MOV R10, 0x1D ;reset for queue MOV R9, 0x00 ;count to 30 for 1 screen MOV R0, 0x00 ;register for queue MOV R28, 0x00 ;"distance counter" ;--------------------INIT FOR PLANE------------------------- SEI MOV R20, 0x00 ; main loop MOV R22, 0x1D ;y =29 MOV r23, 0x14 ;x=20 MOV r24, R22 ;y coordin MOV r25, r23 ;x coordin MOV r30, 0xF0 ;color MOV r15, 0x00 MOV r13, 0x00 ;------------------------------------------------------------ DRAW_HORIZANTAL_COLOR: LD r1, (r0) ;Load from Queue MOV R6, 0x0F ;SOME COLOR CALL DRAW_ROW ;DRAW A DOT AT A SAFE STARTING LOCATION 0xFF ADD R8, 0x01 ; MOVE X TO THE RIGHT ONCE CMP R1, R8 ;comapre x with mem val BRNE DRAW_HORIZANTAL_COLOR
DRAW_DARK_HORIZANTAL: MOV R6, 0x00 ; BLACK COLOR CALL DRAW_ROW ; DRAW A DOT ADD R8, 0x01 ; MOVE X TO THE RIGHT ONCE ADD R2, 0x01 ;count to length of black CMP R2, 0x0C ; DARK LINE LENGHT OF 12 BRNE DRAW_DARK_HORIZANTAL
DRAW_HORIZANTAL_COLOR_CONT: MOV R6, 0x0F ;SAME GREEN COLOR CALL DRAW_ROW ;DRAW A DOT AT A SAFE STARTING LOCATION 0xFF ADD R8, 0x01 ;MOVE X TO THE RIGHT ONCE CMP R8, 0x28 ;BRANCH OUT WHEN YOU REACH EDGE OF SCREEN 0x27 =R4 BRNE DRAW_HORIZANTAL_COLOR_CONT RESET: ADD R9, 0x01 ;count 30 MOV R8, 0x00 ;RESET THE LOCATION OF X TO INNTIAL LOCATION MOV R2, 0x00 ;RESET DARK LINE LENGHT COUNTER ADD R7, 0x01 ;increment Y ADD r0, 0x01 ;increment queue CMP R0, 0x1E ;check if queue is at end BREQ RST_INDEX ;branch to roll queue back to zero Q_BACK: CMP R9, 0x1E ;count to 30 for number of rows BREQ RESET_Q ;branch after filling screen BRN DRAW_HORIZANTAL_COLOR
RESET_Q: CALL SR_CHECK ;check to see if we hit a wall CALL DRAW_DOT ;draw dot MOV R9, 0x00 ;reset 30 count to zero MOV R7, 0x00 ;reset y to zero MOV R0, R10 ;index queue SUB R10, 0x01 ;adjust index for queue BRCS RESET_TO_29 ;branch for underflow RETURN_FROM_29: CALL timedelay ;time delay between drawing full screens BRN DRAW_HORIZANTAL_COLOR
;-------------DRAW_ROW--------------------------------------------- DRAW_ROW: MOV R4, R7 ;y coordin MOV R5, R8 ;x coordin OUT r5, FB_LADD ; write bot 6 address bits to register for x axis (40) OUT r4, FB_HADD ; write top 5 address bits to register for y axis (30) OUT r6, FB_COLOR ; write data to frame buffer RET ;---------------DELAY BEFORE GOING TO NEXT Y LINE---------------
timedelay: MOV R17, OUTSIDE_FOR_COUNT outside_for0: SUB R17, 0x01 MOV R18, MIDDLE_FOR_COUNT middle_for0: SUB R18, 0x01 MOV R19, INSIDE_FOR_COUNT inside_for0: SUB R19, 0x01 BRNE inside_for0 OR R18, 0x00 BRNE middle_for0 OR R17, 0x00 BRNE outside_for0 OUT r28, SSEG ADD r28, 0x01 RET ;------------------------SUBROUTINES--------------------------------------- RST_INDEX: MOV R0, 0x00 ;roll queue back to zero BRN Q_BACK ;--------------------------------------------------------------------------------------------- RESET_TO_29: mov r10, 0x1D ;roll queue back to 29 when we have underflow BRN RETURN_FROM_29 ;-------------------------------------------------------------------------------------- draw_dot: OUT r25, FB_LADD ; write 6 address bits to register for x axis OUT r24, FB_HADD ; write 5 address bits to register for y axis OUT r30, FB_COLOR ; write data to frame buffer RET ISR: ADD r15, 0x01 ;count Interrupts OUT r15, LEDS ;display count of LEDs IN R16, SWITCHES ;input val from switches into r16 CMP R16, 0x01 ;check for right switch BREQ move_right CMP R16, 0x04 ;check for left switch BREQ move_left BRN ISR_RETURN ;return from interrupt ;---------------------------------------------------------------------------- move_left: MOV r25, r23 ;x coordin MOV r24, R22 ;y coordin CALL DELETE_PRE_DOT
SUB r23, 0x01 ;mov x left MOV r24, R22 ;y coordin MOV r25, r23 ;x coordin CALL draw_dot
BRN ISR_RETURN ;--------------------------------------------------------------- move_right: mov r25, r23 ;x coordin MOV r24, R22 ;y coordin CALL DELETE_PRE_DOT
ADD r23, 0x01 ;mov x right MOV r24, R22 ;y coordin MOV r25, r23 ;x coordin CALL draw_dot BRN ISR_RETURN
;--------------------------------------------------------------- SR_CHECK: out r25, FB_LADD ;get the x coord of planes location out r24, FB_HADD ;get the y coord of planes location in r13, CHECK_COLOR ;check background color cmp r13, 0x00 ;make sure its black BRNE game_over ;if not black game over ret ;------------------------------------------------------------------- ISR_RETURN: RETIE
DELETE_PRE_DOT: MOV R21, 0x00 ; black color OUT r25, FB_LADD ; write 6 address bits to register for x axis OUT r24, FB_HADD ; write 5 address bits to register for y axis OUT r21, FB_COLOR ; write data to frame buffer draw black there to delete plane RET game_over: MOV r25, 0x00 MOV r24, 0x00 loop: MOV R21, 0x00 ; black color OUT r25, FB_LADD OUT r24, FB_HADD OUT r21, FB_COLOR ADD r25, 0x01 ADD r24, 0x01 BRN loop ;----------------------Interrupt--------------------- .CSEG
.ORG 0x3FF BRN ISR
Downloads
Plug Everything In, Power Up and Have Fun!
The final step is to program your Basys 3 board with your pre built RAT MCU.
Notice that your assembly code is the prog_rom.vhd file that is created when you simulate your RAT assembly program and this file needs to be changed in your MCU before you upload to your Baysis 3 board.
Authors: Andy McKeown & Salvador Cortes Soancatl
Cal Poly Winter 2017 - CPE 233