| ECE291 | Computer Engineering II | Lockwood, Spring 1999 |
PEZ WARS
== Screen Shots =============================================
Sample Map:
PEZ WARS is a multiplayer combat game with a top view. The combatants, Santa, Psychedelic Eye, Boba Fett, and Miss Piggy, roam one of four different rooms on the screen. The object of the game is to kill the other player(s) by shooting pez pellets. PEZ WARS has two modes of play, a single player vs. AI, and a networked mode. The AI has four different levels of difficulty. You can have up to 4 players in a networked game.
Pez Wars utilizes a tile based mapping format. Using this, we create four different maps for the players to roam around in. The tile map is its own PCX file that is loaded into its own segment. Various tiles are indexed and placed onto the screen; the screen will be double buffered in order to dramatically reduce screen flicker. All of our graphics are in a 320x200x256 format.
The networking for PEZ WARS uses peer-to-peer routines. The is the most efficient from of networking for this project. Each player may enter the game at any time during the play. Every player sends packets out and is responsible for processing the packets they receive.
Sound proposes another asset to the program. The sound consists of wav and MIDI files. The music is also screen dependent, and for that we will be using MIDI sound files. These will be done using the MIDPAK driver functions.
We based our code on given sound, network, and ECE 291 library functions, and the main procedure of MP5.
A verbal description of the main loop:
Find out from the PlayIntroandMenus function if this is a networked game. If it is networked go to the NetworkGame function (the main loop for a networked game). Initialize health and position, draw the screen with the appropriate map and player. Check for exit conditions (esc pressed or health = 0) and exit to the main, win or lose screen as appropriate. If the exit condition fails, then have the AI move and move the bullets on the screen. Continue this in a loop until we exit.
The NetworkGame is quite different in the sense that it sends Hello messages every 2 seconds. The Hello Message is a structure that gives the players current position, facing direction and status so when another player joins, the joining player can draw the existing characters in the appropriate positions. Update messages are sent 9 times per second. The Update Message structure sends out the current position, player number (which determines which character they are), status, the direction the player is facing, and which direction they shot a bullet in. Every player is responsible for moving all the bullets on their screens by keeping track of each players bullets in a separt bullet array. These arrays contain bullet structures. The bullet structures say whether the bullet is active, which character shot it (to determine the color to make it), and which direction it is going in. The bullet arrays are of length 6 so that each character can only have 6 bullets on the screen at a time.
Networking:
These constants signify the status of the players/bullets.
| NOTACTIVE | EQU | 3 | Player is joining the game |
| ACTIVE | EQU | 1 | Player is currently in the game |
| DEPARTING | EQU | 2 | Player is leaving the game |
These are various constants signifying what type of message
has been recieved over the network.
| HELLO | EQU | 20 | Current position for the new player who may be entering game |
| UPDATE | EQU | 21 | Update player's position |
| GOODBYE | EQU | 22 | Current player is leaving the game |
| FIRE | EQU | 10 | A bullet has been fired |
| GONE | EQU | 11 | A bullet has disappeared |
| BULACTIVE | EQU | 12 | Update the current bullet |
Sounds:
Listing of Wav Files
| santa | EQU | 0 |
| eye | EQU | 12 |
| piggy | EQU | 24 |
| boba | EQU | 36 |
| santabump | EQU | 48 |
| eyebump | EQU | 58 |
| piggybump | EQU | 68 |
| bobabump | EQU | 78 |
| playerselect | EQU | 88 |
| credit | EQU | 100 |
| theme1 | EQU | 111 |
| winthegame | EQU | 122 |
helpful midi command constants
| PlayCurSequence | EQU | 702h |
| Register | EQU | 704h |
| Stop | EQU | 705h |
| Resume | EQU | 70Bh |
| SndStatus | EQU | 70Ch |
| SequenceNum | EQU | 0 |
midi indexes
| hall | EQU | 0 |
| ride | EQU | 13 |
| death | EQU | 23 |
midi sizes
| deadsize | EQU | 3851 |
| hallsize | EQU | 16854 |
| ridesize | EQU | 32964 |
PCX file declaration taken from ECE291 Lab Manual
Macros.inc., constants.inc, MSGTypes.inc --- structures for networking
exitFlag db 0 ;This is a flag of when
to exit the program
oldKbdV db ? ;This is the old keyboard
handler interrupt address
tileArray db 'tiles.pcx',0 ;A null terminated
string to the tile picture
mapFile db 'map.map',0 ;A null terminated
string to the map file
openError db 'Error: File Not Found',CR,LF,'$'
;A message to display for bad opening of files
tileTable ;array of words pointing to indices of tiles to draw to the screen
playerTable ; array of words pointing to indices of player tiles to draw to the screen
midilist ; a list of available midi files to play
midisize ; the size of the midi file to be played
WavName ;used to determine wav to play
MidiName ;used to determine midi to play
fileno ; file handle for opening wavs
wavremaining ; number of bytes left for the dsp to process
wavlength ; total length of the wav to be played
wavdone ;0 if still playing, 1 if wav stopped
MapTable
| dw | offset MapData | first map |
| dw | offset MapData2 | second map |
| dw | offset MapData3 | third map |
| dw | offset MapData4 | fourth map |
PlayerType STRUC
This strcuture contains all the basic variables needed to draw
each player to the screen.
Status db INACTIVE Health db ? CurXPos dw ? CurYPos dw ? Character db ? Direction db ?
BulletType STRUC
This contains all the necessary information to write each bullet
to the screen.
Character db ? BulXPos dw ? BulYPos dw ? Status db BULACTIVE Direction db ?
GenericMSG STRUC
This is the generic networking message format.
MsgType db ? PlayerNum db ? Status db ?
HelloMSG STRUC
This is the message sent to each player to let everyone else know
he is still there.
MsgType db HELLO PlayerNum db ? Character db ? XPos dw ? YPos dw ? FaceDirect db ? FireDirect db ?
UpdateMSG STRUC
This message updates a players information across the network.
MsgType db UPDATE PlayerNum db ? XPos dw ? YPos dw ? FaceDirect db ? FireDirect db ?
FireMsg STRUC
This message is sent whenever any player fires a bullet.
MsgType db FIRE PlayerNum db ? BulXPos dw ? BulYPos dw ? Direction db ? Status db ?
GoodbyeMsg STRUC
This message gets sent when a player is leaving.
MsgType db Goodbye PlayerNum db ?
WavHeader STRUC
| format | db | 'RIFF' |
| filelen | dd | ? |
| wavefmt | db | 'WAVEfmt_' |
| fmt_len | dd | ? |
| fmt_tag | dw | ? |
| channel | dw | ? |
| samples | dd | ? |
| bystesps | dd | ? |
| bkalign | dw | ? |
| bitsps | dw | ? |
| data | db | 'data' |
| datalen | dd | ? |
| Main | Written By | All |
| Input: | None | |
| Output: | None | |
| Purpose: | This function just implements the main loop for the PEZ WARS program. It will justify when it is apropriate to leave the program, and will make sure all other function calls occur in order. |
| PEZWarsExit | Written By | Alex Jurcik |
| Input: | None | |
| Output: | None | |
| Purpose: | The purpose of this routine is to use DOS interrupt 21h routines to exit from the program and to clear up used memory |
| LoadMap | Written By | Alex Jurcik |
| Input: | mapFile = pointer to null terminated string containg map file name | |
| Output: | mapData updated | |
| Purpose: | This function loads and decodes the map file into an array of bytes stored under mapData |
| InitializeBuffer | Written By | Alex Jurcik |
| Input: | None | |
| Output: | None | |
| Purpose: | The purpose of this function is to copy balck to the entire screen buffer |
| LoadPCX | Written By | Alex Jurcik | adapted from Lab Manual |
| Input: | dx = pointer to null terminated string containing file name to open | ||
| Output: | None | ||
| Purpose: | The purpose of this routine is to open up a 320*200*256 PCX file. The file's contents are then stored in the variable PCX. |
| StorePCX | Written By | Alex Jurcik | Adapted from lab manual |
| Input: | ES:DI = segment offset address of where to store the information of variable PCX | ||
| Output: | None | ||
| Purpose: | The purpose of this function is to take the raw PCX data in variable PCX and convert it to a pixel array of color bytes in the location specified by ES:DI. This function also sets the display with the proper pallette entries. |
| DrawScreen | Written By | Alex Jurcik |
| Input: | VBuffer = image to draw to the screen | |
| Output | None | |
| Purpose: | This routine draws the entire video buffer to the screen. |
| MoveMap | Written By | Ava Jamshidi |
| Inputs | NONE | |
| Outputs | NONE | |
| Purpose | This routine takes the Video Buffer and draws it's entirety on to the screen | |
| Notes | NONE |
| MoveTileToBuffer | Written By | Alex Jurcik |
| Input: | BX = tile number index to write to the buffer | |
| DI = upper left spot on screen to start drawing the tile | ||
| Output: | VBuffer updated | |
| Purpose: | This routine takes an index from the tilearray and puts that tile in the screen buffer such that it will be drawn at position DI. This function will also implement cropping of the tiles, in order to have a smooth scrolling map. |
| MovePlayerToBuffer | Written By | Alex Jurcik and Ava Jamshidi |
| Input: | DI = screen offset to display player at | |
| ImFacing = index of player image array to display | ||
| Character = which character to display | ||
| Output: | VBuffer Updated | |
| Purpose: | This routine takes a position at which to draw a player, it then moves the correct image into the video buffer. This routine will also crop the images in case they are leaving the bounds of the screen. |
| MoveTileToMapImage | Written By | Alex Jurcik |
| Inputs | DI : pos on screen to display upper left corner of
tile BX : tile number to draw |
|
| Output | NONE | |
| Purpose | This routine takes and indes in teh tile array and a position. It then draws the appropriate tile to mapImage at the proper place | |
| Notes | NONE |
| FillBuffer | Written By | Alex Jurcik and Ava Jamshidi |
| Input: | None | |
| Output: | VBuffer updated | |
| Purpose: | Through calls to ProcessMap and MovePlayerToBuffer, this function will completely update the video buffer right before displaying it to the screen. This function will also determine when a bullet hits a wall, when a player hits a wall, and when a bullet hits a player. |
| ProcessMap | Written By | Alex Jurcik |
| Input: | mapData = array of bytes of tile indeces that make up the map | |
| Output: | VBuffer updated | |
| Purpose: | This routine draws a series of tiles to the buffer via calls to MoveTileToBuffer. It uses the data in mapData to determine which tiles to draw where on the screen. |
| KbdInstall | Written By | Alex Jurcik |
| Input: | None | |
| Output: | oldKbdV = address of old keyboard handler | |
| Purpose: | This routine installs the new keyboard interrput handler and saves the address of the old one to memory variable OldKbdV. This routine is from MP3. |
| KbdUninstall | Written By | Alex Jurcik |
| Input: | oldKbdV = address of old keyboard handler | |
| Output: | None | |
| Purpose: | This routine reinstalls the default DOS keyboard handler. |
| KbdHandler | Written By | Alex Jurcik |
| Input: | None | |
| Output: | MyXPos = new x-position of the player | |
| MyYPos = new YPosition of the player | ||
| ImFiring = flag for whether or not the person is shooting | ||
| ImFacing = direction that the player is facing | ||
| ExitFlag = whether or not to exit the program | ||
| Purpose: | This is an interrupt service routine for the keyboard. It updates a players current position, their direction, and whether or not they are firing. It will also set the exit flag when ESC is pushed. |
| MouseInstall | Written By | Ava Jamshidi |
| Inputs | none | |
| Ouputs | none | |
| Purpose | Sets a mask for the mouse which calls our
MouseHandler and is called from PlayIntroAndMenus |
| MouseUnInstall | Written By | Ava Jamshidi |
| Inputs | none | |
| Outputs | none | |
| Purpose | Restore Mouse driver to original state |
| MouseHandler | Written By | Ava Jamshidi |
| Inputs | CX : Pixel column position DX : Pixel row position |
|
| Outputs | Sets the "MenuClick" variable for the corresponding menu | |
| Purpose | Handles the users mouse interrupts and procedes with the appropriate screens and functions | |
| Notes | The variables set here will be used in PlayIntroAndMenus, which actully changes the menus |
| NetPost | Written By | Michelle S. Tarson |
| Inputs | RXBuffer with the message | |
| Ouputs | None | |
| Purpose | Communicate between networked players. Updates positions and facing directions of players, says when a player joins or leaves a game, says when a bullet was fired | |
| Notes | Determine which message was recieved, get all of the information from that message and but it in the appropriate array of structures (player or bullet). If you get a bullet hello message (a bullet was fired), then find the next open spot in the array for that player's bullet array and make that bullet active. |
| NetMovePlayerToBuffer | Written By | Michelle S. Tarson | |
| Inputs | DI = screen offset to display player at ImFacing = index of player image array to display Character = which character to display |
||
| Outputs | VBuffer Updated | ||
| Purpose | This routine takes a position at which to draw a networked player, it then moves the correct image into the video buffer. It loops through all the networked players and moves them to the buffer if they are ACTIVE. This routine will also crop the images in case they are leaving the bounds of the screen. | ||
| Note | Modified version of MoverPlayerToBuffer. Get the character, the direction the character is facing, and if they are firing from the player array. Also make sure you're in the right segment!! |
| NetworkGame | Written By | Michelle S.Tarson |
| Inputs | None | |
| Outputs | None | |
| Purpose | This function implements the networked main loop for the PEZ WARS program. It will justify when it is apropriate to leave the program, and will make sure all other function calls occur in order. | |
| Notes | Initialize the Network. Setup the timing for sending the messages. Initalize all players, set the beginning positions for the players to the corners of the map. Move any bullets that are on the screen. Draw the screen. Send a hello or update messgae if the time is right. Loop through until an exit is necessary. Display the win or lose screen as appropriate. Make sure to call NetRelease. |
| PlayIntroAndMenus | Written By | Ava Jamshidi |
| Inputs | Based on what the user clicks | |
| Outputs | NONE | |
| Purpose | To go to the next corresponding menu based on what the user has clicked on the screen | |
| Notes | Each menu has it's own variable which is set in the MouseHandler |
| FadeMenu | Written By | Alex Jurcik |
| Input | NONE | |
| Output | NONE | |
| Purpose | "Fades" between two pcx files | |
| Notes | NONE |
| FireBullet | Written By | Ava Jamshidi and Alex Jurcik |
| Inputs | NONE | |
| Outputs | -Sets Bullet status to active -Sets the bullets direction = to the variable ImFacing -Sets bounces to none -Sets character to my character -Sets the bullets initial positions |
|
| Purpose | Fires Bullet from player | |
| Notes | Called from the kbdhandler |
| MoveBullet | Written By | Ava Jamshidi |
| Inputs | BX : pointer to an array of six bullets | |
| Outputs | All bullet positions updated | |
| Purpose | Moves bullet on the screen. Also calculates when a bullet hits a player, and when a bullet leaves the bounds of the screen. If a bullet hits a wall, a bounce is implemented. | |
| Notes | Bullet status becomes inactive upon hitting a wall or hitting another player. This function does not actually redraw the screen |
| DrawBullet | Written By | Ava Jamshidi |
| Inputs | NONE | |
| Outputs | NONE | |
| Purpose | Draws bullet to the screen | |
| Notes | Puts bullet in buffer and draws accordingly to the screen |
| InitializeBullets | Written By | Alex Jurcik |
| Inputs | NONE | |
| Outputs | NONE | |
| Purpose | Sets all bullets in bullet array to 'GONE' (inactive) | |
| Notes | used before filling array, no loose bullets wandering around |
| DrawHealth | Written By | Alex Jurcik |
| Inputs | SI == offset of the image of your current health number in the tile image. | |
| Outpus | None | |
| Purpose | The purpose of this function si to write to the video buffer a health box with your current health value printed in it. The box appears in the lower right hand corner of the screen. |
| AIProcesses | Written By | Alex Jurcik and Ava Jamshidi |
| Inputs | AILevel : the level of AI that has been chosen by the user | |
| Outputs | The AI player | |
| Purposes | To have an AI player to play against in one player mode |
| MoveAIPlayerToBuffer | Written By | Alex Jurcik and Ava Jamshidi |
| Input | DI : screen offset to display player | |
| Output | NONE | |
| Purpose | Puts the AI character into the player buffer | |
| Notes | Also determines of the AI is firing as well |
| AIFireBullet | Written By | Ava Jamshidi and Alex Jurcik |
| Inputs | NONE | |
| Outputs | Same as FireBullet | |
| Purpose | Fires bullet from AI to player | |
| Notes | Called from the AI processes |
Sound will be based on the Sound Library. (Some functions only
minor changes from lib)
| ResetDSP | Written By | Don |
| Inputs | Base Address of SoundBlaster card. | |
| Outputs | AL--0 unsuccessful, else successful | |
| Purpose | Resets and initializes the SoundBlaster DSP |
| DSPWrite | Written By | Don |
| Inputs | Base Address of SB Card. Al:DSP command or data. | |
| Outputs | DSP function, no return value. | |
| Purpose | Sends a command to the SoundBlaster DSP I/O port | |
| Notes: | Polls DSP Status port until bit 7 = 0 then writes value to port |
| DSPRead | Written By |
|
|
| Inputs | Base Address of SB Card | ||
| Outputs | AL Data read in. | ||
| Purpose: | Reads data from the DSP read port. | ||
| Notes: | Polls DSP Status port until bit 7 = 1. Reads value from port. |
| InstallSB |
|
|
||
| Inputs: | None. | |||
| Outputs: | OldSBV = Far address read from interrupt vector table. | |||
| Purpose: | Installs the SoundBlaster interrupt vector for the game. | |||
| Notes: | The new SB interrupt address is put into interrupt vector table and the old one is saved in OldSBV. |
| RemoveSB |
|
Don | |
| Inputs: | None. | ||
| Outputs: | OldSBV = Far address read from interrupt vector table. | ||
| Purpose: | Removes the SoundBlaster interrupt vector and restores the old vector. | ||
| Notes: | The original interrupt address is put into interrupt vector table. |
| SBHandler | Written By | Don |
| Inputs: | Base address of SoundBlaster DSP. SoundBlaster IRQ number. | |
| Outputs: | Sends IRQ acknowledge signals to DSP and PIC. Also sends EOI. | |
| Purpose: | ISR to handle IRQ generated by DSP at end of DMA sequence. Acknowledges both DSP and PIC. |
| LoadSound | Written By | Don |
| Inputs: | CS = Source segment of the sound file | |
| DX = Source Offset of the sound file | ||
| ES = Destination segment of the buffer | ||
| DI = Destination offset of the buffer | ||
| CX = Length of the sound file data including the header | ||
| Outputs: | Sound segment contains the sound file. | |
| Purpose: | Loads a sound file into a memory segment. Used for loading both WAV and XMI sounds. |
| PlayBack | Written by | Don |
| Inputs: | AX = Segment of the sound file | |
| DI = Offset of the sound file | ||
| TimeConstant = Sound transfer rate | ||
| CX = Length of WAV file data including the header | ||
| Outputs: | Playback of a specified sound file. | |
| Purpose: | Plays back a specified sound file. |
| PlayWAV | Written By | Don |
| Inputs: | WavFile -- WAV file to be played. | |
| Outputs: | Plays back a specified sound file. Calls appropriate helper functions to set up playback. | |
| Purpose: | This procedure loads a specified WAV file to a buffer, sets the TimeConstant, and plays the sound file. |
| ProgramDMA | Written By | Don |
| Inputs | Segment of the transfer data file | |
| Offset of transfer data file | ||
| Base Address of SoundBlaster DSP | ||
| Transfer Data Length | ||
| DMA Channel number | ||
| Outputs | ||
| Purpose | Sets the DMAC up for the DMA transfer to the SB Card. |
| SetMixerVolume | Written By | Don |
| Inputs | Base I/O address of SoundBlaster DSP | |
| Outputs | Sets the MIDI and Master volume. | |
| Purpose | This procedure sets the Master, MIDI, DSP volume control registers of the mixer chip according to a specified level |
| GetSettings | Written By | Don |
| Inputs | none | |
| Outputs | BaseAddress of Soundblaster | |
| IRQ number of sound card | ||
| DMA Channel number | ||
| Purpose | Identifies the soundblaster settings on the computer |
| RegisterMidi | Written By | Don |
| Inputs | Segment of midi file | |
| offset of midi file | ||
| length of midi file | ||
| Outputs | flag for success/failure | |
| Purpose | registers a midi file for playback |
| PlayMidi | Written By | Don |
| Inputs | midiname - the index from the midi lookuptable for the file to be played | |
| midisize - the size from the midid lookuptable for the file to be played | ||
| Outputs | flag indicating playing or not | |
| Purpose | Plays the sequence from the currently registered midi file |
| StopMidi | Written By | Don |
| Inputs | none | |
| Outputs | none | |
| Purpose | stops the current midi selection |
| ResumeMidi | Written By | Don |
| Inputs | none | |
| Outputs | none | |
| Purpose | resumes playing of the curren midi selection |
| CheckMidi | Written By | Don |
| Inputs | none | |
| Outputs | AX - 1 if midi is still playing ; 0 if none playing | |
| Purpose | Checks status of current midi selection |
| PlayMidi | Written By | Don |
| Inputs | midiname - the name of the file to be played | |
| Outputs | none | |
| Purpose | This procedure loads a midi file into a buffer, registers it and plays the specified sequence |