Author Topic: need help with mouse in qb program  (Read 6444 times)

0 Members and 1 Guest are viewing this topic.

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
need help with mouse in qb program
« on: September 04, 2019, 08:06:26 am »
I got the game files when I got qb45 program and made changes to it so the mouse would work instead of the keyboard.

I have attached the .bas file that used to work with the mouse.
maybe it is missing something?

Can someone get this program to work with the mouse?

Thanks

« Last Edit: September 04, 2019, 09:41:51 am by tuc47 »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #1 on: September 04, 2019, 08:44:21 am »
Basic mouse access:

Code: QB64: [Select]
  1. WHILE _MOUSEINPUT : WEND  ' yeah really an empty loop (unless you want wheel)
  2. mx = _MOUSEX : my = _MOUSEY : mb = _MOUSEBUTTON(1) '< left button is down if <> 0
  3.  

now you know where mouse is AND if the left button is down, put inside main loop to poll mouse like you do INKEY$ for key presses.

Practice with that first, then we can advance. (hard to advise for advanced app like yours)

Update: hey! those KEY and ONKEY things look interesting!
« Last Edit: September 04, 2019, 09:00:21 am by bplus »

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #2 on: September 04, 2019, 09:01:51 am »
not sure.
This program used to work as written. unsure why it will not work now.
Did you look at the program?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #3 on: September 04, 2019, 09:06:54 am »
I glanced over main loop to see where mouse fits in, I would put my mouse code just above inkey$

The PEEK and POKE and SEG gives me the heebee geebee's there are probably alternate ways for that now. What is that for?

Are there any error messages?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #4 on: September 04, 2019, 09:16:35 am »
For me, it can't find a file 446 or something I continue anyway and Steve's Q Space comes up.

466 is a file of scores looks like.

Would that be our Steve McNeill? nah, just coincidence right?

So I press any key and a tiny little screen pops with earth I suppose, I try arrow keys > work, I hit z and blast something out of sky.

No problem here?

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #5 on: September 04, 2019, 09:40:34 am »
SORRY I attached the wrong file
Here is the correct one.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #6 on: September 04, 2019, 09:47:40 am »
The IDE immediately red lines this:
Code: QB64: [Select]
  1. REM $INCLUDE: 'Q4T.BI'                            ' Contains declarations for      
  2.  

And if the BI file has sub and function procedures you will have to put them in a .BM file and load that after all your other code at bottom of your program.

Multiple files are best attached here in a .zip or 7z
« Last Edit: September 04, 2019, 09:49:33 am by bplus »

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #7 on: September 04, 2019, 10:11:33 am »
that was rem so not run 
I get error  line 258  CALL MouseLimits(15, 10, 150, 310, 0) ' Set mouse limits 

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #8 on: September 04, 2019, 10:13:10 am »
I don't need the file? what if mouse stuff is in it?

YEP! the next red lined this tells me IDE doesn't know WTH this is:
Code: QB64: [Select]
  1. DIM InReg AS RegType, OutReg AS RegType               ' Typed for Interrupt()
  2.  
line 56

And Old QB45 programs used that for mouser routines, if I recall.

Double yeppers!!! This is redlined next:
    CALL MouseLimits(15, 10, 150, 310, 0) ' Set mouse limits
    CALL MouseLocate(Target.Y, Target.x, 0)                 ' Locate mouse

No mouse routines!!

You need the .BI file for sure!!!

« Last Edit: September 04, 2019, 10:18:50 am by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #9 on: September 04, 2019, 10:19:09 am »
Mouse support added. Used QB64 statements. See rows 283 to 295. Set your own time limit on this rows for smaller mouse reactions.
Used first source code in this thread. As missed 1QSpace.sco file i create own contained this:

Petr, 100


Code: QB64: [Select]
  1. '
  2. '                               1QSPACE.BAS
  3. '
  4. '         Copyright (C) 1990 Microsoft Corporation. All Rights Reserved.
  5. '
  6. ' Your mission in QSpace is to defend your orbiting starbases from enemy
  7. ' attack.  Protect them by firing your own interceptor missiles to destroy
  8. ' the incoming missiles.
  9. '
  10. ' To run this game, press Shift+F5.
  11. '
  12. ' To exit this program, press Alt, F, X.
  13. '
  14. ' To get help on a BASIC keyword, move the cursor to the keyword and press
  15. ' F1 or click the right mouse button.
  16. '
  17. ' To view suggestions on changing this game, press Page Down.
  18. '
  19. '
  20. '                             Suggested Changes
  21. '                             -----------------
  22. '
  23. ' There are many ways that you can modify this BASIC game.  The CONST
  24. ' statements below these comments and the DATA statements at the end
  25. ' of this screen can be modified to change the following:
  26. '
  27. '    Enemy missile speed at the start of the game
  28. '    Songs played during this game
  29. '    Color of the game pieces (EGA or VGA systems only)
  30. '    Speed of the targeting crosshair
  31. '    Number of missiles falling at the start of the game
  32. '    Size of missile explosions
  33. '    Duration of the explosions
  34. '    GAME OVER messages
  35. '
  36. ' On the right side of each CONST statement, there is a comment that tells
  37. ' you what it does and how big or small you can set the value.  Above the
  38. ' DATA statements, there are comments that tell you the format of the
  39. ' information stored there.
  40. '
  41. ' On your own, you can also add exciting sound and visual effects or make
  42. ' any other changes that your imagination can dream up.  By reading the
  43. ' Learn BASIC Now book, you'll learn the techniques that will enable you
  44. ' to fully customize this game and to create games of your own.
  45. '
  46. ' If the game won't run after you have changed it, you can exit without
  47. ' saving your changes by pressing Alt, F, X and choosing NO.
  48. '
  49. ' If you do want to save your changes, press Alt, F, A and enter a filename
  50. ' for saving your version of the program.  Before saving your changes,
  51. ' however, make sure the program still works by running the program and
  52. ' verifying that your changes produce the desired results.  Also, always
  53. ' be sure to keep a backup of the original program.
  54. DEFINT A-Z
  55. ' These CONST statements define things in the game that you can control.
  56. CONST GAMEBKGROUNDS7 = 0 ' Screen background color in screen mode 7. Can't be any of the other game colors.  Usually is black (0).
  57. CONST INITIALDELAY = .3 ' Initial value of the Incoming missile delay.  Increase the number to make the Incoming missiles slower; decrease to make them faster.  After odd-numbered waves, the IncomingDelay gets 33% shorter.
  58. CONST INITNUMSTARBASES = 1 ' Initial number of starbases.  This sets the starting value of the MaxStarbases variable.  Range is 1 to 4.
  59. CONST INITNUMMISSILES = 3 ' Number of incoming missiles when the game starts.  This is just the start - the number of missiles increases as you complete more waves.  Range 1 to 6.
  60. CONST TARGETSPEED = 15 ' How fast and far the target moves.  Range 4 to 30.
  61. CONST EXPLOSIONDELAY = .05 ' Rate that explosions grow.  Range .05 to .25.
  62. CONST EXPLRADIUS = 75 ' How big the explosion gets before it stops and is erased.  Range 5 to 75.
  63. CONST NEXPLRADIUS = 35
  64. CONST PLANETS7 = 9 ' Planet color in screen mode 7.
  65. CONST BASECOLORS7 = 7 ' Starbase color in screen mode 7. Can't be the same as GAMEBKGROUNDS7.
  66. CONST ENEMYCOLORS7 = 3 ' Enemy missile color in screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  67. CONST INTERCEPTCOLORS7 = 2 ' Interceptor missile color in screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  68. CONST EXPLCOLORS7 = 12 ' Explosion color in screen mode 7. Can't be the same as GAMEBKGROUNDS7.
  69. CONST TARGETCOLORS7 = 2 ' Target crosshair color for screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  70. CONST FASTESTMISSILE = .01 ' Lowest time delay between enemy missile movements.
  71. CONST RATIOINTERCEPTTOINCOMING = 10 ' How fast your interceptor missiles move compared to enemy missiles.  At 5, interceptors move at least 5 times faster than enemy missiles.  Range 1 to 20.
  72. ' The following sound constants are used by the PLAY command to
  73. ' produce music during the game.  To change the sounds you hear, change
  74. ' these constants.  Refer to the online help for PLAY for the correct format.
  75. ' To completely remove sound from the game set the constants equal to null.
  76. ' For example:  GAMESTARTSONG = ""
  77. CONST GAMESTARTSONG = "MBT150L4O2CD-CL8A-FAECD-L4A-F" ' Played when program starts. No limits.
  78. CONST WAVEOVERSONG = "MB O2 T240 L4 N40 N44 N48 N55 N48 L2 N53" ' Played at the end of each wave. No limits.
  79. CONST GAMEOVERSONG = "MB O1 T240 L2 g- g- L1 a" ' Played when the game is over. No limits.
  80.  
  81. ' The following CONST statements should not be changed like the ones above
  82. ' because the program relies on them being this value.
  83. CONST TRUE = -1 ' Microsoft QuickBASIC uses -1 to mean TRUE.
  84. CONST FALSE = 0 ' 0 means FALSE.
  85. CONST XSCALE = 320 ' Width of the screen.
  86. CONST YSCALE = 200 ' Height of the screen.
  87. CONST MAXY = YSCALE - 11 ' Highest vertical position that a missile can be.
  88. CONST MINY = 11 ' Lowest position an incoming missile can be can be.
  89. CONST MINX = 11 ' Left-most position an incoming missile can be.
  90. CONST MAXX = XSCALE - 11 ' Right-most position that an Incoming missile can be.
  91. CONST PAUSEGAME = 80 ' Key that pauses game.
  92. CONST QUITGAME = 81 ' Key that quits game.
  93. CONST ZKEY = 44 ' Key that fires the left missle.
  94. CONST XKEY = 45 ' Key that fires the right missle.
  95. CONST FACTOR = 250 ' Used to determine the radius of the starbases.  Increase to make the starbases smaller; decrease to make the starbases larger.
  96. CONST PI = 3.14 ' Value of the mathematical constant PI.  Used in determining the position of the starbases orbiting the planet.
  97. CONST PLANETRADIUS = XSCALE * .62 ' The radius of the planet that the starbases orbit.
  98. CONST GAMEBKGROUNDS1 = 0 ' Screen background in SCREEN 1.
  99. CONST PLANETS1 = 2 ' Planet color in SCREEN 1.
  100. CONST BASECOLORS1 = 1 ' Starbase color in SCREEN 1.
  101. CONST ENEMYCOLORS1 = 3 ' Enemy missile color in SCREEN 1.
  102. CONST INTERCEPTCOLORS1 = 3 ' Interceptor missile color in SCREEN 1.
  103. CONST EXPLCOLORS1 = 2 ' Explosion color in SCREEN 1.
  104. CONST TARGETCOLORS1 = 9 ' Target crosshair color for SCREEN 1
  105. CONST RESOLUTION = 100 ' Controls how accurately a line is drawn.
  106.  
  107. ' SUB and FUNCTION declarations
  108. DECLARE SUB Center (Text$, Row)
  109. DECLARE SUB DestroyStarbase (Z)
  110. DECLARE SUB DisplayIntro ()
  111. DECLARE SUB DisplayGameTitle ()
  112. DECLARE SUB DisplayChanges ()
  113. DECLARE SUB EraseMissileTrail (MNum)
  114. DECLARE SUB Explode (Chosen, x, Y, WMissiles)
  115. DECLARE SUB GameOver ()
  116. DECLARE SUB HorizontalScroll (M$, Row)
  117. DECLARE SUB InitScreen ()
  118. DECLARE SUB InitFirebases ()
  119. DECLARE SUB Keys (TurnKeysOn)
  120. DECLARE SUB KeyPause ()
  121. DECLARE SUB LaunchMissile (Chosen, XStart, YStart, XFinish, YFinish)
  122. DECLARE SUB NewMissile ()
  123. DECLARE SUB NewStarbase ()
  124. DECLARE SUB NewInterceptor (x, Y)
  125. DECLARE SUB StopMissile (Chosen, WMissiles)
  126. DECLARE SUB UpdateMissiles (Start, Finish, WMissiles, NumOfTimes, WColor)
  127. DECLARE SUB UpdateExplosions ()
  128. DECLARE SUB UpdateTarget ()
  129. DECLARE SUB UpdateScore ()
  130. DECLARE SUB WaveComplete ()
  131.  
  132. ' Structure definitions.
  133. TYPE Missile
  134.     x AS INTEGER ' Current X (horizontal) position.
  135.     Y AS INTEGER ' Current Y (vertical) position.
  136.     XStart AS INTEGER ' Horizontal missile start position.
  137.     YStart AS INTEGER ' Vertical missile start position.
  138.     XOffset AS INTEGER ' # of X pixels to move each time the UpdateMissile subprogram is called.
  139.     YOffset AS INTEGER ' # of Y pixels to move each time the UpdateMissile subprogram is called.
  140.     Active AS INTEGER ' 0 = not active, 1 = in flight, 2 = frozen (while it explodes)
  141.     XFinish AS INTEGER ' X of the missile's target.
  142.     YFinish AS INTEGER ' Y of the missile's target.
  143.     MaxCount AS INTEGER ' Number of moves in the missile's primary direction until the missile moves in the secondary direction.
  144.     Count AS INTEGER ' Number of moves in the missile's primary direction.
  145.     YMajor AS INTEGER ' TRUE if the missile moves more vertically then horizontally.  FALSE otherwise.
  146.  
  147. TYPE GenericPos ' General-purpose data type for moving objects.  Used many places in QSpace.
  148.     x AS INTEGER ' X position.
  149.     Y AS INTEGER ' Y position.
  150.     Active AS INTEGER ' FALSE (0) = Not active (destroyed, etc.), TRUE (-1) = Active.
  151.     OldX AS INTEGER ' Last X position.  Used to make it possible to restore a previous position if the new one would be off the screen.
  152.     OldY AS INTEGER ' Last Y position.  Used to make it possible to restore a previous position if the new one would be off the screen.
  153.  
  154. TYPE xplode ' Data type for explosions.
  155.     x AS INTEGER ' X position.
  156.     Y AS INTEGER ' Y position.
  157.     Active AS INTEGER ' Explosion status.  FALSE (0) = No explosion, Greater than 0 = Radius of explosion.
  158.     MissileNum AS INTEGER ' Number of the missile that was destroyed to cause this explosion.  Needed to erase missile path after explosion is over.
  159.     MType AS INTEGER ' Type of the missile that exploded.  1 = incoming enemy missile, 2 = interceptor missile.
  160.  
  161. CLEAR , , 5120 ' Set up a large stack for input processing
  162.  
  163. ' DIM SHARED indicates that the following variable is available to all
  164. ' subprograms.  Without this statement, a variable used in one subprogram
  165. ' cannot be used by another subprogram or the main program.
  166. DIM SHARED NumMissiles AS INTEGER ' Maximum number of incoming missiles.  Initially set to InitNumMissiles.
  167. DIM SHARED MaxStarbases AS INTEGER ' Maximum number of starbases.  Initially set to InitNumStarbases.
  168. DIM SHARED Incoming(1 TO 10) AS Missile ' Array used to track of all missiles, both incoming and interceptors.  Incoming missiles are numbered from 1 to 6; interceptors from 7 to 10.
  169. DIM SHARED Starbase(1 TO 4) AS GenericPos ' Array used to keep track of the starbases.  Game begins with 3 starbases but up to 4 starbases can exist depending on the score.  New bases added by the WaveComplete subprogram.
  170. DIM SHARED ContinueGame AS INTEGER ' A flag variable to track the status of the game.  1 = Game in progress, -1 = Begin new game, 0 = End game.
  171. DIM SHARED Target AS GenericPos ' Target crosshair.  The .active element is not used.
  172. DIM SHARED NumIntercepts AS INTEGER ' Number of interceptors flying.  No more than 4 can exist at any one time.
  173. DIM SHARED Score AS LONG ' Score.
  174. DIM SHARED Hscore AS LONG ' High score
  175. DIM SHARED Wave AS LONG ' Number of the current attack wave.
  176. DIM SHARED WaveCount AS LONG ' Number of missiles already launched in the current attack wave.
  177. DIM SHARED NextIncoming AS SINGLE ' Interval, in seconds from current time, to move the incoming missiles again.
  178. DIM SHARED NextExplosion AS SINGLE ' Delay until next explosion begins.
  179. DIM SHARED Explosion(1 TO 10) AS xplode ' Array that keeps track of the explosions.  Since no more than 10 missiles can be flying at once, no more than 10 simultaneous explosions are possible.
  180. DIM SHARED IncomingDelay AS SINGLE ' Delay between incoming missile movements.
  181. DIM SHARED MissilesFlying AS INTEGER ' Number of incoming missiles currently flying.
  182. DIM SHARED BasesLeft AS INTEGER ' Number of starbases left.  Used for scoring and in determining when the game is over.
  183. DIM SHARED TotalIncoming AS LONG ' Total number of incoming missiles that have been destroyed.  Used for the statistics at the end of the game.
  184. DIM SHARED TotalInterceptors AS LONG ' Total number of interceptors launched.  Used for the statistics at the end of the game.
  185. DIM SHARED NextNewBase AS LONG ' Score when a bonus new base will be awarded.
  186. DIM SHARED NumExplosions AS INTEGER ' Number of explosions in progress.
  187. DIM SHARED PlanetColor AS INTEGER ' Color of the planet.
  188. DIM SHARED EnemyColor AS INTEGER ' Color of the enemy missiles.
  189. DIM SHARED InterceptColor AS INTEGER ' Color of interceptor missiles.
  190. DIM SHARED ExplColor AS INTEGER ' Color of the explosions.
  191. DIM SHARED BaseColor AS INTEGER ' Primary color of the starbase.
  192. DIM SHARED GameBkGround AS INTEGER ' Color of the game background.
  193. DIM SHARED TargetColor AS INTEGER ' Color of the target crosshair.
  194. DIM SHARED ScreenMode AS INTEGER ' Number of the screen mode we are running in.
  195. DIM SHARED ScreenWidth AS INTEGER ' Width of the screen. Used in various screen output functions.
  196. DIM KeyFlags AS INTEGER ' Internal state of the keyboard flags when game starts.  Hold the state so it can be restored when the games ends.
  197. DIM BadMode AS INTEGER ' Store the status of a valid screen mode.
  198.  
  199. ON ERROR GOTO ScreenError ' Set up a place to jump to if an error occurs in the program.
  200. BadMode = FALSE
  201. ScreenMode = 7
  202. SCREEN ScreenMode ' Attempt to go into SCREEN 7 (EGA screen).
  203. IF BadMode = TRUE THEN ' If this attempt failed.
  204.     ScreenMode = 1
  205.     BadMode = FALSE
  206.     SCREEN ScreenMode ' Attempt to go into SCREEN 1 (CGA screen).
  207. ON ERROR GOTO 0 ' Turn off error handling for now.
  208.  
  209. IF BadMode THEN ' If no graphics adapter.
  210.     CLS
  211.     LOCATE 10, 13: PRINT "CGA, EGA Color, or VGA graphics required to run QSPACE.BAS"
  212.     RANDOMIZE TIMER ' Ensure that a new random number sequence is generated.
  213.     DisplayIntro ' Display the name of the game, control keys, etc.
  214.  
  215.     DEF SEG = 0 ' Set the current segment to the low memory area.
  216.     KeyFlags = PEEK(1047) ' Read the location that stores the keyboard flag.
  217.     POKE 1047, &H0 ' Force them off.
  218.     DEF SEG ' Restore the default segment.
  219.  
  220.     DO ' For multiple games.
  221.         RESTORE ' BASIC command to allow DATA statements to be reused.  Necessary for multiple games.
  222.         ScreenWidth = 40 ' Set screen width of the two screens supported - 1 and 7.
  223.         IncomingDelay = INITIALDELAY ' Set initial incoming missile IncomingDelay to the value of the InitialDelay constant.
  224.         Wave = 1 ' Set wave number to 1 (first wave).
  225.         WaveCount = 0 ' Set number of missiles in the first wave to 0.  After the first wave, WaveCount is reset by the WaveComplete subprogram.
  226.         Score = 0 ' Set score to 0 to begin the game.
  227.         InitScreen ' Initialize the screen, including drawing the planet.
  228.         NumMissiles = INITNUMMISSILES ' Set maximum number of missiles flying simultaneously in each wave to the value of the InitNumMissiles constant.
  229.         MissilesFlying = 0 ' Set the number of missiles currently flying to 0.  Like WaveCount, this is cleared after subsequent waves by the WaveComplete subprogram.
  230.         NumIntercepts = 0 ' Set the number of interceptors currently flying.
  231.         NumExplosions = 0 ' Set the number of explosions currently happening.
  232.         ContinueGame = TRUE ' ContinueGame = TRUE means that a game is in progress.
  233.         NextIncoming = TIMER ' Time when incoming missiles will again fire.  Setting NextIncoming equal to the timer insures that the incoming missiles will begin moving immediately.
  234.         NextExplosion = TIMER ' Time when explosions will be updated again.   Setting NextExplosion equal to the timer ensures that the explosions will begin immediately.
  235.         TotalIncoming = 0 ' Set total number of destroyed incoming missiles.  Missiles are counted as destroyed if hit by interceptor missiles, hit by the explosion of another incoming missile, or stopped by hitting their targets.
  236.         TotalInterceptors = 0 ' Set total number of interceptors launched.
  237.         BasesLeft = 0 ' Set the number of bases remaining.  Necessary because the NewBase subprogram used below adds 1 to the current number of bases remaining.
  238.         MaxStarbases = INITNUMSTARBASES ' Set maximum number of starbases equal to the value of the InitNumStarbases constant.
  239.         NextNewBase = 25000 ' Set initial point at which a bonus starbase is awarded. After that, new starbases are awarded based on a formula in the WaveComplete subprogram.
  240.  
  241.         ERASE Starbase, Incoming, Explosion ' Set all elements of the entire Starbase, Incoming, and Explosion arrays to 0.
  242.  
  243.         FOR i = 1 TO MaxStarbases ' Loop to create the number of starbases called for in the MaxStarbases variable.
  244.             NewStarbase ' Create a new starbase
  245.         NEXT i
  246.  
  247.         InitFirebases ' Draw the firebases.
  248.  
  249.         FOR i = 1 TO NumMissiles ' Start the incoming missiles flying.
  250.             NewMissile
  251.         NEXT i
  252.  
  253.         ' The KEY n and ON KEY statements below enable QSpace to move the
  254.         ' target crosshair the moment a key is pressed.  After the
  255.         ' KEY (X) ON statement, anytime key (X) is pressed, QSpace stops
  256.         ' what it was doing and moves the crosshair.  After the crosshair
  257.         ' moves, QSpace goes back to where it left off.  This method allows
  258.         ' BASIC to process keys instantly and without explicitly checking
  259.         ' the keyboard.
  260.         KEY 15, CHR$(0) + CHR$(XKEY) ' Right missle the x key
  261.         KEY 16, CHR$(0) + CHR$(ZKEY) ' Left missle  the z key
  262.         KEY 17, CHR$(128) + CHR$(72) ' Extended Up key for player 1.
  263.         KEY 18, CHR$(128) + CHR$(75) ' Extended Left key for player 1.
  264.         KEY 19, CHR$(128) + CHR$(77) ' Extended Right key for player 1.
  265.         KEY 20, CHR$(128) + CHR$(80) ' Extended Down key for player 1.
  266.  
  267.         ON KEY(11) GOSUB MoveCrossHairUp ' Up key.
  268.         ON KEY(12) GOSUB MoveCrossHairLeft ' Left key.
  269.         ON KEY(13) GOSUB MoveCrossHairRight ' Right key.
  270.         ON KEY(14) GOSUB MoveCrossHairDown ' Down key.
  271.         ON KEY(15) GOSUB FireLeftMissle ' Fire the left missle.
  272.         ON KEY(16) GOSUB FireRightMissle ' Fire the right missle.
  273.         ON KEY(17) GOSUB MoveCrossHairUp ' Process Up key.
  274.         ON KEY(18) GOSUB MoveCrossHairLeft ' Process Left key.
  275.         ON KEY(19) GOSUB MoveCrossHairRight ' the Right key.
  276.         ON KEY(20) GOSUB MoveCrossHairDown ' the Down key.
  277.         Keys TRUE ' Enable key event processing.
  278.         _MOUSEHIDE
  279.         DO WHILE ContinueGame = TRUE ' ContinueGame is set to TRUE at the start of each game.  When the game is over, ContinueGame is set to either FALSE (do not play again) or 1 (play again).
  280.  
  281.             IF TIMER > MouseTime THEN
  282.                 WHILE _MOUSEINPUT
  283.                     IF omx > _MOUSEX THEN omx = _MOUSEX: GOSUB MoveCrossHairLeft
  284.                     IF omx < _MOUSEX THEN omx = _MOUSEX: GOSUB MoveCrossHairRight
  285.                     IF omy > _MOUSEY THEN omy = _MOUSEY: GOSUB MoveCrossHairUp
  286.                     IF omy < _MOUSEY THEN omy = _MOUSEY: GOSUB MoveCrossHairDown
  287.                     IF _MOUSEBUTTON(1) THEN GOSUB FireRightMissle
  288.                     IF _MOUSEBUTTON(2) THEN GOSUB FireLeftMissle
  289.                 WEND
  290.                 MouseTime = TIMER + .3
  291.             END IF
  292.  
  293.             IF TIMER >= NextIncoming THEN ' If enough time has elapsed since the enemy incoming missiles last moved,
  294.                 NextIncoming = TIMER + IncomingDelay ' Calculate when to move the incoming missiles again.
  295.                 UpdateMissiles 1, NumMissiles, 1, 1, EnemyColor ' Move the incoming missiles one step.  The 1 means move incoming missiles, a 2 would mean move interceptors; EnemyColor is the color of the incoming missiles -- usually cyan (3).
  296.             END IF
  297.  
  298.             IF NumExplosions > 0 THEN ' Update explosions if there are any.
  299.                 IF TIMER >= NextExplosion THEN ' If enough time has elapsed since the explosions were last updated,
  300.                     NextExplosion = TIMER + EXPLOSIONDELAY ' calculate when to update the explosions again.
  301.                     UpdateExplosions ' Increase the size of any explosions.
  302.                 END IF
  303.             END IF
  304.  
  305.             IF NumIntercepts > 0 THEN ' Update interceptors if any are in the air.
  306.                 UpdateMissiles 7, 10, 2, RATIOINTERCEPTTOINCOMING, InterceptColor
  307.             END IF
  308.  
  309.             K$ = INKEY$ ' Get a key press.
  310.             IF LEN(K$) > 0 THEN ' LEN(K$) will be 0 if no key was pressed.
  311.                 SELECT CASE ASC(UCASE$(K$)) ' Prepare to compare the ASCII value of the key press (done with the ASC function).  UCASE$ forces upper-case.
  312.                     CASE PAUSEGAME ' Key to pause game.
  313.                         SOUND 1100, .75 ' Tone at 1100 hertz for 75 clock ticks.
  314.                         Center " * Paused * ", 12 ' Display message on the screen.
  315.                         DO: LOOP UNTIL INKEY$ <> "" ' Wait until player presses any key.
  316.                         Center SPACE$(12), 12
  317.  
  318.                     CASE QUITGAME ' Key to quit game.
  319.                         SOUND 1700, 1 ' Tone at 1700 hertz for 1 clock tick.
  320.                         SOUND 1100, .75 ' Tone at 1100 hertz for .75 clock tick.
  321.                         Center " Really quit? (Y/N) ", 12 ' Make sure player really wants to quit.
  322.                         DO ' Wait until player presses a key.
  323.                             A$ = UCASE$(INKEY$)
  324.                         LOOP UNTIL A$ <> ""
  325.                         IF A$ = "Y" THEN ContinueGame = FALSE ' If so, set the main loop variable to FALSE to end main program level loop.
  326.                         Center SPACE$(20), 12 ' Clear the message line.
  327.  
  328.                 END SELECT
  329.             END IF
  330.  
  331.         LOOP ' Do again until the game is over.
  332.  
  333.     LOOP WHILE ContinueGame <> FALSE ' At GameOver, the ContinueGame variable is set to either 1 or FALSE (0) depending on whether the player wants to try again.  If 1, then the game restarts.
  334.  
  335.     DisplayChanges ' Display the suggested changes.
  336.  
  337.     DEF SEG = 0 ' Restore the previous flag settings.
  338.     POKE 1047, KeyFlags
  339.     DEF SEG
  340.  
  341.  
  342. END ' End of the main program code.
  343.  
  344. MoveCrossHairUp:
  345. Target.Y = Target.Y - TARGETSPEED
  346. UpdateTarget
  347.  
  348. MoveCrossHairDown:
  349. Target.Y = Target.Y + TARGETSPEED
  350. UpdateTarget
  351.  
  352. MoveCrossHairLeft:
  353. Target.x = Target.x - TARGETSPEED
  354. UpdateTarget
  355.  
  356. MoveCrossHairRight:
  357. Target.x = Target.x + TARGETSPEED
  358. UpdateTarget
  359.  
  360. FireLeftMissle:
  361. Keys FALSE ' Turn all keys off.
  362. NewInterceptor MAXX - 1, MAXY - 1 ' Launch interceptor missile.
  363. Keys TRUE ' Turn the keys back on.
  364.  
  365. FireRightMissle:
  366. Keys FALSE ' Turn all keys off.
  367. NewInterceptor MINX + 1, MAXY - 1 ' Launch interceptor missile.
  368. Keys TRUE ' Turn keys back on.
  369.  
  370. ' All of the data for GameOver messages.  These can also be changed but the
  371. ' format must be the same.  For example, the first line has a 5: that says how
  372. ' many lines of data will come afterwards, and the next lines are made of two
  373. ' parts: what the rank is (such as "Cadet") and the comments to go along with it.
  374. ' You can add a new line by following the format the others have and adding
  375. ' one to the number at the top.  The last line has already been created so you
  376. ' can just change the 5 to a 6 for to add that message.
  377.  
  378. DATA 5: ' The number of messages.
  379. DATA "Cadet","Not good.  Everything destroyed.": ' Lowest possible rank.
  380. DATA "Ensign","You saved a few people.": ' Better rank.
  381. DATA "Lieutenant","Your parents will be proud.": ' Better rank.
  382. DATA "Commander","Medal of Honor!": ' Better rank.
  383. DATA "Admiral","If only we had more like you!": ' Top rank.
  384. DATA "Top Gun","You can guard our starbases anytime!!": ' The ultimate.
  385.  
  386. ScreenError: ' QSpace uses this error handler to determine the highest available video mode.
  387. BadMode% = TRUE
  388.  
  389. '----------------------------------------------------------------------------
  390. ' Center
  391. '
  392. '    Centers the given text string on the indicated row.
  393. '
  394. '                       PARAMETERS:     text$   - The text to center
  395. '                                       row     - The screen row to print on
  396. '----------------------------------------------------------------------------
  397. SUB Center (Text$, Row)
  398.  
  399.     LOCATE Row, (ScreenWidth - LEN(Text$)) \ 2 + 1
  400.     PRINT Text$;
  401.  
  402.  
  403. '----------------------------------------------------------------------------
  404. 'DestroyStarbase
  405. '
  406. '    Declares a given base number as destroyed and determine the
  407. '    number of star bases remaining.  If that number is zero then
  408. '    call the GameOver routine. This subprogram does not do the
  409. '    visual explosion of the starbase.
  410. '
  411. '           PARAMETERS:     BNum - Number of the starbase to destroy.
  412. '----------------------------------------------------------------------------
  413. SUB DestroyStarbase (BNum)
  414.  
  415.     Starbase(BNum).Active = FALSE ' Set the passed starbase number to 0.
  416.     BasesLeft = 0 ' Assume there are no starbases left.
  417.  
  418.     FOR i = 1 TO MaxStarbases ' Perform one more than the initial number of starbases.
  419.         BasesLeft = BasesLeft - Starbase(i).Active ' If not 0, increase by one.
  420.         IF Starbase(i).Active = TRUE THEN MaxStarbases = i ' Keep counting until you've counted the number of starbases left.
  421.     NEXT i
  422.  
  423.     IF BasesLeft = 0 THEN ' If there are no starbases left,
  424.         GameOver ' call the GameOver SUB.
  425.     END IF
  426.    
  427.  
  428. '----------------------------------------------------------------------------
  429. ' DisplayChanges
  430. '
  431. '    Displays list of changes that the player can easily make.
  432. '
  433. '           PARAMETERS:     None
  434. '----------------------------------------------------------------------------
  435. SUB DisplayChanges
  436.     SYSTEM
  437.  
  438. '----------------------------------------------------------------------------
  439. ' DisplayGameTitle
  440. '
  441. '    Displays title of the game.
  442. '
  443. '           PARAMETERS:     None
  444. '----------------------------------------------------------------------------
  445. SUB DisplayGameTitle
  446.  
  447.     SCREEN 0 ' Set Screen mode 0.
  448.     WIDTH 80, 25 ' Set width to 80, height to 25.
  449.     COLOR 4, 0 ' Set colors for red on black.
  450.     CLS ' Clear the screen.
  451.     ScreenWidth = 80 ' Set screen width variable to match current width.
  452.  
  453.     ' Draw outline around screen with extended ASCII characters.
  454.     LOCATE 1, 2
  455.     PRINT CHR$(201); STRING$(76, 205); CHR$(187); ' Draw top border.
  456.     FOR i% = 2 TO 24
  457.         LOCATE i%, 2
  458.         PRINT CHR$(186); TAB(79); CHR$(186); ' Draw left and right borders.
  459.     NEXT i%
  460.     LOCATE 25, 2
  461.     PRINT CHR$(200); STRING$(76, 205); CHR$(188); ' Draw bottom border.
  462.  
  463.     OPEN "I", #1, "1QSPACE.SCO": INPUT #1, name$, Hscore: CLOSE #1
  464.     LOCATE 7, 35: PRINT name$
  465.     LOCATE 9, 20: PRINT USING "HAS THE HIGH SCORE OF ###,###,###"; Hscore
  466.      
  467.     ' Print game title centered at top of screen.
  468.     COLOR 0, 4 ' Set colors to black on red.
  469.     Center "     Steve's     ", 1 ' Center game title on lines
  470.     Center "    Q S P A C E    ", 2 ' 1 and 2.
  471.     Center "   Press any key to continue   ", 25 ' Center prompt on line 25.
  472.     COLOR 7, 0 ' Set colors to white on black.
  473.  
  474.  
  475. '----------------------------------------------------------------------------
  476. ' DisplayIntro
  477. '
  478. '    Explains the object of the game and show how to play.
  479. '
  480. '           PARAMETERS:     None
  481. '----------------------------------------------------------------------------
  482. SUB DisplayIntro
  483.    
  484.     DisplayGameTitle ' Display game title.
  485.  
  486.     COLOR 4
  487.     Center STRING$(74, 196), 15 ' Put horizontal red line on screen.
  488.     COLOR 7
  489.     Center " Game Controls ", 15 ' Display game controls.
  490.     Center "General        Missile Launchers               Target site    ", 17
  491.     Center "                                             (Up)", 19
  492.     Center "P - Pause      Z - Fire left launcher                 " + CHR$(24) + "          ", 20
  493.     Center "Q - Quit       X - Fire right launcher       (Left) " + CHR$(27) + "   " + CHR$(26) + " (Right)", 21
  494.     Center "                                            " + CHR$(25), 22
  495.     Center "                                             (Down)", 23
  496.  
  497.     PLAY GAMESTARTSONG ' Play intro melody.
  498.  
  499.     DO ' Wait for keypress to continue
  500.         kbd$ = UCASE$(INKEY$)
  501.     LOOP WHILE kbd$ = ""
  502.     IF kbd$ = "Q" THEN ' Allow player to quit now
  503.         CLS
  504.         LOCATE 10, 30: PRINT "Really quit? (Y/N)";
  505.         DO
  506.             kbd$ = UCASE$(INKEY$)
  507.         LOOP WHILE kbd$ = ""
  508.         IF kbd$ = "Y" THEN
  509.             CLS
  510.             END
  511.         END IF
  512.     END IF
  513.  
  514.    
  515.  
  516. '----------------------------------------------------------------------------
  517. ' EraseMissileTrail
  518. '
  519. '    Erases the trail of both enemy and interceptor missiles once
  520. '    they have exploded. This subprogram erases one of many
  521. '    possible missile trails temporarily stored in the Incoming() array.
  522. '
  523. '           PARAMETERS:     MNum - Missile line number to erase.
  524. '----------------------------------------------------------------------------
  525. SUB EraseMissileTrail (MNum)
  526.  
  527.     MaxCount = Incoming(MNum).MaxCount ' Set temporary variable to the number of moves in the primary direction made before a move in the secondary direction.
  528.     Count = MaxCount ' Temp variable that keeps track of how many times the trail has been followed since the last move in the secondary direction.
  529.     IF Incoming(MNum).YMajor THEN ' For best speed, use different routines for missiles that move mainly vertically (YMajor = TRUE) and those that move mainly horizontally (YMajor = FALSE).
  530.         x = Incoming(MNum).XStart ' Initial X position.
  531.         XOff = Incoming(MNum).XOffset ' Temp variable for the X offset.
  532.         FOR Y = Incoming(MNum).YStart TO Incoming(MNum).Y STEP SGN(Incoming(MNum).YOffset) ' Loop through all Y positions.
  533.             PSET (x, Y), GameBkGround ' Erase the dot.
  534.             Count = Count - RESOLUTION ' Decrease COUNT.  RESOLUTION controls how accurate this algorithm is (the higher the more accurate).
  535.             IF Count <= 0 THEN ' Don't move in the X direction until Y has moved enough for COUNT to drop to 0 or below.
  536.                 x = x + XOff ' Move in the X direction.
  537.                 Count = Count + MaxCount ' Reset counter.
  538.             END IF
  539.         NEXT
  540.     ELSE ' Missile moves more horizontally than vertically.
  541.         Y = Incoming(MNum).YStart ' Initial Y position.
  542.         YOff = Incoming(MNum).YOffset ' Temp variable for the Y offset.
  543.         FOR x = Incoming(MNum).XStart TO Incoming(MNum).x STEP SGN(Incoming(MNum).XOffset) ' Loop through all X positions.
  544.             PSET (x, Y), GameBkGround ' Erase the dot.
  545.             Count = Count - RESOLUTION ' Decrease COUNT.
  546.             IF Count <= 0 THEN ' Has trail moved enough in the X direction to move in the X direction?
  547.                 Y = Y + YOff ' Yes.  Move in the Y direction.
  548.                 Count = Count + MaxCount ' Reset counter.
  549.             END IF
  550.         NEXT
  551.     END IF
  552.  
  553.  
  554. '----------------------------------------------------------------------------
  555. ' Explode
  556. '
  557. '    Generates the explosion sound and set up an Explosion array
  558. '    element to use when drawing the visual explosion.
  559. '
  560. '       PARAMETERS:     MNum       - Missile number that caused the explosion.
  561. '                       WMissiles  - Type of missile being exploded (enemy or interceptor).
  562. '----------------------------------------------------------------------------
  563. SUB Explode (MNum, x, Y, WMissiles)
  564.     IF Incoming(MNum).Active <> TRUE THEN EXIT SUB ' Makes sure that the same missile is not exploded twice.
  565.     PLAY "MB" ' Play (M)usic in the (B)ackground.
  566.     SOUND 50, 2 ' Tone at 50 hertz for 2 clock ticks (clock tick = .054 seconds).
  567.     SOUND 40, 8 ' Tone at 40 hertz for 8 clock ticks.
  568.  
  569.     DO ' DO loop to determine the highest number of currently active explosions.
  570.         XNum = XNum + 1 ' Increase the counter.
  571.     LOOP UNTIL Explosion(XNum).Active = FALSE ' When this loop is done XNum will contain the number of a valid array offset to use for the new explosion.
  572.  
  573.     Explosion(XNum).Active = 1 ' Set the active status to 1.
  574.     Explosion(XNum).x = x ' Set X and Y values to the current incoming
  575.     Explosion(XNum).Y = Y '  missile's X and Y values.
  576.     Explosion(XNum).MissileNum = MNum ' Set to the missile number that was passed in as an argument.
  577.     Explosion(XNum).MType = WMissiles ' Set to the missile type that was passed in as an argument.
  578.     Incoming(MNum).Active = 2 ' Set the specific incoming missile's active status to 2.
  579.     NumExplosions = NumExplosions + 1 ' Increase the number of global explosions to add this one.
  580.     NextExplosion = TIMER ' Ensure explosion begins immediately.
  581.  
  582.  
  583. '----------------------------------------------------------------------------
  584. ' GameOver
  585. '
  586. '    Displays the full-screen explosion, read the GAME OVER
  587. '    messages, and display the score and statistics.
  588. '    Also asks the player if he/she wants to play again.
  589. '
  590. '                   PARAMETERS:     None
  591. '----------------------------------------------------------------------------
  592. SUB GameOver
  593.  
  594.     DIM MessageCount AS LONG ' Create the variables used for score, etc.
  595.     DIM MaxMessages AS LONG
  596.     DIM MaxScore AS LONG
  597.  
  598.     Keys FALSE ' Turn off the control keys.
  599.     PLAY GAMEOVERSONG ' Play the game end melody.
  600.     SOUND 38, 36 ' Tone at 38 hertz for 36 clock ticks.
  601.     FOR i = 1 TO XSCALE * .666 STEP 2 ' Draw an expanding explosion screen.
  602.         CIRCLE (XSCALE / 2, YSCALE / 2), i, ExplColor
  603.     NEXT i
  604.  
  605.     IF ScreenMode = 7 THEN
  606.         COLOR 15, ExplColor ' Display the ending score and wave for SCREEN 7.
  607.     ELSE
  608.         COLOR 0 ' Display for SCREEN 1.
  609.     END IF
  610.     LOCATE 1, 3: PRINT USING "Score: ###,###,###"; Score
  611.     LOCATE 1, ScreenWidth - 10: PRINT USING "Wave: ###"; Wave
  612.     OPEN "I", #1, "1QSPACE.SCO": INPUT #1, name$, Hscore: CLOSE #1
  613.     IF Score > Hscore THEN OPEN "O", #1, "1QSPACE.SCO": LOCATE 13, 1: PRINT " YOU HAVE BEATEN THE HIGH SCORE "
  614.     IF Score > Hscore THEN LOCATE 15, 1: INPUT "TYPE IN YOUR FIRST NAME"; name$: PRINT #1, name$: PRINT #1, Score: CLOSE #1: PRINT
  615.     IF Score > Hscore THEN LOCATE 13, 1: PRINT "                                   ": LOCATE 15, 1: PRINT "                                          "
  616.     IF Score > Hscore THEN LOCATE 15, 15: PRINT name$
  617.     IF Score > Hscore THEN LOCATE 18, 1: PRINT USING "HAS THE HIGH SCORE OF ###,###,###"; Score
  618.      
  619.    
  620.     LOCATE 3, 1
  621.     PRINT "Game statistics:" ' Print the player's game statistics.
  622.     LOCATE 5, 1
  623.     PRINT "Number of missiles destroyed:" + STR$(TotalIncoming)
  624.     LOCATE 7, 1
  625.     PRINT "Number of interceptors launched:" + STR$(TotalInterceptors)
  626.  
  627.     READ MaxMessages ' Read all the message choices from the DATA statements.
  628.  
  629.     DO ' DO loop to read the Rank$ and Message$ for display.  This loop will end when the MaxScore is greater than or equal to the player's Score.
  630.         READ Rank$, Message$ ' READ two elements from the next DATA statement.
  631.         MaxScore = MaxScore + 10000& + 20000& * MessageCount
  632.         MessageCount = MessageCount + 1 ' Increase message count.
  633.     LOOP WHILE MaxScore < Score AND MessageCount < MaxMessages
  634.     LOCATE 9, 1
  635.     PRINT Message$ ' Display Message$ in the center of line 15.
  636.     LOCATE 11, 1
  637.     PRINT "Rank:  " + Rank$, ' Display the matching rank on line 16.
  638.    
  639.     LOCATE 23, 1
  640.     PRINT "Would you like to try again? (Y/N)" ' Ask if player wants to play again.
  641.  
  642.     DO: LOOP UNTIL INKEY$ = "" ' Clears the keyboard input buffer.
  643.    
  644.     DO ' Wait for a 'y' or 'n' keypress.
  645.         A$ = UCASE$(INKEY$)
  646.     LOOP WHILE A$ <> "Y" AND A$ <> "N"
  647.  
  648.     IF A$ = "Y" THEN RUN "1qsapce" '  Player wants to start playing again.
  649.     IF A$ <> "Y" THEN ContinueGame = FALSE ' Player wants to end the game.
  650.    
  651.  
  652. '----------------------------------------------------------------------------
  653. ' HorizontalScroll
  654. '
  655. '    Displays a string moving across the screen at a given line.
  656. '    Assumes a 40 column display.
  657. '
  658. '                   PARAMETERS:     M$  - String to be displayed.
  659. '                                   Row - Screen row where string is displayed.
  660. '
  661. '----------------------------------------------------------------------------
  662. SUB HorizontalScroll (M$, Row)
  663.  
  664.     M$ = SPACE$(ScreenWidth + 2) + M$ ' Add ending spaces for display.
  665.     FOR i = 1 TO LEN(M$) - 1 ' Loop through the message in M$.
  666.         LOCATE Row, 1 ' Position the message on passed Row value.
  667.         PRINT MID$(M$, LEN(M$) - i, ScreenWidth - 1) ' Uses the MID$() function to print a ScreenWidth-1 character piece of the entire message.  The piece is determined by the value of X.
  668.         UpdateTarget ' Redraw the target crosshair in case the scrolling letters overwrite it.
  669.         Delay! = TIMER + .05 ' Delay the printing of each letter by .1 second.
  670.         DO WHILE TIMER < Delay!: LOOP
  671.     NEXT i
  672.  
  673.  
  674. '----------------------------------------------------------------------------
  675. ' InitFirebases
  676. '
  677. '    Draws two firebases at the lower left and right corners of the
  678. '    screen and fills them with color.
  679. '
  680. '                   PARAMETERS:     None
  681. '----------------------------------------------------------------------------
  682. SUB InitFirebases
  683.    
  684.     ' Draw the left missile launcher.
  685.     LINE (0, YSCALE - 6)-(10, YSCALE - 11), 14 ' Draw each side of the triangle.
  686.     LINE (0, YSCALE - 6)-(5, YSCALE - 1), 14
  687.     LINE (10, YSCALE - 11)-(5, YSCALE - 1), 14
  688.     PAINT (5, YSCALE - 6), 4, 14 ' Fill the triangle with color 4.
  689.    
  690.     ' Draw the right missile launcher.
  691.     LINE (XSCALE - 1, YSCALE - 6)-(XSCALE - 11, YSCALE - 11), 14
  692.     LINE (XSCALE - 11, YSCALE - 11)-(XSCALE - 6, YSCALE - 1), 14
  693.     LINE (XSCALE - 6, YSCALE - 1)-(XSCALE - 1, YSCALE - 6), 14
  694.     PAINT (XSCALE - 6, YSCALE - 6), 4, 14 ' Fill the triangle with color 4.
  695.  
  696.  
  697. '----------------------------------------------------------------------------
  698. ' InitScreen
  699. '
  700. '    Initializes the game. Clears the screen, draws the game pieces,
  701. '    and displays score and wave numbers.
  702. '
  703. '                   PARAMETERS:     None
  704. '----------------------------------------------------------------------------
  705. SUB InitScreen
  706.    
  707.     SCREEN 0 ' Clear the screen for each game.
  708.     SCREEN ScreenMode ' Change to the most appropriate screen mode.
  709.     SELECT CASE ScreenMode
  710.         CASE 7 ' Set colors for color screen.
  711.             PlanetColor = PLANETS7
  712.             EnemyColor = ENEMYCOLORS7
  713.             InterceptColor = INTERCEPTCOLORS7
  714.             ExplColor = EXPLCOLORS7
  715.             BaseColor = BASECOLORS7
  716.             GameBkGround = GAMEBKGROUNDS7
  717.             TargetColor = TARGETCOLORS7
  718.         CASE ELSE
  719.             PlanetColor = PLANETS1 ' Set colors for mono screen.
  720.             EnemyColor = ENEMYCOLORS1
  721.             InterceptColor = INTERCEPTCOLORS1
  722.             ExplColor = EXPLCOLORS1
  723.             BaseColor = BASECOLORS1
  724.             GameBkGround = GAMEBKGROUNDS1
  725.             TargetColor = TARGETCOLORS1
  726.     END SELECT
  727.    
  728.     COLOR , GameBkGround ' Change the background color.
  729.  
  730.     Target.x = XSCALE / 2 ' Setup first X position.
  731.     Target.Y = YSCALE / 2 + 5 ' Setup first Y position.
  732.     Target.OldX = Target.x ' Setup old target position as the current one.
  733.     Target.OldY = Target.Y
  734.     UpdateTarget ' Draw the initial target crosshair.
  735.  
  736.     DO: LOOP UNTIL INKEY$ = "" ' Clear keyboard input buffer.
  737.                        
  738.     UpdateScore ' Display the initial score and wave number.
  739.     ' Draw the planet edge here and fill the planet with PlanetColor.
  740.     CIRCLE (XSCALE / 2, YSCALE + 135), PLANETRADIUS, PlanetColor
  741.     PAINT (XSCALE / 2, YSCALE - 1), PlanetColor
  742.  
  743.  
  744. '----------------------------------------------------------------------------
  745. ' KeyPause
  746. '
  747. '    Suspends key event processing.  This is different than
  748. '    a KEY (X) OFF command because KEY (X) STOP stores key
  749. '    events and will fire them when KEY (X) ON is used.
  750. '
  751. '                   PARAMETERS:     None.
  752. '----------------------------------------------------------------------------
  753. SUB KeyPause
  754.     FOR i = 11 TO 20 ' Loop through all defined keys.
  755.         KEY(i) STOP
  756.     NEXT i
  757.  
  758. '----------------------------------------------------------------------------
  759. ' Keys
  760. '
  761. '    Turns key event processing on or off.
  762. '
  763. '      PARAMETERS:     TurnKeysOn - If it's TRUE then enable, otherwise
  764. '                      disable
  765. '----------------------------------------------------------------------------
  766. SUB Keys (TurnKeysOn)
  767.  
  768.     FOR i = 11 TO 20 ' Loop through all defined keys.
  769.         IF TurnKeysOn THEN
  770.             KEY(i) ON
  771.         ELSE
  772.             KEY(i) OFF
  773.         END IF
  774.     NEXT i
  775.  
  776.  
  777. '----------------------------------------------------------------------------
  778. ' LaunchMissile
  779. '
  780. '    Launches an interceptor or an enemy missile.
  781. '
  782. '     PARAMETERS:     Chosen  - Missile number to launch.
  783. '                     XStart  - X (horizontal) position of where the missile begins.
  784. '                     YStart  - Y (vertical) position of where the missile begins.
  785. '                     XFinish - X position of where the missile is aimed.
  786. '                     YFinish - Y position of where the missile is aimed.
  787. '----------------------------------------------------------------------------
  788. SUB LaunchMissile (Chosen, XStart, YStart, XFinish, YFinish)
  789.  
  790.     Incoming(Chosen).Active = TRUE ' Set the active status to TRUE.
  791.     Incoming(Chosen).XStart = XStart ' Set the initial X position.
  792.     Incoming(Chosen).YStart = YStart ' Set initial Y position.
  793.     Incoming(Chosen).XFinish = XFinish ' Set the missile's X
  794.     Incoming(Chosen).YFinish = YFinish '  and Y destination location.
  795.     Incoming(Chosen).x = XStart ' Set the missile's current X
  796.     Incoming(Chosen).Y = YStart '  and Y to the start.
  797.    
  798.     ' The code below determines which direction, either X or Y, is the
  799.     ' missile's primary direction.  Every time UpdateMissiles is called, the
  800.     ' missile will move in the primary direction.  MaxCount determines how many
  801.     ' primary moves are made before a secondary move is made but MaXCount is
  802.     ' not the actual number of moves since it is multiplied by RESOLUTION to
  803.     ' allow fast integer math to be used instead of slower floating-point.
  804.     ' Every time UpdateMissiles is called, Count is decreased by RESOLUTION.
  805.     ' When Count is less than 0, MaxCount added to Count and the missile moves
  806.     ' in the secondary direction.
  807.     XDistance = XFinish - XStart
  808.     YDistance = YFinish - YStart
  809.     Incoming(Chosen).XOffset = SGN(XDistance) ' Forces X and Y offsets that
  810.     Incoming(Chosen).YOffset = SGN(YDistance) '  are always -1, 0, or 1.
  811.  
  812.     IF ABS(XDistance) >= ABS(YDistance) THEN ' Missile moves more horizontally than vertically.
  813.         Incoming(Chosen).MaxCount = INT(ABS(XDistance) / (ABS(YDistance) + 1) * RESOLUTION) ' Determines how many horizontal moves to make before moving vertically.  RESOLUTION is used to round the value so fast integer math can be used.
  814.         Incoming(Chosen).YMajor = FALSE ' Sets flag to tell UpdateMissiles that primary direction is not Y.
  815.     ELSE ' Missile moves more vertically than horizontally.
  816.         Incoming(Chosen).MaxCount = INT(ABS(YDistance) / (ABS(XDistance) + 1) * RESOLUTION) ' Determines how many vertical moves to make before moving horizontally.
  817.         Incoming(Chosen).YMajor = TRUE ' Sets flag to tell UpdateMissiles that primary direction is Y.
  818.     END IF
  819.     Incoming(Chosen).Count = Incoming(Chosen).MaxCount ' Sets the number of times the missile has moved in the primary direction.
  820.  
  821. '----------------------------------------------------------------------------
  822. ' NewInterceptor
  823. '
  824. '    Determines if there is room for another interceptor, and if so,
  825. '    sets up another Incoming element and draw the crosshairs for a
  826. '    permanent target point.
  827. '
  828. '     PARAMETERS:     StartX - The X screen position to beginning of the missile trail.
  829. '                     StartY - The Y screen position to beginning of the missile trail.
  830. '----------------------------------------------------------------------------
  831. SUB NewInterceptor (StartX AS INTEGER, StartY AS INTEGER)
  832.  
  833.     IF NumIntercepts < 4 THEN ' Allow only 4 interceptor explosions on the screen at once.
  834.         NumIntercepts = NumIntercepts + 1 ' Increase total number of intercepts by one.
  835.         TotalInterceptors = TotalInterceptors + 1 ' Increase the number of total interceptors.
  836.      
  837.         Chosen = 7 ' Start at an offset of 7 because the Incoming array handles both enemy and player missiles.
  838.         DO UNTIL Incoming(Chosen).Active = FALSE ' DO loop to find the first unused Incoming element.
  839.             Chosen = Chosen + 1 ' Increase offset by one.
  840.         LOOP
  841.    
  842.         KeyPause ' Disable key event processing.
  843.         TargetX = Target.x ' Store the current crosshair x location
  844.         TargetY = Target.Y '  and y location, in case the crosshair moves while this subprogram is running.
  845.         Keys TRUE ' Enable key event processing.
  846.  
  847.         ' Draw the stationary crosshairs on the screen so we can see where the missile is heading.
  848.         LINE (TargetX - 5, TargetY - 5)-(TargetX + 5, TargetY + 5), TargetColor
  849.         LINE (TargetX + 5, TargetY - 5)-(TargetX - 5, TargetY + 5), TargetColor
  850.            
  851.         LaunchMissile Chosen, StartX, StartY, TargetX, TargetY
  852.     END IF
  853.  
  854.  
  855. '----------------------------------------------------------------------------
  856. ' NewMissile
  857. '
  858. '    Develops the boundaries and parameters for a new enemy missile
  859. '    to be fired. When completed, another enemy missile will be
  860. '    setup for drawing on the screen.
  861. '
  862. '           PARAMETERS:     None
  863. '----------------------------------------------------------------------------
  864. SUB NewMissile
  865.  
  866.     ' If WaveCount is more than the maximum enemy missile wave or ContinueGame isn't correct.
  867.     IF WaveCount = 10 + Wave * 2 OR ContinueGame <> TRUE THEN EXIT SUB
  868.      
  869.     WaveCount = WaveCount + 1 ' Increase WaveCount by one.
  870.     TotalIncoming = TotalIncoming + 1 ' Increase the total incoming count by one.
  871.     MissilesFlying = MissilesFlying + 1 ' Increase the count of missiles flying.
  872.    
  873.     DO ' DO loop to select which starbase is the target.
  874.         Targ = INT(RND(1) * MaxStarbases) + 1 ' Randomly select until we select one that is currently active.
  875.     LOOP UNTIL Starbase(Targ).Active = TRUE
  876.  
  877.     Chosen = 1 ' Select first available missile.
  878.     DO WHILE Incoming(Chosen).Active <> FALSE ' DO loop to determine the next available Incoming element.
  879.         Chosen = Chosen + 1 ' Increment offset by one.
  880.     LOOP
  881.  
  882.     XStart = INT(RND(1) * XSCALE - 1) + 1 ' Randomly select where to start.
  883.     YStart = 12
  884.     XFinish = Starbase(Targ).x ' Work variables to hold the selected starbase's X and Y position.
  885.     YFinish = Starbase(Targ).Y
  886.  
  887.     LaunchMissile Chosen, XStart, YStart, XFinish, YFinish
  888.  
  889.  
  890. '----------------------------------------------------------------------------
  891. ' NewStarbase
  892. '
  893. '    Determines a new starbase position and draws it in orbit around
  894. '    the planet.
  895. '
  896. '           PARAMETERS:     None
  897. '----------------------------------------------------------------------------
  898. SUB NewStarbase
  899.  
  900.     Chosen = 1 ' Setup initial starbase offset.
  901.     DO WHILE Starbase(Chosen).Active = TRUE ' DO until we find one that hasn't been initialized.
  902.         Chosen = Chosen + 1 ' Increase the offset by one.
  903.  
  904.     LOOP
  905.     BasesLeft = BasesLeft + 1 ' Increase the number of active bases by one.
  906.     DO ' DO loop to determine if the randomly chosen starbase is within range.
  907.         Angle! = RND(1) * 2 * PI ' Randomly select position along planet edge.
  908.         Y = SIN(Angle!) * PLANETRADIUS + YSCALE + 155 ' Set X and Y based on that angle.
  909.         x = COS(Angle!) * PLANETRADIUS + XSCALE / 2
  910.         TooClose = FALSE ' Assume that the new starbase is not too close to another one.
  911.  
  912.         FOR i = 1 TO MaxStarbases ' Loop to make sure there isn't a conflict with an existing starbase.
  913.             ' If starbase is close then set TooClose to TRUE.
  914.             IF ABS(Starbase(i).x - x) < 20 AND Starbase(i).Active = TRUE THEN TooClose = TRUE
  915.         NEXT i
  916.     LOOP WHILE Y > YSCALE - 11 OR TooClose = TRUE
  917.  
  918.     Starbase(Chosen).x = x ' Setup the chosen starbases X and Y coordinates.
  919.     Starbase(Chosen).Y = Y
  920.     Starbase(Chosen).Active = TRUE ' Set starbase active status to TRUE.
  921.     ' Draw the base in orbit around the planet.
  922.     CIRCLE (Starbase(Chosen).x, Starbase(Chosen).Y), 7, BaseColor, , , .3
  923.     PAINT (Starbase(Chosen).x, Starbase(Chosen).Y), BaseColor
  924.     LINE (Starbase(Chosen).x - XSCALE / FACTOR, Starbase(Chosen).Y - XSCALE / FACTOR)-(Starbase(Chosen).x + XSCALE / FACTOR, Starbase(Chosen).Y + XSCALE / FACTOR), 4, BF
  925.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y - 3), 14
  926.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y + 3), 14
  927.  
  928.  
  929. '----------------------------------------------------------------------------
  930. ' StopMissile
  931. '
  932. '    Stops the MNum missile and adjusts all global values that this
  933. '    operation affects.
  934. '
  935. '           PARAMETERS:     MNum      - Missile number to stop
  936. '                           WMissiles - Which type of missile: 1 = Incoming, 2 = Interceptor
  937. '----------------------------------------------------------------------------
  938. SUB StopMissile (MNum, WMissiles)
  939.  
  940.     EraseMissileTrail MNum ' Erase the given missile's trail.
  941.     Incoming(MNum).Active = FALSE ' Set incoming active status to FALSE.
  942.  
  943.     IF WMissiles = 1 THEN
  944.         UpdateScore ' Update the current score.
  945.         MissilesFlying = MissilesFlying - 1 ' Reduce the number of missiles currently flying.
  946.         ' If all of the enemy missiles for this wave have already flown, call WaveComplete subprogram.
  947.         IF WaveCount = 10 + 2 * Wave AND MissilesFlying = 0 THEN WaveComplete
  948.         NewMissile ' Start a new enemy missile flying.
  949.     ELSE
  950.         NumIntercepts = NumIntercepts - 1 ' Decrease the number of intercepted missiles.
  951.         XFinish = Incoming(MNum).XFinish ' Setup work variables for the finish point of the missile.
  952.         YFinish = Incoming(MNum).YFinish
  953.         ' Overwrite the target X with background.
  954.         LINE (XFinish - 5, YFinish - 5)-(XFinish + 5, YFinish + 5), GameBkGround
  955.         LINE (XFinish + 5, YFinish - 5)-(XFinish - 5, YFinish + 5), GameBkGround
  956.     END IF
  957.  
  958.  
  959. '----------------------------------------------------------------------------
  960. ' UpdateExplosions
  961. '
  962. '    Updates all currently active explosions in the Explosions array.
  963. '
  964. '           PARAMETERS:     None
  965. '----------------------------------------------------------------------------
  966. SUB UpdateExplosions
  967.  
  968.     FOR XNum = 1 TO 10 ' Loop for the number of possible concurrent explosions.
  969.         W = Explosion(XNum).Active ' Set work variable for active status of explosion element.
  970.         IF W > 0 THEN ' If this explosion is active.
  971.             x = Explosion(XNum).x ' Set work variables to explosion X and Y coordinates.
  972.             Y = Explosion(XNum).Y
  973.  
  974.             IF W > EXPLRADIUS THEN ' If explosion status (radius) is greater than the max radius.
  975.                 FOR T = 1 TO EXPLRADIUS ' Draw expanding circles with the background color to erase everything!
  976.                     CIRCLE (x, Y), T, GameBkGround
  977.                 NEXT T
  978.            
  979.                 ' Stop the missile that caused the explosion.
  980.                 StopMissile Explosion(XNum).MissileNum, Explosion(XNum).MType
  981.  
  982.                 FOR i = 1 TO MaxStarbases ' Loop through all starbases. If starbase is active and within the exploding missile's range, destroy starbase.
  983.                     IF Starbase(i).Active = TRUE AND ((x - Starbase(i).x) ^ 2 + (Y - Starbase(i).Y) ^ 2) ^ .5 - NEXPLRADIUS < -2 THEN DestroyStarbase i
  984.                 NEXT i
  985.          
  986.                 UpdateTarget ' Redraw the target crosshair.
  987.                 Explosion(XNum).Active = FALSE ' Set this explosion's active status to FALSE.
  988.             ELSE
  989.                 Explosion(XNum).Active = W + 1 ' Increase the status (radius) of current explosion.
  990.                 CIRCLE (x, Y), W, ExplColor ' Draw another circle to increase the explosion visually.
  991.                 UpdateTarget ' Redraw the target crosshair.
  992.             END IF
  993.         END IF
  994.     NEXT XNum
  995.  
  996.  
  997. '----------------------------------------------------------------------------
  998. ' UpdateMissiles
  999. '
  1000. '    Updates one of the two types of missiles by drawing the missile
  1001. '    one pixel more in its direction of travel.
  1002. '
  1003. '           PARAMETERS:     Start      - Where in the Incoming array to begin looking
  1004. '                           Finish     - Where to stop looking
  1005. '                           WMissiles  - Missile type to update (enemy or defense)
  1006. '                           NumOfTimes - Number of times to update the missiles
  1007. '                           ColorToUse - Color to use for the updated line
  1008. '
  1009. ' Note:  Start and Finish are not technically necessary since they can be
  1010. '        resolved from WMissiles.  Passing Start and Finish is faster than
  1011. '        determining them each time UpdateMissiles is called, however.
  1012. '----------------------------------------------------------------------------
  1013. SUB UpdateMissiles (Start, Finish, WMissiles, NumOfTimes, ColorToUse)
  1014.  
  1015.     FOR Chosen = Start TO Finish ' Loop through the possible missiles.
  1016.         IF Incoming(Chosen).Active = TRUE THEN ' If this incoming missile is active...
  1017.             x = Incoming(Chosen).x ' Use temporary local
  1018.             Y = Incoming(Chosen).Y '  variables for best speed.
  1019.             YOffset = Incoming(Chosen).YOffset
  1020.             XOffset = Incoming(Chosen).XOffset
  1021.             Count = Incoming(Chosen).Count
  1022.             MaxCount = Incoming(Chosen).MaxCount
  1023.             XFinish = Incoming(Chosen).XFinish
  1024.             YFinish = Incoming(Chosen).YFinish
  1025.        
  1026.             ' For maximum speed, use different routines for missiles that
  1027.             ' move mainly horizontally than for ones that move mainly
  1028.             ' vertically.
  1029.             IF Incoming(Chosen).YMajor THEN ' If missile is mainly vertical
  1030.                 FOR i = 1 TO NumOfTimes ' Do NumOfTimes
  1031.                     C = POINT(x, Y) ' Read the color of the point.
  1032.                     PSET (x, Y), ColorToUse ' Add a new point to the trail.
  1033.                     Count = Count - RESOLUTION ' Decrease the Count.
  1034.                     Y = Y + YOffset ' Move vertically.
  1035.            
  1036.                     IF Count <= 0 THEN ' Time for the horizontal move?
  1037.                         x = x + XOffset ' Yes.  Move horizontally.
  1038.                         Count = Count + MaxCount ' Prepare Count for the next horizontal movement.
  1039.                     END IF
  1040.            
  1041.                     ' Explode the missile if it hits another explosion, a base,
  1042.                     '  or reaches its target Y.
  1043.                     IF (C = ExplColor) OR (C = BaseColor) OR Y = YFinish THEN Explode Chosen, x, Y, WMissiles ' Explode the chosen missile given the current missile type
  1044.                 NEXT i
  1045.             ELSE ' Mainly horizontal
  1046.                 FOR i = 1 TO NumOfTimes ' Do NumOfTimes
  1047.                     C = POINT(x, Y) ' Read the color of the point.
  1048.                     PSET (x, Y), ColorToUse ' Add a new point to the trail.
  1049.                     Count = Count - RESOLUTION ' Decrease the Count.
  1050.                     x = x + XOffset ' Move horizontally.
  1051.            
  1052.                     IF Count <= 0 THEN ' Time for the vertical move?
  1053.                         Y = Y + YOffset ' Yes.  Move vertically.
  1054.                         Count = Count + MaxCount ' Prepare Count for the next vertical movement.
  1055.                     END IF
  1056.            
  1057.                     ' Explode the missile if it hits another explosion, a base,
  1058.                     '  or reaches its target X.
  1059.                     IF (C = ExplColor) OR (C = BaseColor) OR x = XFinish THEN Explode Chosen, x, Y, WMissiles '  Explode the chosen missile given the current missile type
  1060.                 NEXT i
  1061.             END IF
  1062.        
  1063.             ' Copy the temporary local variables back to the SHARED variables.
  1064.             Incoming(Chosen).Count = Count
  1065.             Incoming(Chosen).x = x
  1066.             Incoming(Chosen).Y = Y
  1067.        
  1068.         END IF
  1069.     NEXT Chosen
  1070.  
  1071.  
  1072. '----------------------------------------------------------------------------
  1073. ' UpdateScore
  1074. '
  1075. '    Calculates new score, then performs a formatted print of the
  1076. '    Score and Wave values.
  1077. '
  1078. '           PARAMETERS:     None
  1079. '----------------------------------------------------------------------------
  1080. SUB UpdateScore
  1081.  
  1082.     ' Calculate the new score.
  1083.     Score = Score + 10 * MissilesFlying * BasesLeft * Wave
  1084.  
  1085.     ' Locate and do a formatted print of the current score and wave numbers.
  1086.     LOCATE 1, 3: PRINT USING "Score: ###,###,###"; Score
  1087.     LOCATE 1, ScreenWidth - 10: PRINT USING "Wave: ###"; Wave
  1088.  
  1089.  
  1090. '----------------------------------------------------------------------------
  1091. ' UpdateTarget
  1092. '
  1093. '    Checks to see if the coordinates for the target are within the
  1094. '    boundaries and adjusts, if necessary.  Erases the old target
  1095. '    crosshair and draws the new target crosshair in its new
  1096. '    position.
  1097. '
  1098. '           PARAMETERS:     None
  1099. '----------------------------------------------------------------------------
  1100. SUB UpdateTarget
  1101.  
  1102.     ' If target goes off the screen horizontally, restore old horizontal position.
  1103.     IF Target.x > XSCALE - 5 OR Target.x < 5 THEN Target.x = Target.OldX
  1104.  
  1105.     ' Target cannot move above the SCORE line or below the top of the planet.
  1106.     IF Target.Y > YSCALE - 53 OR Target.Y < 15 THEN Target.Y = Target.OldY
  1107.  
  1108.     ' If the target is in a different position than when it was last updated.
  1109.     IF Target.x <> Target.OldX OR Target.Y <> Target.OldY THEN ' Erase the old target.
  1110.         LINE (Target.OldX, Target.OldY + 5)-(Target.OldX, Target.OldY - 5), 0
  1111.         LINE (Target.OldX - 5, Target.OldY)-(Target.OldX + 5, Target.OldY), 0
  1112.         Target.OldX = Target.x ' Make the old X and Y values equal to the current ones.
  1113.         Target.OldY = Target.Y
  1114.     END IF
  1115.  
  1116.     ' Draw new target crosshair in the new X and Y position.
  1117.     LINE (Target.x, Target.Y + 5)-(Target.x, Target.Y - 5), 14
  1118.     LINE (Target.x - 5, Target.Y)-(Target.x + 5, Target.Y), 14
  1119.  
  1120.  
  1121. '----------------------------------------------------------------------------
  1122. ' WaveComplete
  1123. '
  1124. '    Handles the screen output when a wave has been completed. Also
  1125. '    sets up information for the next wave.
  1126. '
  1127. '           PARAMETERS:     None
  1128. '----------------------------------------------------------------------------
  1129. SUB WaveComplete
  1130.    
  1131.     KEY(15) OFF ' Disable the Pause key.
  1132.     KEY(16) OFF ' Disable the Quit key.
  1133.    
  1134.     WaveCount = 0 ' Reset the WaveCount variable that holds home many missiles have been launched in the current wave.
  1135.     WaveInterceptCount = 0 ' Reset the counter for the number of interceptors launched in the wave.
  1136.     Score = Score + (Wave * 1000) ' Calculate bonus points.
  1137.     Wave = Wave + 1 ' Increment to the next wave.
  1138.     PLAY WAVEOVERSONG ' Play the wave-end melody.
  1139.  
  1140.     ' Move the Wave Over, etc. message across the screen.
  1141.     M$ = STR$(1000 * (Wave - 1)) + " point bonus!" + SPACE$(20) + "Wave" + STR$(Wave - 1) + " Complete!"
  1142.     HorizontalScroll M$, 10
  1143.     FOR XNum = 1 TO 10 ' Loop through the 10 possible explosions.
  1144.         IF Explosion(XNum).Active > 0 THEN ' If exploding now, explosion(mnum%).active will be greater than 0 (the radius of the explosion).
  1145.             x! = Explosion(XNum).x ' Get the X coordinate of the explosion.
  1146.             Y! = Explosion(XNum).Y ' Get the Y coordinate of the explosion.
  1147.        
  1148.             FOR T = 1 TO NEXPLRADIUS ' Draw expanding circles with the background color to erase everything.
  1149.                 CIRCLE (x!, Y!), T, GameBkGround
  1150.             NEXT T
  1151.        
  1152.             StopMissile Explosion(XNum).MissileNum, Explosion(XNum).MType
  1153.          
  1154.             FOR i = 1 TO MaxStarbases ' Loop through all starbases. If starbase is active and within the exploding missile's range, destroy starbase.
  1155.                 IF Starbase(i).Active = TRUE AND ((x! - Starbase(i).x) ^ 2 + (Y! - Starbase(i).Y) ^ 2) ^ .5 - NEXPLRADIUS < -2 THEN DestroyStarbase i
  1156.             NEXT i
  1157.      
  1158.             UpdateTarget ' Redraw the target crosshair.
  1159.             Explosion(XNum).Active = FALSE ' Reset the active flag so explosion can be re-used.
  1160.      
  1161.         END IF
  1162.     NEXT XNum
  1163.  
  1164.     FOR i = 1 TO 10 ' Loop through all missiles (both interceptor and enemy).
  1165.         IF Incoming(i).Active <> 0 THEN ' If it's flying or frozen,
  1166.             EraseMissileTrail i ' erase it.
  1167.             IF i > 6 THEN ' If it is an interceptor missile:
  1168.                 XFinish = Incoming(i).XFinish ' Store X coordinate of the missile's final target.
  1169.                 YFinish = Incoming(i).YFinish ' Get Y coordinate.
  1170.                 ' Erase the target at this line.
  1171.                 LINE (XFinish - 5, YFinish - 5)-(XFinish + 5, YFinish + 5), GamBkGround ' Erase the target X.
  1172.                 LINE (XFinish + 5, YFinish - 5)-(XFinish - 5, YFinish + 5), GameBkGround
  1173.             END IF
  1174.  
  1175.         END IF
  1176.         Incoming(i).Active = FALSE ' Reset the active flag so missile can be re-used.
  1177.     NEXT i
  1178.  
  1179.     ' If score is high enough score, add another starbase if there's room.
  1180.     IF Score > NextNewBase THEN
  1181.         ' Move the Wave Over, etc. message across the screen.
  1182.         M$ = STR$(10000 * Wave) + " Extra point bonus!"
  1183.         HorizontalScroll M$, 10
  1184.         Score = Score + (Wave * 10000) ' Calculate bonus points.
  1185.         NextNewBase = NextNewBase + 75000 ' Determine when next new starbase will possibly be awarded.
  1186.     END IF
  1187.     CLS
  1188.     ' Determine how to make the next wave more difficult.
  1189.     IF NumMissiles > 6 THEN NumMissiles = 6
  1190.     IF NumMissiles < 6 THEN NumMissiles = NumMissiles + 1 ' If an even number wave, increase the # of missiles unless the maximum (6) has already been reached.
  1191.     IncomingDelay = IncomingDelay * .66667 ' Otherwise, make the incoming missiles 33% faster unless already at maximum speed.
  1192.     IF IncomingDelay < FASTESTMISSILE THEN IncomingDelay = FASTESTMISSILE
  1193.  
  1194.  
  1195.     UpdateScore ' Show new score and wave.
  1196.  
  1197.     FOR i = 1 TO NumMissiles - 1 ' Create the new missiles (one more will be added by the StopMissile subprogram when WaveComplete is finished).
  1198.         NewMissile
  1199.     NEXT i
  1200.  
  1201.     NumIntercepts = 0 ' Reset the number of interceptors.
  1202.     NumExplosions = 0 ' Reset the number of explosions.
  1203.     LINE (1, MINY)-(XSCALE, YSCALE - 51), 0, BF ' Erase this area and cover with black.
  1204.    
  1205.     DO: LOOP UNTIL INKEY$ = "" ' Clear keyboard input buffer.
  1206.     Keys TRUE ' Enable key event processing.
  1207.  
  1208.     FOR GGG = 135 TO 165 'Redraw  planet
  1209.         CIRCLE (XSCALE / 2, YSCALE + GGG), PLANETRADIUS, PlanetColor
  1210.     NEXT GGG
  1211.  
  1212.     InitFirebases
  1213.     Chosen = 1 ' Setup initial starbase offset.
  1214.  
  1215.     ' Draw the base in orbit around the planet.
  1216.     CIRCLE (Starbase(Chosen).x, Starbase(Chosen).Y), 7, BaseColor, , , .3
  1217.     PAINT (Starbase(Chosen).x, Starbase(Chosen).Y), BaseColor
  1218.     LINE (Starbase(Chosen).x - XSCALE / FACTOR, Starbase(Chosen).Y - XSCALE / FACTOR)-(Starbase(Chosen).x + XSCALE / FACTOR, Starbase(Chosen).Y + XSCALE / FACTOR), 4, BF
  1219.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y - 3), 14
  1220.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y + 3), 14
  1221.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #10 on: September 04, 2019, 10:23:35 am »
http://qb64.org/wiki/$INCLUDE

This talks about BI and BM files

The BI files in QB45 use to setup to use INTERUPT or INTERUPTX for mouse data, your Q4T.BI probably had all the mouse routines. ( see attach ) They could be translated to QB64 if you can locate them.

QB64 way is in reply #1 from me.

  [ You are not allowed to view this attachment ]  
« Last Edit: September 04, 2019, 10:32:26 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #11 on: September 04, 2019, 10:39:06 am »
BTW you need a REM or ' before $INCLUDE, it's not commented out, it fakes out compiler to ignore that line.

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #12 on: September 04, 2019, 10:50:16 am »
THANKS THIS WORKS.
I last worked on this program in the 1990's so forget what I did
how can I speed it up - seems slow

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #13 on: September 04, 2019, 10:55:51 am »
Did Petr get your code fixed up?

Nah, Petr had first code, can't be that. What fixed it?
« Last Edit: September 04, 2019, 11:03:35 am by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #14 on: September 04, 2019, 11:02:21 am »
Hi BPlus, hi tuc47. It works fine for me (version which is posted here). For program speed.... the slowest statement you use is PAINT. Better maybe will be Steve's CircleFill. BPlus use it offten. :)