291 Final Project:

Mission Impossible


Team Members:

Ka Chun Ma  -- Graphics

Ryan Tam  -- AI

Shoko Oono   -- Game Main

Richard Rittis -- Sound

Introduction:

          The goal of the game is for Tomy to successfully download 5 separate parts of the mp from his classmate's computer without being caught by a TA.  Tomy must travel, starting from his own computer, across the screen to his classmate's computer and then make the trip back, once he has one of the parts of the mp on his disk.  There will be two TA's, one at the top and one at the bottom of the screen.  They will roam left and right.  They will be designed to pause for a moment before turning to look at Tomy.  At this time, when a TA looks at Tomy, Tomy must turn and hide the disk, otherwise, he will have been caught.  In order to hide the disk, Tomy must turn away from the TA.  The two TA's will never look at Tomy at the same time, because there is no way Tomy can hide the disk from both TA's at once.  Once at a computer, it takes time to download or upload the piece of the mp onto or off of his disk.  A countdown will start.  If Tomy chooses to hide his disk during this time, the countdown will stop, and it will resume once Tomy returns to the proper position for downloading or uploading.  Each portion must be downloaded or uploaded completely for it to count towards the total of 5 parts.

            Tomy's movement will be limited to the center portion of the screen, a rectangle starting at (50, 60) with height 100 and width 220, and the TA's can only move horizontally.  To move Tomy, the player can click with the left mouse button in a valid area of the screen and Tomy will move towards that position.  To make Tomy turn, click with the right mouse button, above or below him, and he will turn in that direction.  Making Tomy turn will also stop his movement to whatever destination was previously designated by the left mouse button.  In order to download or upload from a computer, the player must click on a computer, and if Tomy is close enough to the computer, he will be moved into the proper place for downloading or uploading.

Goals:

 -Game is in 320x200 VGA.
 -Write an AI which does not cause contradictions within the game and yet be not too
    easy to predict its next move.
 -Provide support for the use of a mouse.
 -Provide background music and sound effects coordinated with events within the game.
 

Problem Description:
Sound
         In this program we will be using both MIDI sound files and  unformatted sound files to enhance the game playing environment.  The game uses the MIDPAK API by John W. Ratcliff to play a MIDI file in the background to enhance game play and to set the proper mood.  The implementation of the Midi sequences is straightforward and easy to implement although the documentation is not too clear at times.

Implementing voices and sound effects was the more troublesome of the sound implementation tasks.  The documentation for playing digitized sounds is not as clear and the methods are numerous.  Special attention will have to be paid to ensuring the correct priority for sound files, so sound is in synch with game play.

TAControl
        For the movement of the TAs, random number is used to decide what the next action of the TAs would be.  Random number generation has been given in the earlier semester's mp,
and here is just the method that was presented in the mp.
        R(1)=RandSeed
        R(i+1) = RandSeed = ( K1 * R(i) + K2 ) % MaxValue
        where:
        R(i) is the random value generated in the i-th call to the subroutine.
        RandSeed is a variable that holds the initial random value and is updated with the result after each call to Random.
        K1 and K2 are two large, prime-valued constants, defined as 55821 (0DA0Dh) and 1 respectively.
        MaxValue = 2^16-1 (0FFFFh)
        For our project, the TAs turn their heads whenever the random number falls into the range that we've been set up for the motion.  The range of the random number for turning the
head of the top TA is between 5500h -- 7500h. While the bottom TA is in between 8800h and 9000h. Also, the TAs would stop for a while before they turn, that way it would give Tomy time to respone once he notices that the TAs are goning to turn. Of course the TAs won't turn their heads at the same time because there would be no way for Tomy to avoid being caught.

Mouse Control
        In order to make the mouse driver to something more than its pre-existing functions offer, one way to do it would be to write your own driver.  However, because the mouse is very complicated, there would be much that would have had to be rewritten, just to add that one function to the mouse driver.  Instead, function 000Ch can be used.  This function tacks on a "handler" to the original mouse driver.  Therefore, the mouse driver will work as always, including all of its functions, but with that added "handler" function.  In this way, the mouse status variables are changed whenever the mouse has been moved or a button on it had been pressed.  The mouse "handler" for this specific game will be written to change the outside status variables whenever a button on the mouse has been pressed.
 

Graphics Implementation
       We will be using four segments to hold all the images and background.

              --ForeSeg holds foreground images such as TA's image, Tomy's image.
              --BackSeg conatins the background which won't be change very often.
              --ImageSeg conatins the data from BackSeg and ForeSeg before writing to screen.
              --ScrSeg - segment which LoadPCX and LoadSound

         Most of the images will be 60 X 60 pixel besides the background and the downloading bar.  To allocate the source of  the picture in the PCX file, the look up table would be the best choice.

         One way  to give the illusion of the depth of the game, is to use ZBuffer as we did in MP4.  But I chose not to keep track of  all the z-value of  all pixel on the screen, instead we draw the images in a desired sequence. For example, having TA1's leg covered by Tomy's head as he walks close to him, we need to display the TA's image on the ImageSeg first, so that TA's leg will be drawn over by Tomy's imgae.
 

 Variables:

    Segments:
            -ForeSeg - segment to which people are drawn to
            -BackSeg - segment holds background image
            -ImageSeg - segment to which conatins the data from BackSeg and ForeSeg before writing to screen.
            -SBSeg - segment for outputting to the screen
            -ScrSeg - segment which LoadPCX and LoadSound
 
            -GameMidiSeg - holds game play theme song
            -SoundSeg1 - for soundeffects during game play

    Global Variables:
          sound:
            -GameSong - contains game song (the ever-moving Mission Impossible theme song)
            -SoundFile - contains sound to be played
            -GameMidiSeg - holds GameSong
            -GameSong - offset of MIDI file within GameMidiSeg

            -DMAChannel - 8-bit DMA channel for sound card.   Detected and set by  SetSoundCardData.
            -IRQ - IRQ for sound card.  Detected and set by  SetSoundCardData.
            -SoundBaseAddr - Sound card base address.   Detected and set by  SetSoundCardData.
            -ABuffer - used for converting ASCII base address to hex.
            -Blaster -  stores string to look for in 'set.txt' file for setting sound card parameters
            -BlasterFile - points to 'set.txt' file
            -TimeConstant db  165 = 11KHz time constant for DSP programming 

            -OldSoundV - contains the old interrupt vector for sound IRQ
            -IRQint - Interrupt adjusted for IRQ acknowledgement
            -sound - (1 = sound card installed, 0 = no sound card)

            -DMAPage - the calculated page used for DMAC programming
            -DMAOffset - calculated offset used for DMAC programming
            -DMAPageReg - page register for respective DMA channel for DMAC programming
            -DMAOffsetReg - offset register for respective DMA channel for DMAC programming
            -DMALengthReg - length register for respective DMA channel for DMAC programming

            These variables point to the respective sound file to be played during the game.
            -Perfect - 'itsprfct.pcm'
            -DeepDoo -  'yrndpdo.pcm'
            -Xferred - 'b5xfer.pcm'
            -Beating -  'beating.pcm'
 
            -ThemeFile - 'mission.xmi',  themesong filename
            -ThemeSize - file size set during file loading
            -FileSize - sound file size used to program sound playback, set during file loading
        control:
            -LeftButton - boolean value (cleared when accessed)
            -RightButton - boolean value (cleared when accessed)
            -MouseX - x location of mouse when a button was last pressed
            -MouseY - y location of mouse when a button was last pressed

            -tomx - previous x location of Tomy
            -tomy - previous y location of Tomy
            -newtomx - next x location of Tomy
            -newtomy - next y location of Tomy
            -tompic - holds picture number for Tomy
            -tompos - holds offset for Tomy's next position
            -tomDir - direction of Tomy(used by the jump function)
            -LineArray - array of 200 words that hold x values for corresponding y's
            -NextX - next immediate destination point for Tomy (x)
            -NextY - next immediate destination point for Tomy (y)

            -picNum - index to the offset of a pcx file

            -TA1pic - holds picture number for TA1
            -TA1pos - holds offset for TA1
            -TA1old - TA1's old picture number (tells what TA1 was doing before, but not the turning pic)
            -TA1stop - countdowns pause time for TA1
            -ta1pause - indicator for the pausing of TA1
            -ta1look - countdowns for how long TA1 looks at Tomy

            -TA2pic - holds picture number for TA2
            -TA2pos - holds offset for TA2
            -TA2old - TA2's old picture number (tells what TA2 was doing before, but not the turning pic)
            -TA2stop - countdowns pause time for TA2
            -ta2pause - indicator for the pausing of TA2
            -ta2look - countdowns for how long TA2 looks at Tomy

            -stole - boolean value (set when Tomy steals first piece - from here on, Tomy can be caught)
            -dead - incremented as Tomy get caught
            -Randseed - for random number generator
            -randstate - switch between adding tomX and tomY as the input for the random function

            -xst - the x-coordinate of the point with the lower y value
            -xnd - the x-coordinate of the point with the greater y value
            -yst - the y-coordinate of the point with lower y value
            -ynd - the y-coordinate of the point with higher y value

            -ydiff - the difference between two y values of two pixels
            -drawxpos - the new x-position of the scaled pixel
            -drawypos - the new y-position of the scaled pixel

            -vertcount - counting from 0 to 200
            -horizoncount - counting from 0 to 320
            -scaleX - x-coordinate of each pixel of the pcx file starting from 0 to 319
            -scaleY - y-coordinate of each pixel of the pcx file starting from 0 to 199

            -shrink - for how much the pcx file is goning to be scaled to
            -shift - offset of the scaled pcx
            -flying - offset of 'flying Tomy' in the ending animation

            -zsleep - for which 'z' is displayed on the screen

            -OldTimerV - address of old timer handler
            -Count - counter to set pace of game by
        graphics:
            -pbuf - used in DrawCount
            -pos - stores offset position
            -counter - initialize counter for fist download
            -download - 1= Download, 0=Upload
            -completed - 1 = score is 5, 0 = socore<5
            -InorOut - use in checkarea, 1 = in, 0 = out
            -Score - holds the number of disks to be drawn
            -barPos - lenght of downloading bar
            -leftpos - use in split screen, lenght of left half of screen
            -rightpos - use in split screen, lenght of right half of screen
            -splitSpeed - speed of spliting screen
 
 
Constant:
            -P2_U, P2_D, P2_R, P2_L - for the keyboard control
            -CountDownLoad = undecided (value from which LoadCount counts down)
            -CountDownTA = undecided (value from which TA1stop and TA2stop counts down)
            -TomCompX = x location of Tomy for when uploading to his computer
            -TomCompY = y location of Tomy for when uploading to his computer
            -MateCompX = x location of Tomy for when downloading from his classmate's computer
            -MateCompY = y location of Tomy for when downloading from his classmate's computer
            -MaxValue = 2^16
            - K1 - 55821
            -Zpos1 - constant for the offset of 'z'
            -Zpos2 - same here
            -Zpos3 - same here
 

 ScreenShots:
 
 

Game's Background

 TA at the top of the screen. (actual size 60 X 60 pixel)
 
 
Procedures:
 
Graphics:

 1.MoveImage- Ka Chun Ma
       Purpose: transfer the image in a given segment to another segment.
           Description: For example, it could place the background from the BackSeg to the ImageSeg which
                                 will later merge with  the ForeSeg.
           Input: none

2.DrawScreen- Ka Chun Ma

          Purpose: Display all images in the ImageSeg to the screen
               input: none
            Output: Write to screen

3.LoadPCX- Ka Chun Ma
           Purpose: Loads and decodes a 320x200 PCX file into a specified Seg and maps the RBG color
                             component from 8 bits to 6 bits registers.
           Description: This function is derived from the lab manual.
           Input: AX - Segment in the memory where the image goes to.
                     DX - offset
           Output: set the VGA palette register.
                        load the ImageSeg with the decoded image.

4. DrawCount - Ka Chun Ma

         Purpose: Display numbers on ImageSeg, calls BINASC. calls ScanImage.
              input: Count  = number, which is the Downloading counter.
           Output: write to ImageSeg

5.ScanImage  - Ka Chun Ma

       Purpose: Scan desire image located a given segment to another segment at a given location
                     : Scan all size of all images. Draw non-white pixel only.

             input: Source   = segment that holds that image, 0 = ForeSeg, 1 = Scratchpad
                     : Dest     = segment that will store the image, 0 = ImageSeg, 1 = BackSeg
                     : position = offset of the image to be displayed in Dest segment
                     : H, W     = height and width of image
                     : pic      = index of picture in the look up table (picNum)
          Output: move images from one seg to another

       note: More arguments are added compared to the first version.
               This make it easier to find the changing offset in the "SplitScreen" function.
               e.g. if pic > 75, pic = offset of image != index of picNum

 (*) notation means new added function that wasn't in the first write up 
 

6. DrawScore - Ka Chun Ma (*)

         Purpose: Draw little disk at the status bar (bottom of screen)
              input: Score = number of pieces of MP
           Output: write to BackSeg

7. DrawSkull- Ka Chun Ma (*)

        Purpose: Draw little skull at the status bar. Similar to DrawScore.
             input: Score = number of "caught"
          Output: write to BackSeg

8. WaitTimer - Ka Chun Ma (*)

         Purpose: Give pause between drawing things.  Used in Opening function.
              input: howLong  = how long is the pause.
           Output: none

9. Opening - Ka Chun Ma (*)

         Purpose: The title screen. Calls SplitScreen and end with option Screen.
               input: none
            Output: Write to Screen

10. SplitScreen - Ka Chun Ma (*)

         Purpose: Split screen into half slowly with a background image behind it

               input: ImageBuffer should contain images for spliting
                         BackBuffer  should contain the desire background.(loadPCX file into BackBuffer)
             Output: write to ImageSeg and BackSeg;
                        : transfer the background from BackBuffer to Imagebuffer at the end
                  note: must call install timer before calling this function since it uses WaitTimer.

11. CheckArea - Ka Chun Ma (*)

          Purpose: Check if Tomy is at the right place for downloading and uploading.
               input: dimension of a Rectangle
            Output: Set InorOut = 1 if in.  Set InorOut = 0 if out.

12.CheckDownload  - Ka Chun Ma (*)

          Purpose:1.Check for downloading and uploading. If download or uploading,
                            dec counter and display it.
                        2.Once finish downloading, avoid "re-download". Likewise for upload.
                        3.Draw Download Bar on the ImageSeg.
                        4.Keep track of Score.
                        5.Earse Bar and Counter on Screen when quit.

             Input:    tomypic = 9, download; 8 = upload
                         dowload = 1, download; 1 = upload.  Avoid re-download
           Output:  Draw Count, Score and download bar. Set tomypic = face down when finish
                        Reset count when quit.
 
 
13. InitWhite-Ryan Tam
        Purpose:  This routine initializes all the bytes in the Scratchpad to white.
            Inputs: none
            Outputs: reset the all the bytes in the Scratchpad to 0D7h

14. InitWhite-Ryan Tam
        Purpose:  This routine initializes all the bytes in the ImageBuffer to black.
            Inputs: none
            Outputs: reset the all the bytes in the ImageBuffer to 00h

15. Random-Ryan Tam
            Purpose:  This routine generates a pseudo-random number by multiplication and addition of large prime
                             constant to a random number.
            Inputs: randseed, tomx, tomy
                         randstate: if randstate = 1, add the variable tomy as the input
                                        if randstate = 0, add the variable tomx as the input
            Outputs: Randseed = Random number between 0 .. 2^16-1
            Description: This function is adopted from previous MP

16. TopTAControl -Ryan Tam
            Purpose: have the computer decide the movement and action of TA1
            Description: This routine calls the random AI so that the TA on the top would move, stop and turn according to the output of
                                  the random function
           Inputs: TA1pic - the previous direction of the top TA
                       ta2pause - see if the other TA is pause at this time
                       ta1look - a counter for how long the TA is looking at Tomy
                       ta1stop - a counter for how long the TA stops before he turns
           Outputs: TA1pic - the next motion of the TA
                          TA1pos - the offset of the top TA on the screen
                          ta1old - saves the TA1pic when the TA doesn't stop or turn

17. TA1turn-Ryan Tam
        Purpose:  This routine set the variable for the top TA when he stops.
            Inputs: randseed
            Outputs: ta1pause
            Description: This routine is called by the TopTAControl and gives signal to the caller function when the top TA needs to turn.

18. BottomTAControl -Ryan Tam
           Purpose: have the computer decide the movement and action of TA2
           Description: same as TopTAControl
           Inputs: TA2pic - the previous direction of the top TA
                        ta1pause - see if the other TA is pause at this time
                        ta2look - a counter for how long the TA is looking at Tomy
                        ta2stop - a counter for how long the TA stops before he turns
           Outputs: TA2pic - the next motion of the TA
                          TA2pos - the offset of the top TA on the screen
                          ta2old - saves the TA1pic when the TA doesn't stop or turn

19. TA2turn-Ryan Tam
        Purpose:  This routine set the variable for the bottom TA when he stops.
            Inputs: randseed
            Outputs: ta2pause
            Description: This routine is called by the BottomTAControl and gives signal to the caller function when the bottom TA needs to turn.

20. Caught -Ryan Tam
           Purpose: check to see if Tomy is being caught by one of the TAs
           Inputs: stole, tompic, TA1pic, TA2pic
           Outputs: increment dead when Tomy is caught by the either one of the TAs

21. Arrangepts-Ryan Tam
        Purpose:  This routine rearranges any two points on the decoded pcx file.
            Inputs: X1, Y1, X2, Y2
            Outputs: xnd and ynd - the point that has a higher y value
                            xst and yst - the point which has a lower y value
            Description: This routine rearranges any two points with respect to their y-value.

22. Scaling-Ryan Tam
        Purpose:  This routine puts a pixel in the decoded pcx file and put it in a new position depending on the variable scale.
                             The range for the scaling factor is from 0 to 255.
            Inputs: xst, yst, xnd, ynd
                         scale = how much the pcx file is going to be scale
            Outputs: drawxpos = the new x-position that the same pixel has to be drawn
                            drawypos = the new y-position that the same pixel has to be drawn
            Description: This routine first calculates the slope between the pixel you want to relocate and the center pixel, and multiplies
                                  it by whatever scale you want to use.

23. DrawScale-Ryan Tam
        Purpose:  This routine put every pixel on the pcx to a new position in the Scratchpad
            Inputs:scaleX - x-position of the pixel that is going to be scaled
                        scaleY - y-position of the pixel that is going to be scaled
            Outputs: pixels are placed in the scaled position on in the buffer
            Description: This routine calls Scaling and loops through the entire 320x200 pcx file and scales every pixel.

24. EndingScreen-Ryan Tam
        Purpose:  This function outputs the ending animation to the screen which also with sound associated with it.
            Inputs: shrink - for how much the pcx is shrink
                         shift -  for how much the scaled pcx is placed away from the previous drawn picture
            Outputs: the entire ending animation
            Description: This routine calls InitWhite, InitImage, WaitTimer, playbeating, ScanImage, DrawScale and DrawScreen
                                  and mix them all up for the entire animation.

MIDI Sound

25. RegisterXMIDI -Richard Rittis
         Purpose: Registers XMIDI data.
         Inputs:
                        CX - Segment address of MIDI segment.
                        BX - Offset of midi file.
         Outputs: none
         Description: This function stores the XMIDI data to be played in Midpak's interal buffer by using the
                              MIDPAK driver function 704h on INT 66h.
 

26. PlayTheme-Richard Rittis
             Purpose: Play the currently registered midi file.
             Outputs: sound (midi file)
             Description: This function starts the playing of a selected midi file by using the MIDPAK driver
                                  function 702h on INT 66h.

27. StopMIDI-Richard Rittis
            Purpose: Stops playing the xmidi file.
            Description: This function uses the MIDPAK function 705h on INT 66h.

28. ResumeMIDI-Richard Rittis
            Purpose: Resumes playing a stopped midi sequence.
            Description: This function uses the MIDPAK function 70Bh on INT 66h.

29. CheckMIDIStatus-Richard Rittis
            Purpose: Checks the status of the xmidi file play process.
            Description: This function uses the MIDPAK function 70Ch on INT 66h.

VOICE/SOUND EFFECT sound

30. InstSound -Richard Rittis
          Purpose:  Installs new vector for ISR.
          Inputs: None
          Outputs: Sets OldSoundV.
          Description: Saves old sound card interrupt vector and installs sound card  IRQ vector .

31. DeInstSound -Richard Rittis
          Purpose: Reinstalls original vector for sound card IRQ ISR.
          Inputs: None
          Outputs: Restores interrupt vector to original.
          Description: uses OldSoundV.

32. MySoundHandler -Richard Rittis
          Purpose: ISR to acknowledge IRQ and send EOI command to Master/slave PIC .
          Inputs: None
          Outputs: EOI command to PICs, read command to acknowlege the DSP.
          Description:   DSP only requires a read command to acknowledge interrupt.  If IRQ
                                 is greater than 7, then it also sends EOI to slave PIC.

33. SetSoundCardData -Richard Rittis
          Purpose: Read the sound card settings from the environment PSP.
          Inputs: None
          Outputs: Sets DMAChannel, IRQ, and SoundBaseAddr.
          Description: Calls LoadSound to load the SET.TXT file into memory.  Scan through the DOS environment
                               data located in the file SET.TXT until it finds BLASTER section.  Retrieves and sets the information;
                               SoundBaseAddr = A### (base address), IRQ = I# (interrupt), and DMAChannel = D# (DMA).
                               Also Calculates IRQint which is dependent upon IRQ.

34. LoadSound-Richard Rittis
         Purpose: Load a selected unformatted file to Buffer.
         Inputs: DX - Offset to string.
         Outputs: Loads the segment, returns AX = FileSize.
         Description: It utilizes DOS function to open file into the buffer and updates the file pointer.
 

35. ResetDSP-Richard Rittis
         Purpose: Reset/Initialize the DSP.
         Inputs: SoundBaseAddr
         Outputs: None.
         Description: Prior to using (programming) the DSP, it must be reset/initailized.  This is done by sending
                            a ‘1’ to the Reset port (2x6h), waiting 3 seconds, and then sending a ‘0’ to the port.  After
                            approx. 100 us, the DSP should be reset.  This can be verified by polling for a ready byte (AAh)
                            from the Read Data port (2xAh) when a ‘1’ is received at the Read-Buffer Status port (2xEh).

36. ReadDSP-Richard Rittis
         Purpose: Read the DSP.
         Inputs: SoundBaseAddr
         Outputs: None.
         Description:  When read buffer status port (2xEh) contains a ‘1’, this command reads data in read data port (2xAh).

37. WriteDSP-Richard Rittis
         Purpose: A C-style function write to the DSP.
         Inputs: Command.
         Outputs: Writes to DSP.
         Description:  Reads Write-buffer status port. Sends command to DSP write buffer status port when DSP is ready.

38. InitDMAC-Richard Rittis
         Purpose: Sets up the DMA Controller in preparation for a transfer.
         Inputs: DMAChannel
         Outputs: Set DMAC
         Description:  Calculates Page and offset, MASK DMA channel, RESET, write the transfer MODE,
                            DMA_PAGE,  DMA_OFFSET and DMA_LENGTH, then DEMASK channel.

39. PlaySound-Richard Rittis
         Purpose: A C-style function to play the desired sound file.
         Inputs: offset of sound file, segment of sound file (usually SoundSeg1), length of file
         Outputs: Plays sound
         Description: Turn Speaker on, Set TIME_CONSTANT, HIGHSPEED, AUTOINIT, buffer size and
                             play MODE, turn speaker off.

40. SetVolume-Richard Rittis
         Purpose:  Sets the volumes of the various mixer channels
         Inputs: none
         Outputs: sound levels on mixer channels set
         Description:  Calls MixerSet.

41. MixerSet-Richard Rittis
         Purpose: Sets the mixer register to the value passed to it.
         Inputs: MixerRegIndex, MixerRegSetting
         Outputs: Sets mixer according to value passed
         Description: none

42. CalcLine
         purpose - calculates line from left point to right point
                    - assumes that RightY is larger than LeftY
                    - writes x value to corresponding y location in LineArray
         inputs - LeftX, LeftY, RightX, RightY
         outputs - writes to LineArray

43. ClearLine
         purpose - clears LineArray to all zeros
         inputs - no input
         outputs - writes to LineArray

44. StartMouse
         purpose - mouse handler for option screen
                    - checks for quit and play buttons
         inputs - AX = conditional mask causing call
                        - BX = button state (0-left button, 1-right button)
                        - CX = horizontal cursor position
                        - DX = vertical cursor position
                        - DS = mouse driver data seg
        outputs - boolean value in quit or play or neither.

45. MouseHandler
        purpose - mouse handler for during game
                    - checks for all hotspots on screen and returns values accordingly
                    - returns fudged location of MouseX and MouseY depending on location
                        of mouse and Tomy
                    - returns boolean values to button variables
                    - returns boolean value in computer dependent on whether the computer was
                        clicked legitimately (i.e. was Tomy close enough to the computer?)
                    - returns boolean in quit button if play clicks quit
        inputs - AX = conditional mask causing call
                        - BX = button state (0-left button, 1-right button)
                        - CX = horizontal cursor position
                        - DX = vertical cursor position
                        - DS = mouse driver data seg
        outputs - MouseX, MouseY, LeftButton, RightButton, computer, quit

46. OffsetCalc- Shoko Oono
            Purpose: calculate offset video memory given x and y coordinates
            Inputs:
                -CX = x
                -DX = y
           Outputs:
                -DI = offset in video memory

47. GameMain- Shoko Oono
             Purpose
              -control flow of game
              -installs and deinstalls timer
              -starts and ends background music
              -resets mouse and installs handler into mouse
              -output opening screen with mouse-selectable choices
              -each round, clear score and clear screen to start position
              -play soundeffects during gameplay
              -during game, refresh screen, move characters, keep track of characters
              -check for game over, and display screen for "game over"
              -return to opening screen after each round
             Inputs
              -mouse variables (LeftButton, RightButton, etc)
             Outputs
            -the game

48. Movement- Shoko Oono
        purpose - to plot the next location of Tomy every iteration of GameMain
                    - calls CalcLine if new destination needs to be plotted
                    - accesses LineArray to find next destination and then moves to
                        that point a point at a time for smooth movement
                    - note - 30 is subtracted from Mouse vars because Tomy's locations
                        are at his upper left, whereas he should move directly towards
                        the mouse
        inputs - MouseX, MouseY, LineArray, NextX, NextY
        outputs - newtomx, newtomy

49. TomyControl - Shoko Oono
            Purpose:      Gives the direction of motion of Tommy for other drawing routines
            Description: This function basically gives the drawing routines information for which pictures of Tommy
                      they output on the screen.
            Inputs: newtomx, newtomy, tomx, tomy
            Outputs: tompic, tompos
 

50. InstTimer - Shoko Oono
            Purpose: installs MyTimerHandler and saves old timer vector
                            configures timer chip at a suitable pace
           Note: derived from old mp
            Input: none
            Output: OldTimerV

51. MyTimerHandler- Shoko Oono
            Purpose: increments counter, Count
                            calls old timer handler 18times per second
                            sends end-of-interrupt
           Note: derived from old mp
            Input: Count and OldTimerV
            Output: Count

52. DeInstTimer- Shoko Oono
            Purpose: restores OldTimerV
                            restores old configurations
           Note: derived from old mp
            Input: OldTimerV
            Output: none

53. InstKey
            Purpose: installs MyKeyHandler and saves the default old key vector
            input: none
            output: OldKeyV

54. MyKeyHandler
            Purpose: This routine sets escPressed to 1 if the escape key is pressed sets spcPressed to 1 if the
                           spacebar is pressed; also sets tomDir to one of UP, DOWN, LEFT, or RIGHT depending on  which keys were pressed
            input: none
            output: escPressed, spcPressed, TomDir

55. DeInstKey
            Purpose: to restore the default keyboard interrupt vector
            input: OldKeyV
            output: none