ECE291 Computer Engineering II Lockwood, Spring 1999
Mini-Golf
 
 
 
 
 
 
 
 
Team Members:

Sam Chen  (group leader)
Ryan Pratt
Syed Ahmed
Chris Shannon

Objective:
Our goal is to design and implement a single-player and multi-player mini-putt-putt course that allows for interactive play between players and the computer AI.  The course is 9 holes in length viewed from an isometric overhead view.  Each hole has a specific "theme" that is represented through sound, graphics, and obstacles on the course.  The game is planned to be dynamic in that it can be played with a computer AI or with a group of up to four friends.  The computer AI will have five levels of difficulty, from very easy to very difficult.

PROGRAMMING SPECS:
-graphics are to be written in 320x200 mode 13h, using double buffering
-Develop a "smart" AI which can be set to run at five different difficulty levels
-Sound will be used as appropriate for each of the different holes, menus, etc. using MIDI and WAV files
 
 
Problem Description:

        We will be implementing a 9 hole miniature golf course where each hole has a different theme.  At the start of each hole, whichever player scored lowest on the prior hole (unless the first hole, where player 1 start) will putt first and the following order is determined in the order of finish on the previous hole.  A line is drawn from the ball position in the direction that the player moves the mouse in order to decide where he/she wants to hit the putt.  The force of the putt is determined by moving the line longer or shorter, with a maximum and minimum force set specifically for each hole. The ball is put in motion with a click of the left mouse button.
        The hardest part of this program is the algorithm for moving the ball.  This is because, the ball can travel on different surfaces, and hit different type of walls and objects which may or may not be angled in some direction.  The hitting of a wall or object should obviously deflect the motion of the ball.  We used a separate array to store the poisition and color of each pixel.
        The course will have different slopes (up and down) with differing pitches, and the turf can also have different properties (i.e. wet, dry, sandy, etc.) which effect the friction between the ball and the surface, and thus slow the ball down faster, or slower.
        The sound is intended to be implemeneted with WAV and MIDI files.  For hitting of the ball and walls, objects, etc. we will use a wave file.  For background music in the opening sequence and during the menu sequence, we will use MIDI files.  We plan on having some other "extra" random sounds during course play.  Such as, bird sounds, gallery cheering/clapping, etc.  These would probably be WAV files.
       We intend to develop a smart AI that will play along with the user.  The AI is smart in that it can be played at different difficulty levels where at the most difficult level, the AI should shoot par or close to it.  The way we plan on implementing the AI is to have a series of functions which will determine direction and hitting speed depending on the hole, with a certain amount of allowed error.
 
 
Implementation:
j
To trace the path of the ball and move the mouse line, we used Bresenham's Line Algorithm to draw a best fit line.  We had six different types of walls: horizontal, vertical, and four types of 45 degree angles (right outer, right inner, left outer, left inner).  Each type of wall is marked by a distinct color.  After a ball hits each of the walls, the x-direction or y-direction is either maintained or changes signs depending on the wall characteristic.  For instance, when a ball hits a horizontal wall, the y-dir changes signs, but the x-dir maintains the same sign.  That way, the ball bounces in the proper direction.  For vertical walls, x-direction is flipped while y-direction is maintained.  For the 45 degree angle walls, implementation was a bit more difficult.  Basically, the slope is flipped so the x-direction and y-direction magnitudes are switched and the signs changed according to the angle of the wall.

We made several assumptions in the calculation of the velocity of the ball to make the math easier.  We used the weight of the ball as 1 kg and didn't take account of energy lost due to collisions with walls.  Instead of using floating point math, which was tedious and unnecessary, we used integer math.  We set an initial force based on the length of the mouse line and decremented that force every five pixels.  This gave the impression that the ball was slowing due to friction.  After the speed of the ball reaches a certain minimum speed, we stop the ball.  We also adjusted the speed accordingly for slopes.

For the Artificial Intelligence, we used a random function and certain set points on each hole.  The AI would hit in the direction of those set points with variation due to the random function.  At an easier level, the variations are greater and at the more difficult levels, the variations are less.  Therefore, the AI changes according to the difficulty levels.
 

Strucs:

WaveHdr  STRUC                ;struct for .wav files
   format   db 'RIFF'
   filelen  dd ?
   wavefmt  db 'WAVEfmt_'
   fmt_len dd  ?
   fmt_tag dw  ?
   channel  dw ?
   samples  dd ?
   bytesps dd  ?
   bkalign  dw ?
   bitsps   dw ?
   data  db 'data'
   datalen  dd ?
WaveHdr Ends

Ball STRUC                        ;struct for the ball
  Cur_X_Pos dw ?
  Cur_Y_Pos dw ?
  Old_X_Pos dw ?
  Old_Y_Pos dw ?
  HoleVar db 0
  order_of_finish db 0
  CurrentHoleScore db 0
  Status db 0
  hole1score db 0
  hole2score db 0
  hole3score db 0
  hole4score db 0
  hole5score db 0
  hole6score db 0
  hole7score db 0
  hole8score db 0
  hole9score db 0
  scoretotal db 0
Ball ENDS

 

Variables:

GoToNextHole    db      0        ;set if all players are done

SinglePlayer    db      1           ;set if single player mode on

FinishOrder     db      1           ;variable used in determining order of finish
HoleDoneVar     db      0         ;indicates player has finished the current hole

animate_array   db      17          ;this array is used for animation
                                              ;basically, every image is put in the array, with the first byte as the
                                              ;number of animations in the given hole.  An offset in this array is
                                              ;passed into the HandlerHelper so that the starting image of each
                                              ;animation can be determined.
 
                db      'hole3.pcx',0   ;offset 1 (first hole)
                db      'hole3.pcx',0
                db      'hole8.pcx',0   ;offset 21 (second hole)
                db      'hole8.pcx',0
                db      'h10-5.pcx',0   ;offset 41 (third hole)
                db      'h10-5.pcx',0
                db      'h10-5.pcx',0
                db      'h10-4.pcx',0
                db      'h10-3.pcx',0
                db      'h10-2.pcx',0
                db      'h10-1.pcx',0
                db      'h10-1.pcx',0
                db      'h10-2.pcx',0
                db      'h10-3.pcx',0
                db      'h10-4.pcx',0
                db      'h10-5.pcx',0
                db      'hole6.pcx',0   ;offset 161 (fourth hole)
                db      'ho6-0.pcx',0
                db      'ho6-1.pcx',0
                db      'ho6-2.pcx',0
                db      'ho6-3.pcx',0
                db      'ho6-4.pcx',0
                db      'ho6-5.pcx',0
                db      'ho6-6.pcx',0
                db      'new75.pcx',0   ;offset 241 (fifth hole)
                db      'new75.pcx',0
                db      'new75.pcx',0
                db      'new74.pcx',0
                db      'new73.pcx',0
                db      'new72.pcx',0
                db      'new71.pcx',0
                db      'new71.pcx',0
                db      'new71.pcx',0
                db      'new72.pcx',0
                db      'new73.pcx',0
                db      'new74.pcx',0
                db      'new75.pcx',0
                db      'new75.pcx',0
                db      'new75.pcx',0
                db      'hol4a.pcx',0   ;offset 391 (sixth hole)
                db      'hol4b.pcx',0
                db      'hol4c.pcx',0
                db      'hole9.pcx',0   ;offset 421 (seventh hole)
                db      'ho9-2.pcx',0
                db      'ho9-3.pcx',0
                db      'ho9-4.pcx',0
                db      'ho9-5.pcx',0
                db      'ho9-6.pcx',0
                db      'ho9-7.pcx',0
                db      'ho9-8.pcx',0
                db      'ho9-3.pcx',0
                db      'ho9-2.pcx',0
                db      'ho9-7.pcx',0
                db      'ho9-5.pcx',0
                db      'ho9-4.pcx',0
                db      'ho9-8.pcx',0
                db      'hole9.pcx',0
                db      'ho9-2.pcx',0
                db      'ho9-7.pcx',0
                db      'hol21.pcx',0   ;offset 591 (eigth hole)
                db      'ho122.pcx',0
                db      'ho123.pcx',0
                db      'ho121.pcx',0  
                db      'hol5a.pcx',0   ;offset 631 (ninth hole)
                db      'hol5b.pcx',0
                db      'hol5c.pcx',0
                db      'hol5d.pcx',0
                db      'hol5e.pcx',0
                db      'hol5f.pcx',0
                db      'hol5g.pcx',0
                db      'hol5h.pcx',0
                db      'hol5i.pcx',0
                db      'hol5j.pcx',0
                db      'hol5k.pcx',0
                db      'hol5l.pcx',0
 
 
 

PCX0    DB      'TITLE.PCX', 0                ;pcx files for the title screens, winner sequences, scorecard
PCXP0   DB      'TITLE2.PCX', 0             ;and credits screen
PCXM0   DB      'TITLE3.PCX', 0
PCXD0   DB      'TITLE4.PCX', 0
PCXH0   DB      'INFO.PCX',0
PCXLAST DB      'SCOREC.PCX', 0
TROPHY1  DB      'TROPHY1.PCX', 0
TROPHY2 DB      'TROPHY2.PCX',0
TROPHY3 DB      'TROPHY3.PCX',0
TROPHY4 DB      'TROPHY4.PCX',0
TROPHY5 DB      'TROPHY5.PCX',0
CREDITS DB      'CREDITS.PCX',0

NoBridge        dw      1                        ;variables for drawbridge and barriers
NoBarrier       dw      1

RoveHolePosX    dw      71                ;variables used in determining the position of moving hole
RoveHolePosY    dw      97
 
 

intro     db      15              ;sequence of images for intro
           db      'intr1.pcx',0
           db      'intr2.pcx',0
           db      'intr3.pcx',0
           db      'intr4.pcx',0
           db      'intr5.pcx',0
           db      'intr6.pcx',0
           db      'intr7.pcx',0
           db      'intr8.pcx',0
           db      'intr9.pcx',0
           db      'intrA.pcx',0
           db      'intrB.pcx',0
           db      'intrC.pcx',0
           db      'intrC.pcx',0
           db      'intrC.pcx',0
           db      'intrC.pcx',0
           db      'intrC.pcx',0
 

PCX1    DB       'hole3.pcx', 0        ;each hole has an initial screen
PCX2    DB       'hole8.pcx', 0
PCX3    db        'h10-5.pcx', 0
PCX4    DB       'hole6.pcx', 0
PCX5    db        'new75.pcx', 0
PCX6    db        'hol4a.pcx', 0
PCX7    db        'hole9.pcx', 0
PCX8    db        'ho121.pcx', 0
PCX9    db        'hol5a.pcx', 0
 

AnimTime        dw      ?            ;variable for use with timer function in anim_seq

sbuf_page   db ?                      ;variables for sound
sbuf_offset dw ?
sbuf_length dw 8192     ; 8 k - all that is guaranteed to not
               ; cross a DMA Page.

finalbuffersize dw ?                ;more variables for sound
mycounter   dw -1
needrefill  dw 0
loadbuf  WaveHdr < >
WavMsg      db 'Played wav file in ','$'
CyclesMsg   db ' cycles.',13,10,'$'

deb dw ?                ;debug use
freqCheck dw 0       ;debug use

OldTimerV  dd  ?    ;for timer

OldKbdV dd ?

DistVar dw 0

Force_Var dw 50
PUBLIC Force_Var

Frequency  dw 200    ;frequency of timer
 

Coef_Fric_Turf REAL4  0.1            ;some variables for friction
PUBLIC Coef_Fric_Turf

Coef_Fric_Water REAL4  0.8
PUBLIC Coef_Fric_Water

Coef_Fric_Sand   REAL4  0.6
PUBLIC Coef_Fric_Sand

InHoleVar dw 0                        ;are we in the hole?

palette         db      256     dup(?)  ;save the palette
PUBLIC palette

pal_seg dw      ?        ;segment and offset of the palette
PUBLIC  pal_seg
pal_off dw      ?
PUBLIC  pal_off

First_Player dw 0      ;used to access BallArray
PUBLIC First_Player

Second_Player dw 1
PUBLIC Second_Player

Third_Player dw 2
PUBLIC Third_Player

Fourth_Player dw 3
PUBLIC Fourth_Player

NumPlayers dw 0        ;number of players in game
PUBLIC NumPlayers

ExitStatus db 0           ;should we exit game (Esc key pressed)
PUBLIC ExitStatus

Current_Player dw 0       ;who is up now
PUBLIC Current_Player
 
difficulty_flag db 0            ;AI difficulty
PUBLIC difficulty_flag
WantCompFlag  db 0
PUBLIC WantCompFlag

NetworkFlag  db 0
PUBLIC   NetworkFlag

NumofPlayerFlag db 0
PUBLIC  NumofPlayerFlag

Current_Hole dw 9            ;determines current hole
PUBLIC Current_Hole

Computer_Var db 0   ;set if computer is playing
PUBLIC Computer_Var

Tournament_Play  db 0  ;set if tournament is to be played
PUBLIC Tournament_Play

Delta_X dw ?            ;for use with CalcMoveBall function
PUBLIC Delta_X

Delta_Y dw ?
PUBLIC Delta_Y

Error dw ?            ;error flag
PUBLIC Error

ScreenPosition dw ?        ;current screen position
PUBLIC ScreenPosition

OldScreenPosition dw ?    ;previous screen position
PUBLIC OldScreenPosition

MouseDoneVar db 0
PUBLIC MouseDoneVar

BiosLetterFore  dw 232    ;variables for videoBIOS to write player name and scores during gameplay
PUBLIC BiosLetterFore

BiosLetterBack    dw 0
PUBLIC BiosLetterBack
 

MouseClick db 0        ;set to move ball
PUBLIC MouseClick

BallStopped db 0        ;set if ball has stopped
PUBLIC BallStopped

Col dw ?
PUBLIC Col

Row dw ?
PUBLIC Row
 
startflag       db 0
PUBLIC startflag

helpflag     db  0
PUBLIC helpflag

pcx_ctr dw      ?

BallLineCount dw 0

DrawXVar db 0

DrawYVar db 0

RealFive REAL4 5.0

TimerStillInst dw 0

Mess dw 0

letter  dw  0

Player1Str       db  'PLAYER1' ,'$'        ;some strings for videoBIOS

Player2Str       db  'PLAYER2','$'

Player3Str   db  'PLAYER3','$'

Player4Str   db  'PLAYER4','$'

ComputerStr   db  'DEEPGRN','$'

ScoreStr        db      'STROKE: ','$'

errorvar dw ?
finalx dw ?
finaly dw ?
twody dw ?
twodx dw ?
linecount db ?
xdir dw ?
ydir dw ?
NoIncX db 0
NoIncY db 0
IncBoth db 0
 NextScreen db 0
wavtable   dw offset wavfile0                ;.wav files
                   dw offset wavfile1
                   dw offset wavfile2
                   dw offset wavfile3
                   dw offset wavfile4
                   dw offset wavfile5
                   dw offset wavfile6
                   dw offset wavfile7
                   dw offset wavfile8
                   dw offset wavfile9
                   dw offset wavfile10
                   dw offset wavfile11
 
 

wavfile0   db 'test.wav',0       ; null terminate file names
wavfile1   db 'Almost.wav',0
wavfile2   db 'Cheer.wav',0
wavfile3   db 'Claps.wav',0
wavfile4   db 'HitBall.wav',0
wavfile5   db 'InHole.wav',0
wavfile6   db 'prpmartn.wav',0
wavfile7   db 'anykey.wav',0
wavfile8   db 'compstrt.wav',0
wavfile9   db 'typekey.wav',0
wavfile10  db 'glasbk.wav',0
wavfile11  db 'glf_swng.wav',0
 

miditable     dw offset midi0
                  dw offset midi1
                  dw offset midi2
                  dw offset midi3
                  dw offset midi4
                  dw offset midi5
                  dw offset midi6
                  dw offset midi7
                  dw offset midi8
                  dw offset midi9
 

midi0  db 'haloween.xmi',0
midi1  db 'hotelcal.xmi',0
midi2  db 'freebird.xmi',0
midi3  db 'master.xmi',0
midi4  db 'stairway.xmi',0
midi5  db 'hey_you.xmi',0
midi6  db 'higher.xmi',0
midi7  db 'turning.xmi',0
midi8  db 'sremains.xmi',0
midi9  db 'jump1984.xmi',0
 

Jtable dw offset HandlerDone
           dw offset EscapeKey
           dw offset NumberOne
           dw offset NumberTwo
           dw offset NumberThree
           dw offset NumberFour
           dw offset NumberFive
           dw offset NumberSix
           dw offset NumberSeven
           dw offset NumberEight
           dw offset NumberNine
           dw offset NumberZero
 
 

sequence dw 0
fileno          dw ?
wavremaining   dd 0
wavlength       dd 0
wavdone         db 0

wavtoplay dw 1
miditoplay dw 1
 

Computer_Play db 0            ;whether computer is playing or not
 

Com_Player_Num  db 4          ;computer player number is always 4, so always
                              ;uses ball struc 4 in ballarray

Tournement_Var db 0           ;whether want to play with tournament on or not

Decel_Var dw -1  ;REAL4 0.1

Old_Turf dw ?

TurfPos dw ?

SlowCount dw 30

SlowVar dw 0

IsUpSlope dw 0

IsDownSlope dw 0

RandNum dw 1

RandDInt  dw  1

RandSInt  dw  1

RandSpeed dw 1

DifVar2   dw ?      ;1-5

Difficulty_Level  dw  ?   ;5-1

IsTurf dw 1

RandDirNeg dw 0

RandSpeedNeg dw 0

NoLava db 1     ;need to reinitialize to 0
 

AnimVar dw 0

Anim dw 0

AnimateNow db 0

OffsetVar  dw ?

OldVect  dw 0

OutOfBounds  dw  0

TimerCount  dw  0

RealCount  dw  ?

TrackTime  dw  0

;;;;;;;;;;again, keep these variables in case they become useful;;;;;;;;
;MyNum db 63
;PUBLIC MyNum

;ItNum  db 63  ; Who is it
;PUBLIC ItNum

;TagNum db 63  ; Who tagged me
;PUBLIC TagNum

;player PlayerType 64 dup(< >) ; Player Array
;PUBLIC player

Player TourPlayer 10 dup (< >)  ;holds the tournament players and their calculated scores
PUBLIC Player

MaxForceArray dw 175, 150, 150, 100, 250, 200, 250, 220, 250

BallArray Ball 5 dup(< >)   ;holds ball structs
PUBLIC BallArray

CountMessage db 'BallCoutn greater than should be$'

OtherError db 'BADNESS$'
PUBLIC OtherError

VertMessage db 'I have no idea hwy this is happening$'
PUBLIC VertMessage

holemessage db 'in the hole$'
PUBLIC holemessage

rightangleMessage db 'Hit Right Angled Message$'

HorizMessage db 'You are in HorizLineHandle$'

deltaoppMessage db 'In DeltaOpposites Handle$'

nextposMessage db 'In NextPositiveCheck Handle$'

YMessage db 'YOu are in CalcDrawY and its not working$'

leftangleMessage db 'In the left handler past checks$'

player1scoremess  db 'Player 1 score is: $'

;MyPosition dw 320*100+160-16  ; Start at middle of screen
;PUBLIC MyPosition

;ExitFLag db 0 ; 0=Play, 1=exit
;PUBLIC ExitFlag

;MyImage  db 'myimage.bmp',0  ; Null-terminated filename
;PUBLIC MyImage

ErrorMessage  db  'politely quitting because this should not happen$'
PUBLIC ErrorMessage
 

pbuf           db 7 dup(?)
crlf           db CR,LF,'$'
Num320         dw 320
;SizePlayerType db Sizeof Playertype
 
 

Functions we wrote:
 

Main:
Inputs: None
Outputs: None
This function initializes the keyboard and mouse handlers, changes to mode 13h graphics mode.  This function then calls all the handlers for each hole, followed by the call to the scorecard after each hole handler is called.  Then it exits the program.
 

MouseInstallGame
Input:  none
Outputs:  none
sets pointer to MouseGameHandler for left clicks and moves during game play
Written by:  Syed Ahmed

MouseUninstallGame:
Inputs:  none
Outputs: none
resets mouse driver and hides mouse
Written by: Syed Ahmed

MouseGameHandler:
Inputs:  X(0...639) and Y(0...199) position of cursor
            which buttons where pressed

Outputs:  sets Cur_X_Pos and Cur_Y_Pos of Current_Player
              sets Error variable
              sets initial Delta_X and Delta_Y varaibles
              when left button clicked twice, sets MouseDoneVar to 1
Written by:  Syed Ahmed
 

ChangeMouse:
Inputs: None
Outputs: changes the mouse cursor to a golf club
Written by:  Chris Shannon
 

KbdInstall:
Inputs: none
Outputs: oldKbdV, pointer to old handler
hands keyboard control over to KbdHandler during program execution
Written by: Ryan Pratt
 

KbdUninstall:
Inputs:  OldKbdV
Outputs: none
resets the pointer for keyboard interrupt to OldKbdV
Written by:  Ryan Pratt
 

KbdHandler:
Inputs:  none
Outputs:   if ESC pressed, sets ExitStatus to 1
                 if a number is pressed, the corresponding midi song is played
                 if 'S' is pressed, midi music stops
Written by: Ryan Pratt and Chris Shannon
 

TimerInstall
Inputs:  segment:offset of old timer vector using INT 21H
Outputs:  OldTimerV set to correctg seg:offset
Purpose:  Set timer interrupt to point to my handler, TimerHandler
Written by: Ryan Pratt
 

TimerUninstall:
Inputs:  OldTimerV
Outputs:  none
Purpose:  Reset timer interrupt vector to System Handler
Written by:  Ryan Pratt

TimerHandler:
Inputs:  DistVar, TimerCount, RealCount, Force_Var,
         Decel_Var
Outputs:  Force_Var, RealCount, TrackTime, AnimVar
Purpose:  everytime handler is called, it calls CalcMoveBall and
          DecelHandle, increments TimerCount, sets RealCount
          and 18 times a second calls OldV
Written by:  Ryan Pratt

 
Anim_Seq:
Inputs: None
Outputs: Outputs directly to screen.
Animates the intro screen.
Written by:  Sam Chen

DrawLine:
Inputs: DI = X-COORD of mouse position
           SI = Y-COORD of mouse position
Outputs:  draws directly to screen a line from Current_player's ball position towards the position fo the mouse,
              at specified length of 25 pixels
Written by:  Chris Shannon
 

ShowPCX:
Inputs:  None
Outputs:  Draws image to screen
Copies the image from the buffer to the screen.
Written by: Sam Chen (modified from version in lab manual)
 

Buf_PCX:
Inputs: DX = offset address of pcx file
Ouputs: Outputs the uncompressed pcx image to double_buf array
Implements the double buffering of the PCX file.
Written by:  Sam Chen (variation of ShowPCX in lab manual)
 

StorePCX:
Inputs:  None
Outputs:  writes uncompressed pcx image into holeseg array
Writes to an array so that pixel comparisons may be made to determine where walls,
turf, out of bounds, etc are.
Written by:  Sam Chen

CalcMoveBall
 Inputs:  Current_Player, Cur_X_Pos, Cur_Y_Pos, holearray, xdir, ydir,
          twodx, twody, IncBoth, NoIncX, NoIncY, IsUpSlope, IsDownSlope,
          IsTurf

Outputs:  ScreenPosition, IsUpSlope, IsDownSlope, IsTurf, xdir, ydir
          twodx, twody, NoIncX, NoIncY, ExitStatus, InHoleVar
Purpose:
Moves ball to next pixel as appropriate - if it hits a wall or enters
a slope, it changes xdir, ydir, NoIncX, NoIncY, twodx, twody, IsUpSlope,
IsDownSlope, IsTurf appropriately.  It also checks for "unknown" cases
and will set the ExitStatus flag if this should ever occur (which it
SHOULDN'T!!) and sends corresponding error messages.  If the ball goes
into the hole, it either set the InHoleVar flag to 1, or if the ball is
going to fast, "bounces" it out of the hole the appropriate direction
depending on from what direction it entered and reduces the velocity of
the ball.

Written by:  Ryan Pratt
 

DecelHandle:
Inputs:  Current_Player, Abs_Vel, Cur_X_Pos, Cur_Y_Pos, Coef_Fric_*
Outputs:  Updates Current_Player's Abs_Vel

Purpose:  The absolute velocity of the player's ball that is moving
is "slowed" as it moves, simulating the effects of friciton, and the main
checks this value and appropraitely jumps to the correct ball move section
that will effecctively slow the balls movement on the screen the further
goes by having using the timer interupt at longer lengths of time

Written by: Ryan Pratt
 

RandomDir:
Inputs:  Difficulty_Level

Outputs:  Random number between (0-Dificulty_Level)*5
            Number is positive 50% of the time, else negative
Purpose:  To be added to "set" direction in AI for specific hole and
          position on hole in order to add element of error into
          AI play
Written by:  Ryan Pratt
 

MouseTitleHandler:
Inputs: No Inputs, uses  int  33h to use mouse functions
Outputs: outputs menu(s) to screeen
This function loads the appropriate pcx files depending on which buttons are hit
This function initially load the title screen and has four buttons. Single Player, Multi Player, Help and Exit.  Depending on which button is pressed, a different pcx file is loaded.

If One Player is selected, a screen is loaded if you want to play with the computer. If
you choose YES, then a screen is loaded and asks you to input the difficutly of the computer.

If MultiPlayer is selected, then it a screen is loaded that asks how many players you want.  You can have up to 2 to 4

Startflag is set to one after you select difficutly of computer, or the number of players needed, play without computer
 
Written by:  Syed Ahmed
 

AIHandler:
Inputs:  Current_Hole, Difficulty_Level, DirectionArray, SpeedArray,
         Cur_X_Pos, Cur_Y_Pos

Outputs: Initial twodx, twody, xdir, ydir, IncBoth, NoIncX, NoIncY,
         Force_Var

Purpose:  To determine, depending on current position, distance from
          the "direction post" in the DirectionArray, the vector of
          movement and the initial force
Assumptions: 5 words per hole per array
Written by: Ryan Pratt

OpenWave:
 Inputs: none
Outputs: EAX = data length = bytes of sound data
Written by:  Chris Shannon based on SBTest.asm

PlayWave:
Inputs: none
Outputs: Plays WAV file as specified
Written by:  Chris Shannon based on SBTest.asm

LoadHalfBuffer:
Inputs: AX = secondhalf
Outputs: CF=1 if just loaded last buffer, AX = number of bytes read
Written by:  Chris Shannon based on SBTest.asm

SoundHandler:
Inputs:  none
Outputs:  none
Called whenever the DSP generates an interrupt.  Increases the buffer which generates increasingly loud tone.
Written by:  Chris Shannon based on SBTest.asm

MidiPlay:
Inputs: miditoplay
Outputs: Opens specified MIDI file
Written by: Chris Shannon

StopMIDI:
Inputs: none
Outputs: Stops currently playing MIDI file
Written by: Chris Shannon
 

WinSequence:
Inputs:  BallArray[bx].scoretotal - total score
             NumPlayers - determines the number of players playing
Outputs:  Draws winner PCX file to screen .  After playing, returns to main menu.
This function compares the total scores of all the players and displaying the winning
screen for the player who has the lowest score
Written by: Ryan Pratt
 

HandlerHelper:
Inputs: DX = offset of PCX image, SI = offset of first animation image.
Outputs:
A comprehensive helper function for the hole handlers.  It buffers the image, stores it in an array for pixel checking, and writes the image to the screen.  Using the timer, it polls the mouse, calls the AI, and animates through each hole.  This function sets the frequency of the timer to handle the mouse polling and animation.  In addition, HandlerHelper calculates who goes next, maintains the player scores, determines if the computer is playing, and checks for whether the ball is in the hole.  It makes a great function.
Written by:  Ryan Pratt
 

SetOrder:
Inputs:  BallArray for each player
Outputs: Resets HoleVar variable, CurrentHoleScore variables for each player.
A helper function to determine the order of play for the next hole.  The winner goes first,
the next best score goes next, etc.  Also resets HoleVar and CurrentHoleScore variable for next hole.
Written by: Sam Chen

 
HoleOneHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen

HoleTwoHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen

HoleThreeHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen

HoleFourHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen

HoleFiveHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen

HoleSixHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen
 

HoleSevenHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen
 

HoleEightHandler:
Inputs:  pcx files, DX = offset of first animation in sequence
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen
 
HoleNineHandler:
Outputs:  updates players scores, totals, increments hole number, sets hole starting position.
This function will load the hole one pcx image and call HelperHandler to handle the animation.
It will internally call all necessary functions for hole play.
Written by: Sam Chen
 

GetBiosChars:
Inputs: letter - ascii value of character to display
            BiosLetterFore - foreground color of character
            BiosLetterBack - background color of character
            di - location of screen where character should be printed
Outputs: Outputs to screen
This function uses the character map that is in bios and reads  in the
characters bit by bit.  It also prints out the characters bit by bit
Written by:  Syed Ahmed
 

PrintNameScore:
Inputs: Current_Player - determines which player is currently playing
            Current_Player[bx].CurrentHoleScore
Outputs: prints to the screen
This function displays the name and the players current score at the beginning
of their turn
Written by:  Syed Ahmed
 

FillOnePlayer:
Inputs: Current_Player[bx].Hole#Score
Outputs: writes to screen
This function writes fills the name and score for the first player
on the scorecard.  This function uses Player1Str to output the the name and
uses ScoreStr to output the score.
Written by:  Syed Ahmed
 

FillTwoPlayer:
Inputs: Current_Player[bx].Hole#Score
Outputs: writes to screen
This function writes fills the name and score for the second  player
on the scorecard.   This function uses Player2Str to output the the name and
uses ScoreStr to output the score.
Written by:  Syed Ahmed
 

FillThreePlayer:
Inputs: Current_Player[bx].Hole#Score
Outputs: writes to screen
This function writes fills the name and score for the thrid player
on the scorecard.   This function uses Player3Str to output the the name and
uses ScoreStr to output the score.
Written by:  Syed Ahmed
 

FillFourPlayer:
Inputs: Current_Player[bx].Hole#Score
Outputs: writes to screen
This function writes fills the name and score for the fourth player
on the scorecard.   This function uses Player4Str to output the the name and
uses ScoreStr to output the score.
Written by:  Syed Ahmed
 

FillComputer:
Inputs: Current_Player[bx].Hole#Score
Outputs: writes to screen
This function writes fills the name and score for the computer
on the scorecard.   This function uses ComputerStr to output the the name and
uses ScoreStr to output the score.
Written by:  Syed Ahmed

FillScoreCard:
Inputs: NumPlayers - determines how many players are playing
Outputs: calls other Fill functions to fill in scoreboard
Written by:  Syed Ahmed
 

Functions we used:

DosXit:
Inputs: None
Outputs: exits to DOS
This function is used to exit to DOS

Kbdin
Inputs: a keyboard press
Outputs: exits with AL = ASCII code of character typed in.
We used this to pause the game at certain points, such as after the scorecard and intro sequence.

Macros we used:

GMODE
used to switch to mode 13h graphics mode.

TMODE
used to switch to text mode graphics.

GETTIME
used to get the time for the timing function.