ECE 291 Final Project:

Team Members:
Shane Ryoo: Introduction, Menus, Timing, Credits
Paul Voelker: Networking
Bob Waldrop: Graphics & Game Engine
Jeff Gomberg: Game Engine / Physics
Darrell Micheli: Music & Sound FX


Introduction

In the olden days, people played Asteroids, a game where one pilots a starship through the midst of asteroids, attempting to destroy them before they destroy the pilot. And there would be UFOs flying around, trying to destroy you as well.

However, humanity always fights among itself. And thus...


Description of Game

This two player game is very similar to any other space duel that you may be familiar with.  Two ships with equal capabilities (not necessarily equal in all categories) fight each other on a single space map.  A nearby gravity well (a planet) gravitationally affects space travel and makes the game play more interesting.  The game concludes with the destruction of an opponent or a cry for uncle by hitting the escape key.  Network and sound enchanced play make the battle more realistic and a choice of five different ships make game play more random.  This game is essentially a two player Asteroids or Comet Busters without the asteroids.

This is more advanced than anything we're seen in the 291 final projects, because it will have a gravity well, multiple ship types, and the destruction beam (which is basically a lightsaber from Star Wars, except for a spaceship). Music and good sound FX will be included, networking (via NetBIOS) will be an option (although it was not integrated at the time of handin), and the graphics will be encoded in PCX format.


Implementation

The best way to describe the general workings of this project is to point out how the work has been divided among the team members.  Five members of the team are in charge of the following segments of work:  Non-game code (intro, menus, credits, etc.), sound, physics, graphics and networking.

The game first loads with the THX header seen in movie theaters. Then a "Productions" screen, and then the title screen (at the beginning of the page) comes up. These all fade in and/or out, using several subroutines. Next, the menu screen fades in. It allows players to choose one of five different ship types. Each of the ships will have different abilities including thrust, angular velocity, number of special weapons and shields, but all ship abilities will be normalized (e.g. a faster ship may have fewer shields than in its slower counterpart or a ship with more special weapons may have a slower angular velocity).  This is accomplished with a large array of values for each ship description (in the form of a look up table). This is important, as ships that turn very fast have fewer images to cycle through when turning than ships that turn more slowly. The graphics holding all the different directions of two different ships are shown below.

Each ship is designated by a number, with the first number pressed being assigned to Player One, the next to Player Two, and it toggles back and forth. For a networked game, the server will take the ship it selected for Player One, and the client will take the ship it selected for player Two.Then the players choose the type of game they want: Non-networked, networked server, or networked client (although with the way our network code was developing, one networked selection would have been sufficient). One can also look at the instructions, or exit.

The playing field for the ships is a 320 X 200 resolution screen background with a singular, fixed light source.  Thus, when a ship's image is loaded at a particular angle, the graphic (sprite) will be lit on the side facing the fixed light source.  The light source intensities will not change with distance from the source (for simplicity).  There will also be a gravity well that will affect/hinder travel. Ships that fly off of the screen will be looped back around to the next part of the screen using location mod screen height/width (and a few other modifications).  The physics section of the game (along with the graphics section) will determine ship positions and angles (along with the weaponry) based on the gravity well and user inputs. As soon as position calculations finish and the network has been updated, the changes will be posted to the CRT. Lastly, the sounds corresponding to a hit, explosion and potentially a collision will be sent to the sound card.

Graphically, ships and explosions are drawn from offsets into a PCX file. The relevant part of the explosions file is to the right.

The networked part of the game will set up one machine as the server and another as a client.  The client machine will send interrupt data from the keyboard/mouse to the server for processing.  The server will then return calculated data concerning ship (and weapon fire) location and sound to the client, for refreshing. The variables changed by interrupts on the server machine (by the player on the server) will be used along with the client data to determine new ship positions and weapon fire.  A large array will be the medium for updates on both machines.  The data sent to the server will, of course, also be used to update the server's CRT.

As stated before, the program itself begins with an introduction. Then a graphical menu comes with options for ships, and to start a game as either the game server, game client, or a dual-player single computer game. There are also options for instructions or exiting.

The empty combat area is displayed to the right. Status bars, ships, and destruction beams are drawn separately.

At the beginning of a match, Player One starts in the upper left part of the screen, and Player Two starts in the lower left part of the screen. The planet is in the middle right of the screen. The match continues until one of the players dies or the escape key is hit. If a player died, a "Player #" screen comes up. In any case, the program returns to the menu screen, and everything starts over again.

When exiting is selected, the program simply fades in and out several different pcx files.

We have included pseudocode for the game engine for perusal.

 


Screen Shots

 

Action Shot With Line Clip

Action Shot--Special Weapon

Exploding Ship Screen Shot

Main Menu Selection Shot

void GAME_ENGINE (global variables){

setup_game_data();
install_key_interrupt handler();
load_background_screen();
load_selected_ships_into_buffer();

while(!esc_key){
update_ship_locations(); //calls physics calculations
update_weapon_fire();
//checks for collision with planet/ship
//and updates shields
update_statistics();

if(ship == destroyed){
do_explosion();
break;
//and makes the appropriate sound calls.
//This only changes the ship of interest
}

if(ship == hit){
update_shields_block();
//shows the shields blocking the fire
//from reaching the hull. (another sprite)
if(network_is_on)
send(global_array);

erase_old_ship_locations();
erase_old_weapon_fire();
draw_ship_locations(); //to screen buffer
draw_weapon_fire(); //to screen buffer
display_changes(); //to Vid segment
play_sounds(); //to card
}

Updated game engine loop:

void GAME_ENGINE (global variables){

setup_game_data();
install_key_interrupt handler();
load_background_screen();
load_selected_ships_into_buffer();

while(!esc_key){

adjustangles();
update_ship_locations(); //calls physics calculations
erase_old_ship_locations();
erase_old_weapon_fire();
drawship();
drawlaser(); //if interrupt called
play_laser_sound();

if(ship == hit){
update_shields_block(); //shows the shields blocking the fire
//from reaching the hull. (another sprite)
if(ship == collision)
update_shields_block();

if(ship == destroyed){
do_explosion(); //This only changes the ship of interest
break; //and makes the appropriate sound calls.
}

update_statistics();
drawship(); //must be done because the laser is overlapping
//draws ship according to calculations in collision attack

}

Here are the segments used by the program.


VIDSEG--has the actual Screen Segment
SBSEG--has the ScreenBuffer
SHAPES_SEG--(may need two+ of these for our five ships) holds the sprites of the various ships.
TEST_SEG--contains a two color map of objects that can be checked for collisions

Here are the general variables used by the program.

Picture variables
KeyPic db 'grphx/Keys.PCX', 0
TestPic db 'grphx/Test.PCX', 0
ShipOne db 'grphx/ShipOne.PCX' , 0
ShipTwo db 'grphx/ShipTwo.PCX' , 0
ShipThree db 'grphx/ShipTh~1.PCX' , 0
ShipFour db 'grphx/ShipFour.PCX' , 0
ShipFive db 'grphx/ShipFive.PCX' , 0
ExplodePic db 'grphx/Explos~1.PCX' , 0
BackgroundPic db 'grphx/backgr~1.PCX' , 0
TestgroundPic db 'grphx/testgr~1.PCX' , 0
OneWon db 'grphx/onewins.pcx', 0
TwoWon db 'grphx/twowins.pcx', 0

Sound variables
TempSound db 'sound/laser.wav', 0
ST_EXP db 'sound/ST_EXP.wav', 0
Kombat db 'sound/mktheme.xmi', 0
Collide db 'sound/crash.wav', 0

Variables for velocities of different ships (word length)
MAX_VELOCITY_ONE = 7
MIN_VELOCITY_ONE = -7
MAX_VELOCITY_TWO = 7
MIN_VELOCITY_TWO = -7

Temporary variables (word-length)
temp
tempx1
tempx2
tempy1
tempy2
tempgravityx
tempgravityy

Ship statistics (word-length)
ship_one_gravity_x
ship_one_gravity_y
ship_two_gravity_x
ship_two_gravity_y
ship_one_thrust = 10
ship_one_velx
ship_one_vely
ship_two_velx
ship_two_vely
twelve = 12
shipvelx1 (24 words long)
shipvely1 (24 words long)
shipvelx2 (24 words long)
shipvely2 (24 words long)
ship_two_thrust = 10
planetx = 220
planety = 80
planetr = 16

Graphics Variables (byte-length)
Color_Red
Color_Green
Color_Black
Color_White
GRAPHIC_ROW_LENGTH
GRAPHIC_ROW_LENGTHX2
SHIP_COLOR

Explosion variable (word-length)
END_OF_HORIZ_BLOW

Test variables
SHIP_ONE_TEST_OFFSET (word)
SHIP_TWO_TEST_OFFSET (word)
SHIP_TEST_OFFSET (word)
SHIP_TEST_COLOR (byte)

Collision variables (byte-length)
SHIP_ONE_HIT
SHIP_TWO_HIT
SHIP_ONE_DEAD
SHIP_TWO_DEAD
ship1planet
ship2planet
shipcollision

TransparentTable (3 words)

ShipTable (5 words) - offsets of the ships

Region Variables
TopMargin (word)
BotMargin (word)
LeftMargin (word)
RightMargin (word)
RegionCode (byte)
EndPointDrawX (word)
EndPointDrawY (word)

RegionTable (13 words) - contains offsets of

State Variables
SHIP_ONE (byte)
SHIP_TWO (byte)
SHIP_ONE_R (byte)
SHIP_TWO_R (byte)
SHIP_ONE_R_WORD (word)
SHIP_TWO_R_WORD (word)
SHIP_ONE_ROWS (byte)
SHIP_TWO_ROWS (byte)
SHIP_ONE_ROWS_WORD (word)
SHIP_TWO_ROWS_WORD (word)

SHIP Position/Orientation variables.
MAX_ANGLE_ONE (byte)
MAX_ANGLE_TWO (byte)
ANGLE_ONE (byte)
ANGLE_TWO (byte)
PLAYER_ONE_X (word)
PLAYER_ONE_Y (word)
PLAYER_TWO_X (word)
PLAYER_TWO_Y (word)
ROTATE_AMOUNT_ONE (word)
ROTATE_AMOUNT_TWO (word)
ROTATE_AMOUNT_ONE_MINUS (word)
ROTATE_AMOUNT_TWO_MINUS (word)

Old Position/Orientation variables
OLD_PLAYER_ONE_X (word)
OLD_PLAYER_ONE_Y (word)
OLD_PLAYER_TWO_X (word)
OLD_PLAYER_TWO_Y (word)
OLD_ANGLE_ONE (byte)
OLD_ANGLE_TWO (byte)

Keyboard Interrupt Variables
OldKeyBoardSegment - segment location of old handler
OldKeyBoardOffset - offset of old key handler

Key Flags (all byte-length)
ESC_KEY
ROTATE_LEFT_ONE
ROTATE_LEFT_TWO
ROTATE_RIGHT_ONE
ROTATE_RIGHT_TWO
THRUST_ONE
THRUST_TWO
FIRE_ONE
FIRE_TWO
SPECIAL_FIRE_ONE
SPECIAL_FIRE_TWO
EXTENDED_KEY_HIT

Line Drawing Values (all word-length)
LASER_DELTA_X
LASER_DELTA_Y
LASER_START_X
LASER_START_Y
LASER_END_X
LASER_END_Y
LASER_COLOR
LASER_PK_SMALL
LASER_PK_BIG
X_STANDARD_ADD
Y_STANDARD_ADD
X_SPEC_SMALL_ADD
Y_SPEC_SMALL_ADD
X_SPEC_BIG_ADD
Y_SPEC_BIG_ADD
PK_IF_SMALL
PK_IF_BIG

Constants
ThreeTwenty = 320
MAX_LASER_R = 55

Timer variables
Delta_Time (word) - increments every 1/18.2 sec.
FadeTimeDelay (word)
Old_Timer (double word) - stores the segment and offset of the old timer interrupt

Fading variables
Palette (768 bytes) - stores the values of the palette registers in the video card
BoxOffset (5 words) - stores the offset locations of the menu boxes

Menu/key variables
ShipType (word) - contains the ship number for players one and two
GameType (byte) - determines where to go from the menu screen
Continue (byte) - flag to exit quickly during the intro and credits

Keyboard interrupt variables (word-length)
MenuKeySeg - old keyboard interrupt's segment
MenuKeyOff - old keyboard interrupt's offset

Networking Variables
PlayerName - unique name for player on NetBIOS
PlayerNum - number for game player assigned by NetBIOS
GroupName - unique name for game group on NetBIOS
GroupNum - number for NetBIOS group assigned by NetBIOS
SendPacket - send NCB
ReceivePacket - receive NCB
SendBuffer - data structure for sending data
ReceiveBuffer - data structure for receiving data
Server - flag indicating whether or not system is the game server
Connected - connection status flag

Procedures

Game Physics Procedures

All code in this section written by Jeff Gomberg.

BuildTables

CalcDistance

CalcGravity

CollisionDetect

CalculateMovement

ProcessMovement

Game Graphics and Keyboard Procedures

Code written by Bob Waldrop.

Run_Game

Inst_Key

Remove_Key

Key_Handler

Update_Statistics

ExchangeBuffer

Test segment test example map

Draw_Ship

DrawLaser

Explode_Ship

UpdateDisplay

SetUpGame

SetupAngleOffsets

AdjustAngles

CheckLasers

SetUpLaserDeltas

ExplodeShip

BlowUpProc

ExchangeBuffer

Introductory and Menu Procedures

Code written by Shane Ryoo.

Timer Interrupts

LoadFADEPCX

ShowScreenBuffer

Blackout

Fade

DrawBoxes

DrawBox

DrawBigBox

MenuKeyInt

InstMenuKey

DeInstallMenuKey

Networking Procedures

Code written by Paul Voelker.

Networking Implementation: For all game data transmission over the network we were going to use NetBIOS. Professor Lockwood's example code, the "CBIS Net BIOS Programmer's Reference" by Tom Thompson, and the lecture notes were about the only sources of information available. Figuring out just how it all worked took quite a bit of time. The networking did not involve too much code, but it involved much more research and scratch work. Commands for NetBIOS are issued by using the NCB (Network Control Block) format. Game data would have been sent in structures containing critical information needed by the server or client. The following is a list of variables related directly to the networking procedures:

The model that we were going to use to transfer data over the network was the server/client model. Originally we thought about using a peer-to-peer type of model. However, after conversing with several previous ECE 291 students, we found we would have big problems with synchronization. One system would get ahead of the other resulting in program errors or unrealistic game play. Basically the one system, the server, handles all calculations and event handling. The client sends data the server needs for calculations (which is primarily just keyboard presses) and gets information back so the display and sound can be maintained. However, due to complications and lack of time, the networking procedures were not integrated into the main program. They were however coded and fully tested on an independant basis. The file called "network.exe" is the executable demo of the networking procedures and "network.asm" is the associated source code.

Game Networking Model

AddNetGroup

AddNetName

RemoveNetName

SetupPackets

InitGame

TermGame

PostReceive

ReceiveNetData

SendNetData

NetBIOSMessage

Timer Interrupt Procedures

Code written by Paul Voelker (also written by Shane Ryoo, but scrapped because it had exactly the same functionality).

GameTimer

InstallTimer

DeinstallTimer

Sound Procedures

Code written by Darrell Micheli.

LoadSound

RegisterXMIDI

PlaySequence

StopMidi

SetSoundSettings

LoadWave

RSTDSP

DMAInit

PlaySound


Operation

The version of Ultra Space Duel that we handed in runs on a single computer and two players at the same keyboard. Given more time, we would have integrated the networking and had two players at two different computers, both having NetBIOS capabilities. One player starts as the server, the other as the client. After both players are done setting up, the game begins. The game continues until a player quits or dies. The server will be doing all of the movement calculations. For more specifics, see previous sections.


Distribution

Ultra Space Duel is freeware. If we ever have time to work some more on it, we might. However, being ECE majors, we probably won't. The game, from what we understand, is University property, as we are doing this as part of a class. Thus, we cannot license the rights of the game to anyone, nor can anyone "borrow" the idea. We are sorry.



This page was created and maintained by Shane Ryoo
This page was last updated Friday, May 1st, 1998 A.D. at 0520 hours CST.
(c) Shane Ryoo, Up-All-Night Productions
Asteroids (c) Atari Corporation