| |||||||||||||||||
Machine Problem 3: Forest Racer
In this MP, you will write a program that implements a vertically scrolling driving game where the object is to navigate your car along the various pathways towards the finish line. Reading: Lab Notes -- Libraries (Chapter 9), Arrays (Section 7.1),Queues (Section 7.2), Keyboard (Section 10.1), Graphics (Chapter 11). (03/06/2006) The ScrollMap subroutine mistakenly listed Status as an output. This has been corrected. (03/06/2006) Important: It has been brought to our attention that occasionally mp3 will give an error before starting and fail to load. This occurs fairly infrequently, however before trying to figure out what it wrong with your MP if this happens, do a make clean and re-make your MP. This seems to solve the problem 99% of the time. Clearing the screen (cls in the command window) before running the MP (after re-making) also seems to help. (03/06/2006) A new version of the library is available which slows the game down a little. Use this if you want the map and car to move slower. libmp3-slower.zip (Note: We will use this to test your program) *(03/01/2006) New Map Added! channels.txt. Excel Sheet: channels.xls (Right click and select save as) *(03/06/2006) New Map Added! short.txt. Excel Sheet: short.xls (Right click and select save as). Use this one for debugging to avoid the "cannot load into memory" error in TD. Screen DumpBelow is a screenshot of an example run of the program. You can see the number of lives left in the upper right corner, represented by red hearts, as well as the car and various types of terrain.
Program SpecificationThe car drives along the map following the path represented by green squares. If the car crashes into a tree or water a life is lost and the game is paused until
the player respawns. At this point, the car is placed back on the correct path towards the goal. The game responds to the following key presses:
The Game MapThe entire map for the game is contained in an array called GameMap whose size can be up to a 255x80 (It will always have 80 columns). The number
of rows in the array is specified by the MapLength variable. Each row in GameMap represents one row on the display. Each value in GameMap
is one word in length, and contains the color and character specification (see Section 11.1.2 of the lab manual) for a given pixel on the screen. There are four defined values:
The five constants in bold are defined by EQU's at the top of mp3asm so you can and should use these mnemonics rather than the hex values. Program OrganizationThe program uses 80x25 text mode for the display. The map is drawn on rows 1-23 (zero-indexed) and the 0th and 24th rows should be black lines. The program has the following global variables:
SavKOff RESW 1 ; Keyboard interrupt vector
SavKSeg RESW 1
SavTOff RESW 1 ; Timer interrupt vector
SavTSeg RESW 1
CarState DB 0 ; Current state of the car-- 1 = Move Left, -1 = Move Right,
; 0 = Stopped, -2 = Dead
CarCol DB 40 ; Which column your car is in
CarTicks DB 0 ; Used to determine frequency of car movement
Scroll DB 0 ; Used to determine frequency of scrolling
CurrentRow DB 24 ; Current row in GameMap
Status DB 1 ; Current game status--0 = Paused, 1 = Playing
; 2 = Won, -1 = Lost
Lives DB 3 ; # of lives left
WinString DB 'You Win!!!','$' ;If you win
LoseString DB 'You Lose :(','$' ;If you lose
The program uses a circular queues to store keyboard scan codes. QBeg EQU 0 ; Beginning offset of queue area QCap EQU 2 ; Capacity of of queue QFront EQU 4 ; Index of front item QRear EQU 6 ; Index of next place to put rear item QData EQU 8 ; BYTE to input or output KQList RESB 0 ; Parameter list for Keyboard Queue KQBeg DW KQArea ; Offset of Keyboard Queue area KQCap DW 10 KQFront DW 0 KQRear DW 0 KQData RESB 1 KQArea RESB 10 The queue is specified by a parameter list. The first word of the list specifies the offset of the first byte of the queue area, where data are stored. The second word is the capacity of the queue c. The third word of the parameter list is the index of the byte at the front of the queue, and the fourth word is the index of the byte that will be new rear of the queue. These indices run from 0 to the c-1. The byte at the front of the queue is the next to be dequeued. If the front and rear indices are equal, then the queue is empty. If the the rear index is either one less than the front index, or one less than the front index plus c, then the queue is full. (So the maximum number of bytes that can be stored in the queue is actually c-1.) Enq uses the Data byte on the parameter list for the item to be enqueued, and Deq delivers the dequeued item into this byte. Below is a detailed description of all the functions you are responsible for writing. Document each subroutine with a header. In the Lab Notes, standards for headers appear on page 4, and examples of subroutines on pages 28-33 and 84-88. You may use libDrawGameEnd WITHOUT PENALTY
Friendly Advice
Files for MP3 are on the V: drive in the directory V:\ece390\mp3. In this directory are the program framework mp2.asm
and a running version of the program mp2lab.exe. Lab versions of subroutines are in libmp3.lib, which contains all subroutines of
LIB291 plus versions of the MP3 subroutines (libMain for Main, etc). You will use mp3xit instead of dosxit. You should start by copying these files
to your home directory with the following command: Demonstration, Documentation, and GradingDemonstrate your program to an ECE 390 staff member. As in MP2, keep an MP development log and write a cover memo, which should address the following questions:
After the demonstration, submit your program and cover memo. Your program will be graded according to the clarity of your design and the quality of your documentation. Gradesheet:
mp3.asm (program framework)
1 ; MP3 - Forest Racer
2 ; This program implements a vertically scrolling driving game
3 ;
4 ; Your name
5 ; Date
6
7 BITS 16
8
9 ;====== SECTION 1: Define constants =======================================
10
11 KVEC EQU 0024h ; Location of Keyboard Vector
12 TVEC EQU 0070h ; Location of User Timer Vector
13 ESCSCAN EQU 1 ; Scan code for ESC key
14 SPSCAN EQU 57 ; Scan code for spacebar
15 LEFT EQU 75 ; Scan code for left arrow
16 LEFT_UP EQU 0CBh ; Scan code for left arrow release
17 RIGHT EQU 77 ; Scan code for right arrow
18 RIGHT_UP EQU 0CDh ; Scan code for right arrow up
19
20 CHAR_P EQU 25 ; Scan code for 'P'
21 ROWS EQU 25 ; Number of rows in entire display
22 COLS EQU 80 ; Number of columns in entire display
23
24 MAXLIVES EQU 3
25 GAMESPEED EQU 02 ; Number of ticks between scrolling
26 CARSPEED EQU 1 ; Speed of the car
27 WON EQU 2 ; The game has been won
28 LOST EQU -1 ; The game has been lost
29 PLAYING EQU 1 ; The game is still being played
30 PAUSED EQU 0 ; The game is paused
31 DEAD EQU -2 ; The car hit something
32
33 NULL EQU 0
34 SPAWNBLOCK EQU 6ADBh ; The spawn block
35 FINISH EQU 0DFh ; The finish Line
36 WATER EQU 69B0h ; Water
37 TREE EQU 6A05h ; A tree
38 GROUND EQU 6AB0h ; The light block shape extended ASCII
39 BLOCK EQU 0DBh ; The block shape extended ASCII
40 HEART EQU 03h ; The heart shape
41 CAR EQU 06h ; Your Car (Spade)
42 BROWN EQU 06h ; Color attribute for brown
43 WHITE EQU 0Fh ; Color attribute for white
44 BLACK EQU 00h ; Color attribute for black
45 RED EQU 0Ch ; Color attribute for red
46
47 ;====== SECTION 2: Declare external procedures ============================
48
49 EXTERN ascbin, binasc, kbdin, dspout, dspmsg, dosxit
50
51 GLOBAL SavKOff, SavKSeg, SavTOff, SavTSeg
52 GLOBAL KQList, KQBeg, KQCap, KQFront, KQRear, KQData, KQArea
53 GLOBAL CarState, CarCol, CarTicks, Scroll, CurrentRow, Status, Lives
54 GLOBAL WinString, LoseString, MapLength, GameMap
55 GLOBAL Init, KbdInt, ReadKeyboard, UpdateMoves
56 GLOBAL ScrollMap, CollisionDetect, DrawStatus, DrawGameEnd
57 GLOBAL FindRespawn, Enq, Deq
58
59
60 EXTERN libInit, libKbdInt, libReadKeyboard, libUpdateMoves
61 EXTERN libScrollMap, libCollisionDetect, libDrawStatus, libDrawGameEnd
62 EXTERN libFindRespawn, libEnq, libDeq
63 EXTERN TimerInt, mp3xit
64
65 ;====== SECTION 4: Define stack segment ===================================
66
67 SEGMENT stkseg STACK ; *** STACK SEGMENT ***
68 RESB 64*8
69 stacktop:
70 RESB 0 ; NASM bug workaround
71
72 ;====== SECTION 5: Define code segment ====================================
73
74 SEGMENT code ; *** CODE SEGMENT ***
75
76 ;====== SECTION 6: Declare variables for main procedure ===================
77 SavKOff RESW 1 ; Keyboard interrupt vector
78 SavKSeg RESW 1
79 SavTOff RESW 1 ; Timer interrupt vector
80 SavTSeg RESW 1
81
82 QBeg EQU 0 ; Beginning offset of queue area
83 QCap EQU 2 ; Capacity of of queue
84 QFront EQU 4 ; Index of front item
85 QRear EQU 6 ; Index of next place to put rear item
86 QData EQU 8 ; BYTE to input or output
87
88 KQList RESB 0 ; Parameter list for Keyboard Queue
89 KQBeg DW KQArea ; Offset of Keyboard Queue area
90 KQCap DW 10
91 KQFront DW 0
92 KQRear DW 0
93 KQData RESB 1
94 KQArea RESB 10
95
96 CarState DB 0 ; Current state of the car-- 1 = Move Left, -1 = Move Right,
97 ; 0 = Stopped, -2 = Dead
98 CarCol DB 40 ; Which column your car is in
99
100 CarTicks DB 0 ; Used to determine frequency of car movement
101 Scroll DB 0 ; Used to determine frequency of scrolling
102 CurrentRow DB 24 ; Current row in GameMap
103 Status DB 1 ; Current game status--0 = Paused, 1 = Playing
104 ; 2 = Won, -1 = Lost
105 Lives DB 3 ; # of lives left
106
107 WinString DB 'You Win!!!','$' ;If you win
108 LoseString DB 'You Lose :(','$' ;If you lose
109
110 ;The game map. An XXx80 array of words, each specifying a specific part
111 ;of the map. First byte is the attributes, 2nd is the character.
112 %include "gamemap.txt"
113
114
115 ; You may declare additional variables here
116
117 ;====== SECTION 7: Program initialization =================================
118
119 ..start:
120 MOV AX, CS ; Initialize Data Segment register
121 MOV DS, AX
122 MOV AX, stkseg ; Initialize Stack Segment register
123 MOV SS, AX
124 MOV SP, stacktop ; Initialize Stack Pointer register
125
126 ;====== SECTION 8: Main procedure =========================================
127
128 main:
129 MOV AH, 2Ch ; Get current time of day
130 INT 21h ; (DH) = secs, (DL) = hundredths of secs
131 CALL Init ; Initialization
132 .mainLoop:
133 CALL ReadKeyboard
134 CALL UpdateMoves
135 CALL ScrollMap
136 CALL CollisionDetect
137 JMP .mainLoop
138
139
140 ;=============== Your Subroutines =========================================
141
142 KbdInt:
143 JMP libKbdInt
144 IRET
145
146 Init:
147 CALL libInit
148 RET
149
150 ReadKeyboard:
151 CALL libReadKeyboard
152 RET
153
154 UpdateMoves:
155 CALL libUpdateMoves
156 RET
157
158 ScrollMap:
159 CALL libScrollMap
160 RET
161
162 CollisionDetect:
163 CALL libCollisionDetect
164 RET
165
166 DrawStatus:
167 CALL libDrawStatus
168 RET
169
170 DrawGameEnd:
171 CALL libDrawGameEnd
172 RET
173
174 FindRespawn:
175 CALL libFindRespawn
176 RET
177
178 Enq:
179 CALL libEnq
180 RET
181
182 Deq:
183 CALL libDeq
184 RET
Makefile1 MPNAME=mp3 2 3 all: $(MPNAME).exe 4 5 clean: 6 rm -f $(MPNAME).exe $(MPNAME).obj $(MPNAME).lst $(MPNAME).map 7 8 %.exe: %.obj 9 tlink /c /v $<, $*.exe, $*.map, lib291.lib libmp3.lib 10 11 %.obj: %.asm 12 nasm -g -f obj -o $*.obj $< -l $*.lst 13 |
| Spring 2006 |