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

CPE 233 Final Project

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

File_000.jpeg
File_001.jpeg
File_003.jpeg
File_002.jpeg

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

Screen Shot 2017-03-18 at 4.17.10 PM.png

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

FullSizeR.jpg

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

Plug Everything In, Power Up and Have Fun!

Screen Shot 2017-03-18 at 5.43.24 PM.png

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