2 player one computer games

Started by
25 comments, last by Diodor 18 years, 6 months ago
havent tried on xp, but should work.

I dont suppose anyone will complain about saying downloading as it is so old now, and you probably owned it at one point.

try and download msdos 6? disks, and install on a virtual machine, or a old pc if you have it... or just try and search the disks for a compressed file I think it is, qbasic.ex_, or it could be expanded to .exe if it isnt run the expand comand. then try and find gorrilas or monkeys .vbs I think, not sure on extension.

I had so many fun hours playing that game! I tried throwing a bananna here, but was sadly disappointed when it didnt take a chunk out of a building or explode when touching someone!
>wilhil<
Advertisement
'QBASIC GORILLAS 2.1b3'Version 1.0 (c)1990 Microsoft Corp and/or IBM Corp'Version 2.* (c)1997-2005 Daniel Beardsmore'See http://telcontar.net/Misc/Gorillas/ for more information'Set default data type to integer for faster game playDEFINT A-Z'Sub DeclarationsDECLARE SUB restReal (t#)DECLARE SUB alertSnd ()DECLARE SUB LoadSettings ()DECLARE SUB Center (Row, Text$)DECLARE SUB DoBeep ()DECLARE SUB DoExplosion (x#, y#)DECLARE SUB DoSun (Mouth)DECLARE SUB DrawBan (xc#, yc#, r, bc)DECLARE SUB DrawGorilla (x, y, arms)DECLARE SUB ExplodeGorilla (x#, y#, PlayerHit)DECLARE SUB Extro ()DECLARE SUB GetInputs (player$(), NumGames, P)DECLARE SUB GorillaIntro (player$(), cIntro)DECLARE SUB Intro ()DECLARE SUB MakeCityScape (BCoor() AS ANY)DECLARE SUB PlaceGorillas (BCoor() AS ANY)DECLARE SUB rest (t#)DECLARE SUB SetScreen ()DECLARE SUB ShowPrompts (fieldNum AS INTEGER)DECLARE SUB Slidy ()DECLARE SUB SparklePause (opt AS INTEGER)DECLARE SUB Stats (Wins(), name$(), Ban!(), P, abortYN)DECLARE SUB VictoryDance (player)DECLARE FUNCTION CalcDelay# ()DECLARE FUNCTION DoShot (PlayerNum, x, y, turn, othX, othY)DECLARE FUNCTION GET$ (Row, Col, Prev$, Typ, Max, Esc)DECLARE FUNCTION PlayGame (player$(), NumGames, P)DECLARE FUNCTION PlotShot (StartX, StartY, angle#, velocity, PlayerNum, othX, othY)DECLARE FUNCTION Scl (N!)DECLARE FUNCTION WHEREX (num)DECLARE FUNCTION WHEREY (num)'Make all arrays Dynamic'$DYNAMIC' User-Defined TYPEsTYPE settings  useSound AS INTEGER  useOldExplosions AS INTEGER  newExplosionRadius AS INTEGER  useSlidingText AS INTEGER  defaultGravity AS INTEGER  defaultRoundQty AS INTEGER  showIntro AS INTEGEREND TYPETYPE XYPoint  XCoor AS INTEGER  YCoor AS INTEGEREND TYPETYPE PlayerData  PNam AS STRING * 17  Rounds AS INTEGER  Won AS INTEGER  Accu AS SINGLEEND TYPE' ConstantsCONST NPLAYERS = 20CONST TRUE = -1CONST FALSE = NOT TRUECONST HITSELF = 1CONST BACKATTR = 0CONST OBJECTCOLOR = 1CONST WINDOWCOLOR = 14CONST SUNHAPPY = FALSECONST SUNSHOCK = TRUECONST RIGHTUP = 1CONST LEFTUP = 2CONST ARMSDOWN = 3' Global VariablesDIM SHARED GSettings AS settingsDIM SHARED lastErrCodeDIM SHARED SLIDECONST AS LONGDIM SHARED GorillaX(1 TO 2)  'Location of the two gorillasDIM SHARED GorillaY(1 TO 2)DIM SHARED LastBuildingDIM SHARED pi#DIM SHARED LBan&(x), RBan&(x), UBan&(x), DBan&(x) 'Graphical picture of bananaDIM SHARED GorD&(120)        'Graphical picture of Gorilla arms downDIM SHARED GorL&(120)        'Gorilla left arm raisedDIM SHARED GorR&(120)        'Gorilla right arm raisedDIM SHARED GravityDIM SHARED WindDIM SHARED GLeftAngle#DIM SHARED GRightAngle#DIM SHARED GLeftVelocDIM SHARED GRightVeloc'Screen Mode VariablesDIM SHARED ScrHeightDIM SHARED ScrWidthDIM SHARED ModeDIM SHARED MaxCol' Screen Color VariablesDIM SHARED ExplosionColorDIM SHARED SUNATTRDIM SHARED BackColorDIM SHARED SunHtDIM SHARED GHeightDIM SHARED MachSpeed AS DOUBLEDIM SHARED PDefs(1 TO 2)DIM player$(1 TO 2)DIM SHARED PDat(1 TO NPLAYERS) AS PlayerDataDIM SHARED GamePlayedYNDIM SHARED DoesFileExistDIM NumGames ' Check for league table file, and load table entries DoesFileExist = 1 ON ERROR GOTO IsThereNoFile OPEN "GORILLAS.LGE" FOR INPUT AS #1 ON ERROR GOTO CorruptFile IF DoesFileExist = 1 THEN  INPUT #1, count  FOR l = 1 TO count   INPUT #1, PDat(l).PNam, PDat(l).Rounds, PDat(l).Won, PDat(l).Accu  NEXT  CLOSE #1  ON ERROR GOTO 0 ELSE  count = 0 END IF DEF FNRan (x) = INT(RND(1) * x) + 1 DEF SEG = 0                         ' Set NumLock to ON KeyFlags = PEEK(1047) IF (KeyFlags AND 32) = 0 THEN  POKE 1047, KeyFlags OR 32 END IF DEF SEG ' Initialisation and sliding text speed calculation GOSUB InitVars MachSpeed = CalcDelay IF MachSpeed < 1000 THEN  SLIDECONST = (4 * MachSpeed) - 1250  IF SLIDECONST < 0 THEN SLIDECONST = 0 ELSE  SLIDECONST = 2.929 * MachSpeed END IF ' Program outline LoadSettings Gravity = GSettings.defaultGravity NumGames = GSettings.defaultRoundQty ' Init screen SCREEN 0 WIDTH 80, 25 MaxCol = 80 COLOR 15, 0 CLS GamePlayed = 0 IF GSettings.showIntro THEN Intro more = 1: DO  GetInputs player$(), NumGames, count  GorillaIntro player$(), DoesFileExist  more = PlayGame(player$(), NumGames, count) LOOP UNTIL more = 0 Extro DEF SEG = 0                         ' Restore NumLock state POKE 1047, KeyFlags DEF SEG SYSTEM' Banana sprite definitionsCGABanana: 'BananaLeft DATA 327686, -252645316, 60 'BananaDown DATA 196618, -1057030081, 49344 'BananaUp DATA 196618, -1056980800, 63 'BananaRight DATA 327686,  1010580720, 240EGABanana: 'BananaLeft DATA 458758,202116096,471604224,943208448,943208448,943208448,471604224,202116096,0 'BananaDown DATA 262153, -2134835200, -2134802239, -2130771968, -2130738945,8323072, 8323199, 4063232, 4063294 'BananaUp DATA 262153, 4063232, 4063294, 8323072, 8323199, -2130771968, -2130738945, -2134835200,-2134802239 'BananaRight DATA 458758, -1061109760, -522133504, 1886416896, 1886416896, 1886416896,-522133504,-1061109760,0' Initialise graphics mode and spritesInitVars: pi# = 4 * ATN(1#) 'þ This is a clever way to pick the best graphics mode available ON ERROR GOTO ScreenModeError Mode = 9 SCREEN Mode ON ERROR GOTO PaletteError IF Mode = 9 THEN PALETTE 4, 0   'Check for 64K EGA ON ERROR GOTO 0 IF Mode = 1 THEN  PRINT "Sorry, but CGA is not currently supported. If you want to run Gorillas"  PRINT "in CGA then let me know, and I'll fix the program to support it."  PRINT : SYSTEM END IF IF Mode = 9 THEN  ScrWidth = 640  ScrHeight = 350  GHeight = 25  SUNATTR = 3  RESTORE EGABanana  REDIM LBan&(8), RBan&(8), UBan&(8), DBan&(8)  FOR i = 0 TO 8   READ LBan&(i)  NEXT i  FOR i = 0 TO 8   READ DBan&(i)  NEXT i  FOR i = 0 TO 8   READ UBan&(i)  NEXT i  FOR i = 0 TO 8   READ RBan&(i)  NEXT i  SunHt = 43 ELSE  ScrWidth = 320  ScrHeight = 200  GHeight = 12  SUNATTR = 3  RESTORE CGABanana  REDIM LBan&(2), RBan&(2), UBan&(2), DBan&(2)  REDIM GorL&(20), GorD&(20), GorR&(20)  FOR i = 0 TO 2   READ LBan&(i)  NEXT i  FOR i = 0 TO 2   READ DBan&(i)  NEXT i  FOR i = 0 TO 2   READ UBan&(i)  NEXT i  FOR i = 0 TO 2   READ RBan&(i)  NEXT i  MachSpeed = MachSpeed * 1.3  SunHt = 20 END IFRETURNFuckOff: lastErrCode = ERR RESUME NEXTScreenModeError:  IF Mode = 1 THEN    CLS    LOCATE 10, 5    PRINT "Sorry, you must have CGA, EGA color or VGA graphics to play Gorillas"    PRINT    SYSTEM  ELSE    Mode = 1    RESUME  END IFPaletteError:  Mode = 1            '64K EGA cards will run in CGA mode.  RESUME NEXT' Message displayed when league table absentIsThereNoFile: 'CLS 'BEEP 'PRINT "League table (GORILLAS.LGE) not found. A new league table file will" 'PRINT "be created after the first match. DON'T PANIC!" 'SLEEP 3 DoesFileExist = 0RESUME NEXTNoSaveStats: COLOR 7: CLS COLOR 12: PRINT "An error occurred trying to save the stats file GORILLAS.LGE" PRINT "The statistics have not been saved.": COLOR 7: PRINT CLOSESYSTEMCorruptFile: PRINT BEEP COLOR 12: PRINT "An error occurred while attempting to read data from the league" PRINT "table file, GORILLAS.LGE. Fix it, get it fixed, or delete it. Simple." COLOR 7: PRINTSYSTEM' Sliding text data storeSlidyText:DATA 6DATA "        Q B a s i c  G O R I L L A S  v2.1b3",15,1,4DATA "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ",7,-1,5DATA "DELUXE EDITION",15,1,6DATA "Original program (c)1990 Microsoft Corporation",4,1,10DATA "Gorillas Deluxe (c)1997-2005 Daniel Beardsmore",12,-1,12DATA "Dedicated to all the Gorillas and Gorillas Deluxe fans",2,1,16DATA 10DATA "INSTRUCTIONS",9,1,8DATA "Your mission is to hit your opponent with an exploding",11,1,10DATA "banana by varying the angle and power of your throw, taking",11,-1,11DATA "into account wind speed, gravity, and the city skyline.",11,1,12DATA "The wind speed is shown by a directional arrow at the bottom",11,-1,14DATA "of the playing field, its length relative to its strength.",11,1,15DATA "Zero degrees is horizontal, towards your opponent, with 90 degrees",11,-1,16DATA "being vertically upwards, and so on. Angles can be from 0 to",11,1,17DATA "360 degrees and velocity can range from 1 to 200.",11,-1,18DATA "Press any key to continue...",15,1,20PartingMessage:DATA 1DATA "Thank you for playing Gorillas!",11,1,8'Next number is the number of final phrasesDATA 5DATA 1,"May the Schwarz be with you!",14,-1,14DATA 1,"Live long and prosper.",14,-1,14DATA 1,"Goodbye!",14,-1,14DATA 1,"So long!",14,-1,14DATA 1,"Adios!",14,-1,14Ready:DATA 1,"Prepare for battle!",12,1,1Setup:DATA 1,"Game Setup",14,-1,1GameOver:DATA 1,"Game Over!",14,-1,3Aborted:DATA 1,"Game aborted",12,-1,3NowWhat:DATA 1,"Now What?",14,1,1VectorData:DATA 39DATA 0.582,0.988, 0.608,0.850, 0.663,0.788, 0.738,0.800DATA 0.863,0.838, 0.813,0.713, 0.819,0.650, 0.875,0.588DATA 1.000,0.563, 0.850,0.450, 0.825,0.400, 0.830,0.340DATA 0.925,0.238, 0.775,0.243, 0.694,0.225, 0.650,0.188, 0.630,0.105DATA 0.625,0.025, 0.535,0.150, 0.475,0.175, 0.425,0.150DATA 0.325,0.044, 0.325,0.150, 0.315,0.208, 0.288,0.250, 0.225,0.275DATA 0.053,0.288, 0.150,0.392, 0.175,0.463, 0.144,0.525DATA 0.025,0.638, 0.163,0.650, 0.225,0.693, 0.250,0.775DATA 0.225,0.905, 0.360,0.825, 0.450,0.823, 0.525,0.863DATA 0.582,0.988REM $STATICSUB alertSnd IF GSettings.useSound THEN PLAY ">>B10<<"END SUB'CalcDelay:'  Checks speed of the machine.FUNCTION CalcDelay#  s# = TIMER  DO    i# = i# + 1  LOOP UNTIL TIMER - s# >= .5  CalcDelay# = i#END FUNCTION' Center:'   Centers and prints a text string on a given row' Parameters:'   Row - screen row number'   Text$ - text to be printed'SUB Center (Row, Text$) Col = MaxCol \ 2 LOCATE Row, Col - (LEN(Text$) / 2) + 1 PRINT Text$;END SUBSUB DoBeep  IF GSettings.useSound THEN PLAY "O2A24"END SUB' DoExplosion:'   Produces explosion when a shot is fired' Parameters:'   x#, y# - location of explosion'SUB DoExplosion (x#, y#) DIM radii(1 TO 4, 1 TO 2), colors(1 TO 4)  IF GSettings.useOldExplosions THEN  IF GSettings.useSound THEN PLAY "MBO0L32EFGEFDC"  Radius = ScrHeight / 50  IF Mode = 9 THEN Inc# = .5 ELSE Inc# = .41  FOR c# = 0 TO Radius STEP Inc#    CIRCLE (x#, y#), c#, ExplosionColor  NEXT c#  FOR c# = Radius TO 0 STEP (-1 * Inc#)    CIRCLE (x#, y#), c#, BACKATTR    FOR i = 1 TO 100    NEXT i    rest .005  NEXT c# ELSE  radii(1, 1) = GSettings.newExplosionRadius  radii(2, 1) = .9 * radii(1, 1)  radii(3, 1) = .6 * radii(1, 1)  radii(4, 1) = .45 * radii(1, 1)  FOR i = 1 TO 4   radii(i, 2) = .825 * radii(i, 1)  NEXT  colors(1) = 4: colors(2) = 2  colors(3) = 3: colors(4) = 9    'þ Draw grey smoke  IF GSettings.useSound THEN PLAY "MBO0L32EFGEFDC"  CIRCLE (x#, y#), 1.175 * radii(1, 1), 10  PAINT (x#, y#), 10, 10  FOR i = 1 TO 4   Iwidth = 2 * radii(i, 1): Iheight = 2 * radii(i, 2)   locX = x# - radii(i, 1): locY = y# - radii(i, 2)   imageCol = colors(i)   IF MachSpeed > 700 THEN    GOSUB DrawShape    Delay = .5   ELSE    CIRCLE (x#, y#), radii(i, 1), imageCol: PAINT (x#, y#), imageCol, imageCol    Delay = .9   END IF  NEXT  timeStay! = TIMER: DO: LOOP UNTIL TIMER > timeStay! + .1 '.08  CIRCLE (x#, y#), 1.175 * radii(1, 1), 0  PAINT (x#, y#), 0, 0 END IFEXIT SUBDrawShape: RESTORE VectorData READ noOfPoints, initX!, initY! initX! = (initX! * Iwidth) + locX initY! = (initY! * Iheight) + locY FOR lVar = 1 TO noOfPoints - 1  READ toX!, toY!  toX! = (toX! * Iwidth) + locX  toY! = (toY! * Iheight) + locY  IF lVar = 1 THEN   LINE (initX!, initY!)-(toX!, toY!), imageCol  ELSE   LINE -(toX!, toY!), imageCol  END IF NEXT PAINT (locX + (Iwidth / 2), locY + (Iwidth / 2)), imageCol, imageColRETURNEND SUB' DoShot:'   Controls banana shots by accepting player input and plotting'   shot angle' Parameters:'   PlayerNum - Player'   x, y - Player's gorilla position'   turn - do not show zeroes at input prompts on first turn'FUNCTION DoShot (PlayerNum, x, y, turn, othX, othY)  'Input shot  IF PlayerNum = 1 THEN    LocateCol = 2  ELSE    IF Mode = 9 THEN      LocateCol = 67    ELSE      LocateCol = 26    END IF  END IF  IF PlayerNum = 1 THEN    PrevA# = GLeftAngle#: PrevV# = GLeftVeloc  ELSE    IF PlayerNum = 2 THEN      PrevA# = GRightAngle#: PrevV# = GRightVeloc    END IF  END IF  GAng$ = "": Velo$ = ""   LOCATE 2, LocateCol + 3: PRINT "Angle:";  LOCATE 3, LocateCol: PRINT "Velocity:";  IF turn > 2 THEN    PRINT PrevV#    Pa$ = LTRIM$(STR$(PrevA#))    Pv$ = LTRIM$(STR$(PrevV#))  ELSE    Pa$ = "": Pv$ = ""  END IF   WHILE INKEY$ <> "": WEND  DO: pass = 1   DO    GAng$ = GET$(2, LocateCol + 10, Pa$, 0, 360, 1)    IF GAng$ = "" THEN GOSUB AbortGame   LOOP UNTIL GAng$ <> ""   IF LEFT$(GAng$, 1) = "*" THEN GAng$ = RIGHT$(GAng$, LEN(GAng$) - 1)   angle# = VAL(GAng$)      'LOCATE 3, LocateCol   'PRINT "Velocity:";   DO    Velo$ = GET$(3, LocateCol + 10, Pv$, 1, -200, 1)    IF Velo$ = "" THEN GOSUB AbortGame   LOOP UNTIL Velo$ <> ""   IF LEFT$(Velo$, 1) = "*" THEN    pass = 0: Velo$ = RIGHT$(Velo$, LEN(Velo$) - 1)    PrevA# = angle#    PrevV# = CINT(VAL(Velo$))    Pa$ = GAng$    Pv$ = Velo$   END IF   velocity = CINT(VAL(Velo$))  LOOP UNTIL pass = 1  IF PlayerNum = 1 THEN   GLeftAngle# = angle#: GLeftVeloc = velocity  ELSE   IF PlayerNum = 2 THEN    GRightAngle# = angle#: GRightVeloc = velocity   END IF  END IF   IF PlayerNum = 2 THEN   angle# = 180 - angle#  END IF  'Erase input  FOR i = 1 TO 4   LOCATE i, 1   PRINT SPACE$(30 \ (80 \ MaxCol));   LOCATE i, (50 \ (80 \ MaxCol))   PRINT SPACE$(30 \ (80 \ MaxCol));  NEXT  PlayerHit = PlotShot(x, y, angle#, velocity, PlayerNum, othX, othY)  IF PlayerHit = 0 THEN   DoShot = FALSE  ELSE   DoShot = TRUE   IF PlayerHit <> PlayerNum AND turn < 3 THEN    'þ Killed opponent in one shot message    tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .8    IF GSettings.useSound THEN PLAY "MFO2L24A+>DFA+FD<A+>DFA+FD<A+>DFA+FD<A+4MB"    COLOR 12    FOR msg = 1 TO 3     Center 1, "IN ONE THROW!": tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .25     Center 1, SPACE$(14): GOSUB DSRestoreSun: tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .25    NEXT   ELSE tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .9   END IF   IF PlayerHit = PlayerNum THEN PlayerNum = 3 - PlayerNum   VictoryDance PlayerNum  END IFEXIT FUNCTIONAbortGame: cont = FALSE: cval = 1: tpause! = TIMER - 2 DO  IF TIMER > tpause! + .5 THEN   tpause! = TIMER   cval = 15 / cval: COLOR cval - 1: Center 1, " Abort game? [Y/N]"   IF cval = 1 THEN GOSUB DSRestoreSun  END IF  resp$ = UCASE$(INKEY$)  IF resp$ = "Y" THEN cont = 1  IF resp$ = "N" THEN cont = 2 LOOP UNTIL NOT (cont = FALSE) IF cont = 1 THEN  DoShot = 1: EXIT FUNCTION ELSE  IF cval = 15 THEN COLOR 1: Center 1, SPACE$(18)  DoSun SUNHAPPY: COLOR 15: RETURN END IFEXIT FUNCTIONDSRestoreSun: sunX = ScrWidth \ 2: sunY = Scl(25) LINE (sunX, sunY - Scl(15))-(sunX, sunY), SUNATTR LINE (sunX - Scl(8), sunY - Scl(13))-(sunX, sunY), SUNATTR LINE (sunX, sunY)-(sunX + Scl(8), sunY - Scl(13)), SUNATTRRETURNEND FUNCTION' DoSun:'   Draws the sun at the top of the screen.' Parameters:'   Mouth - If TRUE draws "O" mouth else draws a smile mouth.'SUB DoSun (Mouth)  'set position of sun  x = ScrWidth \ 2: y = Scl(25)  'clear old sun  LINE (x - Scl(22), y - Scl(18))-(x + Scl(22), y + Scl(18)), BACKATTR, BF  'draw new sun:  'body  CIRCLE (x, y), Scl(12), SUNATTR  PAINT (x, y), SUNATTR  'rays  LINE (x - Scl(20), y)-(x + Scl(20), y), SUNATTR  LINE (x, y - Scl(15))-(x, y + Scl(15)), SUNATTR  LINE (x - Scl(15), y - Scl(10))-(x + Scl(15), y + Scl(10)), SUNATTR  LINE (x - Scl(15), y + Scl(10))-(x + Scl(15), y - Scl(10)), SUNATTR  LINE (x - Scl(8), y - Scl(13))-(x + Scl(8), y + Scl(13)), SUNATTR  LINE (x - Scl(8), y + Scl(13))-(x + Scl(8), y - Scl(13)), SUNATTR  LINE (x - Scl(18), y - Scl(5))-(x + Scl(18), y + Scl(5)), SUNATTR  LINE (x - Scl(18), y + Scl(5))-(x + Scl(18), y - Scl(5)), SUNATTR  'mouth  IF Mouth THEN  'draw "o" mouth    CIRCLE (x, y + Scl(5)), Scl(2.9), 0    PAINT (x, y + Scl(5)), 0, 0  ELSE           'draw smile    CIRCLE (x, y), Scl(8), 0, (210 * pi# / 180), (330 * pi# / 180)  END IF  'eyes  CIRCLE (x - 3, y - 2), 1, 0  CIRCLE (x + 3, y - 2), 1, 0  PSET (x - 3, y - 2), 0  PSET (x + 3, y - 2), 0END SUB'DrawBan:'  Draws the banana'Parameters:'  xc# - Horizontal Coordinate'  yc# - Vertical Coordinate'  r - rotation position (0-3). (  \_/  ) /-'  bc - if TRUE then DrawBan draws the banana ELSE it erases the bananaSUB DrawBan (xc#, yc#, r, bc)SELECT CASE r  CASE 0    IF bc THEN PUT (xc#, yc#), LBan&, PSET ELSE PUT (xc#, yc#), LBan&, XOR  CASE 1    IF bc THEN PUT (xc#, yc#), UBan&, PSET ELSE PUT (xc#, yc#), UBan&, XOR  CASE 2    IF bc THEN PUT (xc#, yc#), DBan&, PSET ELSE PUT (xc#, yc#), DBan&, XOR  CASE 3    IF bc THEN PUT (xc#, yc#), RBan&, PSET ELSE PUT (xc#, yc#), RBan&, XOREND SELECTEND SUB'DrawGorilla:'  Draws the Gorilla in either CGA or EGA mode'  and saves the graphics data in an array.'Parameters:'  x - x coordinate of gorilla'  y - y coordinate of the gorilla'  arms - either Left up, Right up, or both downSUB DrawGorilla (x, y, arms)  DIM i AS SINGLE   ' Local index must be single precision  'draw head  LINE (x - Scl(4), y)-(x + Scl(2.9), y + Scl(6)), OBJECTCOLOR, BF  LINE (x - Scl(5), y + Scl(2))-(x + Scl(4), y + Scl(4)), OBJECTCOLOR, BF  'draw eyes/brow  LINE (x - Scl(3), y + Scl(2))-(x + Scl(2), y + Scl(2)), 0  'draw nose if ega  IF Mode = 9 THEN    FOR i = -2 TO -1      PSET (x + i, y + 4), 0      PSET (x + i + 3, y + 4), 0    NEXT i  END IF  'neck  LINE (x - Scl(3), y + Scl(7))-(x + Scl(2), y + Scl(7)), OBJECTCOLOR  'body  LINE (x - Scl(8), y + Scl(8))-(x + Scl(6.9), y + Scl(14)), OBJECTCOLOR, BF  LINE (x - Scl(6), y + Scl(15))-(x + Scl(4.9), y + Scl(20)), OBJECTCOLOR, BF  'legs  FOR i = 0 TO 4    CIRCLE (x + Scl(i), y + Scl(25)), Scl(10), OBJECTCOLOR, 3 * pi# / 4, 9 * pi# / 8    CIRCLE (x + Scl(-6) + Scl(i - .1), y + Scl(25)), Scl(10), OBJECTCOLOR, 15 * pi# / 8, pi# / 4  NEXT  'chest  CIRCLE (x - Scl(4.9), y + Scl(10)), Scl(4.9), 0, 3 * pi# / 2, 0  CIRCLE (x + Scl(4.9), y + Scl(10)), Scl(4.9), 0, pi#, 3 * pi# / 2  FOR i = -5 TO -1    SELECT CASE arms      CASE 1        'Right arm up        CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4        CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(4)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4        GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorR&      CASE 2        'Left arm up        CIRCLE (x + Scl(i - .1), y + Scl(4)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4        CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4        GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorL&      CASE 3        'Both arms down        CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4        CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4        GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorD&    END SELECT  NEXT iEND SUB'ExplodeGorilla:'  Causes gorilla explosion when a direct hit occurs'Parameters:'  X#, Y# - shot locationSUB ExplodeGorilla (x#, y#, PlayerHit)  YAdj = Scl(12)  XAdj = Scl(5)  SclX# = ScrWidth / 320  SclY# = ScrHeight / 200   IF GSettings.useSound THEN PLAY "MBO0L16EFGEFDC"' FOR i = 1 TO 8 * SclX#'   CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), i, ExplosionColor, , , -1.57'   'LINE (GorillaX(PlayerHit) + 7 * SclX#, GorillaY(PlayerHit) + 9 * SclY# - i)-(GorillaX(PlayerHit), GorillaY(PlayerHit) + 9 * SclY# - i), ExplosionColor' NEXT i  FOR i = 1 TO 16 * SclX#'   IF i < (8 * SclX#) THEN CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), (8 * SclX# + 1) - i, BACKATTR, , , -1.57    CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, i MOD 2 + 1, , , -1.57  NEXT i'  DO: LOOP UNTIL INKEY$ <> ""  FOR i = 24 * SclX# TO 1 STEP -1    CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, BACKATTR, , , -1.57    FOR count = 1 TO 200    NEXT  NEXT i END SUBSUB Extro RESTORE PartingMessage Slidy READ num num = CINT(RND * (num - 1)) IF num > 0 THEN FOR l = 1 TO num: READ pnum, pmsg$, pnum, pnum, pnum: NEXT Slidy t! = TIMER: DO: LOOP UNTIL TIMER > t! + 3.8 OR INKEY$ <> "" COLOR 7: CLSEND SUBFUNCTION GET$ (Row, Col, Prev$, Typ, Max, Esc) ' Row,Col : position ' Prev$ : the previous value of the number or string. ' Typ : the type of input required: TRUE for string, FALSE for numeric '       and 1 for numerical, tabbable while empty ' Max : the maximum number of characters for string or the maximum ' value for numeric. For numeric, a negative maximum means that the minimum ' value is to be one not zero and the maximum value is the absolute value ' of Max. ' Esc : TRUE if Escape key permitted, FALSE if not permitted, 1 if Escape ' clears input rather then undoes SpecTab = 0: IF Typ = 1 THEN Typ = FALSE: SpecTab = 1 IF NOT Typ THEN   IF Max < 0 THEN Zero = 0 ELSE Zero = -1   Max = ABS(Max) END IF Hold$ = Prev$ cont = 0: Lett$ = "": Curs = 0: Timo! = 0 Valid$ = "1234567890" + CHR$(8) + CHR$(9) + CHR$(13) + CHR$(27) IF Typ THEN Valid$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ- .'!" + Valid$ LOCATE Row, Col: IF Typ THEN   Bck = Max - LEN(Hold$) + 1 ELSE   Bck = LEN(STR$(Max)) - LEN(Hold$) END IF PRINT Hold$; SPC(Bck); DO   DO     Timo! = TIMER: Curs = 0: LOCATE Row, Col + LEN(Hold$): IF LEN(Hold$) = Max THEN PRINT "Û" ELSE PRINT "_"     DO: LOOP UNTIL INKEY$ = ""     DO       IF TIMER > Timo! + .5 THEN         LOCATE Row, Col + LEN(Hold$)         IF Curs <> 1 THEN          PRINT " "         ELSE          IF Typ AND LEN(Hold$) = Max THEN PRINT "Û" ELSE PRINT "_"         END IF         Curs = 1 - Curs         Timo! = TIMER       END IF       Lett$ = INKEY$     LOOP UNTIL Lett$ <> ""     LOCATE Row, Col + LEN(Hold$): PRINT " "     Intra = INSTR(Valid$, UCASE$(Lett$))     IF Lett$ = CHR$(0) + CHR$(83) THEN Intra = 50 ' DEL key     IF Intra = 0 THEN DoBeep: DO: LOOP UNTIL INKEY$ = ""   LOOP UNTIL Intra > 0   SELECT CASE Intra     CASE 50     'þ DELETE key       LOCATE Row, Col: PRINT STRING$(LEN(Hold$), " ");       Hold$ = ""     CASE 1 TO LEN(Valid$) - 4 'þ Letter, number or symbol     'þ Numeric field      IF NOT Typ THEN 'þ Number       IF NOT ((Lett$ = "0" AND (NOT Zero AND Hold$ = "")) OR Hold$ = "0") THEN        IF VAL(Hold$ + Lett$) <= Max THEN         Hold$ = Hold$ + Lett$         LOCATE Row, Col: PRINT Hold$        ELSE DoBeep        END IF       ELSE DoBeep       END IF      ELSE 'þ Text field       IF LEN(Hold$) < Max THEN        Hold$ = Hold$ + Lett$        LOCATE Row, Col: PRINT Hold$       ELSE DoBeep       END IF      END IF     CASE LEN(Valid$) - 3     'þ BACKSPACE key      IF LEN(Hold$) > 0 THEN       Hold$ = LEFT$(Hold$, LEN(Hold$) - 1)       LOCATE Row, Col: PRINT Hold$; " ";      ELSE DoBeep      END IF                             CASE LEN(Valid$) - 2     'þ TAB key       IF (LEN(Hold$) > 0 AND NOT Typ) OR SpecTab = 1 THEN Hold$ = "*" + Hold$: cont = 1 ELSE DoBeep     CASE LEN(Valid$) - 1     'þ RETURN key       IF LEN(Hold$) > 0 THEN cont = 1 ELSE DoBeep     CASE LEN(Valid$)     'þ ESCAPE key       IF Esc = TRUE THEN Hold$ = Prev$: cont = 1       IF Esc = 1 THEN Hold$ = "": cont = 1   END SELECT   DO: LOOP UNTIL INKEY$ = "" LOOP UNTIL cont = 1GET$ = Hold$END FUNCTION'GetInputs:'  Gets competing players and game configuration play at beginning of game'  and manages players list'Parameters:'  Player$() - player names'  NumGames - number of games to play'  P - number of stored playersSUB GetInputs (player$(), NumGames, P)' Lay out screen CLS : RESTORE Setup: Slidy: COLOR 2: LOCATE 2, 1: PRINT STRING$(80, "Í") 'þ Show screen title active = 0: FOR fld = 1 TO 4: GOSUB SetupFields: NEXT 'þ Display fields fld = 0: GOSUB SetupFields 'þ Display player names' Fill in players box cStat = 0: FOR N = 1 TO P: GOSUB Curs: NEXT 'þ Must highlight opponent player (normally done after [ENTER] or [TAB] IF PDefs(2) > 0 THEN N = PDefs(2): cStat = 2: GOSUB Curs' Process fields loop  ' complete: ready to start the game  ' fld: which field is being processed  ' numG$: text field to hold number of games  ' grav$: text field to hold gravity complete = 0: fld = 1: numG$ = LTRIM$(STR$(NumGames)): grav$ = LTRIM$(STR$(Gravity)) DO  'þ Highlight current field if there are enough players. Player field not  '  highlighted until there is a player which can be assigned to it, and the  '  last two fields are unselectable unless there are enough players  active = 1: IF P >= 2 THEN GOSUB SetupFields  SELECT CASE fld   CASE 1 TO 2    GOSUB ManagePlayers   CASE IS = 3    GOSUB Rounds   CASE IS = 4    GOSUB Gravity  END SELECT  active = 0: GOSUB SetupFields 'þ Unhighlight current field  IF NOT complete THEN fld = fld + 1: IF fld = 5 THEN fld = 1  IF complete AND (PDefs(1) = 0 OR PDefs(2) = 0) THEN fld = 1: complete = 0 LOOP UNTIL completeplayer$(1) = RTRIM$(PDat(PDefs(1)).PNam)player$(2) = RTRIM$(PDat(PDefs(2)).PNam)NumGames = VAL(numG$)Gravity = VAL(grav$)'þ Clear most of the screenCOLOR , 0: FOR l = 3 TO 24: LOCATE l, 1: PRINT STRING$(80, " "); : NEXTEXIT SUB'þþþþþþþþþþþþþþþþþþþþ'þ FIELDS SUBROUTINESManagePlayers: cre = 0 WHILE P < 2 'þ Ensure enough players for the game (only used before league table created)  cre = 1: GOSUB CreatePlayer  IF P = 2 THEN GOSUB SetupFields 'þ Finally ready to highlight Player field WEND cre = 0 'þ OK. Assuming that there are enough players to select. opp = 2 / fld 'þ PDefs array number of opposite player ShowPrompts fld IF PDefs(fld) > 0 THEN 'þ Put cursor bar on currently selected player  x = ((PDefs(fld) - 1) MOD 4) + 1: y = INT((PDefs(fld) - 1) / 4) + 1 ELSE                   'þ Otherwise choose free player  IF PDefs(opp) <> 1 THEN   x = 1: y = 1  ELSE   'IF PDefs(opp) = 1 AND P > 1 THEN   x = 2: y = 1  END IF END IF finished = 0: mov = 0: IF P > 1 THEN mov = 1 DO defSwap = 0 'þ Flag for player definition swapping  N = (y - 1) * 4 + x 'þ Convert cursor bar position into player number  LOCATE 8 + (fld * 2 - 2), 22  'þ Do not display player name if it is taken and swap is not permitted  IF NOT ((PDefs(fld) = 0 OR PDefs(opp) = 0) AND PDefs(opp) = N) THEN   COLOR 2, 0: PRINT PDat(N).PNam;  ELSE   COLOR 12, 0: PRINT "Can't have.      "  END IF  IF (PDefs(opp)) = N AND PDefs(fld) > 0 THEN   LOCATE 8 + (opp * 2 - 2), 23 + LEN(RTRIM$(PDat(PDefs(opp)).PNam))   COLOR 2, 0: PRINT "("; CHR$(26); " "; RTRIM$(PDat(PDefs(fld)).PNam); ")";   COLOR 2: LOCATE 7, 3: PRINT "": COLOR 9: LOCATE 7, 5   PRINT "Pressing [ENTER] now will switch the players over."   defSwap = 1  END IF  IF mov = 1 THEN cur = 1: GOSUB Move  DO   key$ = INKEY$  LOOP UNTIL key$ <> ""  COLOR 1, 0  IF defSwap = 1 THEN   LOCATE 8 + (opp * 2 - 2), 23 + LEN(RTRIM$(PDat(PDefs(opp)).PNam))   PRINT STRING$(21, " ")   LOCATE 7, 3: PRINT STRING$(52, " ")  END IF  'þ Move cursor bar, manipulate players, and select a player to compete  SELECT CASE UCASE$(key$)   CASE CHR$(0) + CHR$(72)    IF y > 1 THEN cur = 0: GOSUB Move: y = y - 1: mov = 1 ELSE alertSnd   CASE CHR$(0) + CHR$(80)    IF (y * 4 + x) <= P THEN cur = 0: GOSUB Move: y = y + 1: mov = 1 ELSE alertSnd   CASE CHR$(0) + CHR$(75)    IF x > 1 THEN     cur = 0: GOSUB Move: x = x - 1: mov = 1    ELSE     IF y > 1 THEN      cur = 0: GOSUB Move: mov = 1: x = 4: y = y - 1     ELSE      alertSnd     END IF    END IF   CASE CHR$(0) + CHR$(77)    IF x < 4 AND ((y - 1) * 4 + (x + 1)) <= P THEN     cur = 0: GOSUB Move: x = x + 1: mov = 1    ELSE     IF (y * 4 + 1) <= P THEN      cur = 0: GOSUB Move: mov = 1: x = 1: y = y + 1     ELSE      alertSnd     END IF    END IF   CASE CHR$(9), CHR$(13)    IF key$ = CHR$(13) THEN 'þ Only update player defs if ENTER pressed     IF PDefs(opp) = N AND PDefs(fld) > 0 THEN      'þ Swap player definitions      SWAP PDefs(1), PDefs(2): COLOR , 0: finished = 1      cStat = 2: GOSUB Curs      IF fld = 2 THEN N = PDefs(opp): GOSUB Curs     ELSEIF PDefs(opp) <> N THEN      'þ Define player      IF PDefs(fld) <> N THEN 'þ Remove green highlight and define PDefs       IF PDefs(fld) > 0 THEN Nt = N: N = PDefs(fld): cStat = 0: GOSUB Curs: N = Nt       PDefs(fld) = N      END IF      finished = 1      cStat = 2: GOSUB Curs     ELSE      alertSnd     END IF    ELSE     IF PDefs(fld) > 0 THEN      'þ Abort change to definition, and move to next field      finished = 1      cur = 0: GOSUB Move 'þ Remove cursor bar      N = PDefs(fld): cStat = 2: GOSUB Curs 'þ Red highlight     ELSEIF PDefs(fld) = 0 AND PDefs(opp) <> N THEN      'þ Player undefined, so define it      PDefs(fld) = N: finished = 1      cStat = 2: GOSUB Curs     ELSE      alertSnd     END IF    END IF    IF finished = 1 THEN     LOCATE 8 + (fld * 2 - 2), 22: COLOR 10, 0: PRINT PDat(PDefs(fld)).PNam;     IF defSwap = 1 THEN LOCATE 8 + (opp * 2 - 2), 22: PRINT PDat(PDefs(opp)).PNam;    END IF   CASE "N"    GOSUB CreatePlayer   CASE "R"    GOSUB RenamePlayer   CASE CHR$(0) + CHR$(83)    GOSUB DeletePlayer   CASE ELSE    'þ Incorrect key pressed    alertSnd  END SELECT 'Player chosen LOOP UNTIL finishedRETURN       CreatePlayer: IF P < NPLAYERS THEN  IF cre = 1 THEN ShowPrompts -12 ELSE ShowPrompts 12  nx = WHEREX(P + 1): ny = WHEREY(P + 1)  cStat = 0: GOSUB Curs: COLOR 10, 1  PDat(P + 1).PNam = " "  DO: cont = 1   IF P < 2 THEN Esc = FALSE ELSE Esc = TRUE 'þ Prevent ESCAPE key when players not yet created   PDat(P + 1).PNam = RTRIM$(GET$(ny, nx, RTRIM$(PDat(P + 1).PNam), -1, 17, Esc))     IF LTRIM$(PDat(P + 1).PNam) = "" THEN    cont = 2   ELSE    FOR inl = 1 TO P     IF PDat(inl).PNam = PDat(P + 1).PNam THEN alertSnd: cont = 0    NEXT   END IF  LOOP UNTIL cont > 0  IF cont = 1 THEN   P = P + 1: DoBeep: x = ((P - 1) MOD 4) + 1: y = INT((P - 1) / 4) + 1   IF P > 1 THEN N = P - 1: cur = 0: GOSUB Move   N = (y - 1) * 4 + x: cStat = 0: GOSUB Curs  ELSEIF cont = 2 THEN   Nt = N: N = P + 1: cStat = 0: GOSUB Curs   N = Nt: GOSUB Move  END IF  ShowPrompts fld ELSE  alertSnd END IFRETURNRenamePlayer: ShowPrompts 13 nx = WHEREX(P + 1): ny = WHEREY(P + 1) cStat = 0: GOSUB Curs: COLOR 10, 1 DO: cont = 1: count = 0  PDat(N).PNam = GET$(WHEREY(N), WHEREX(N), RTRIM$(PDat(N).PNam), -1, 17, TRUE)  IF LEFT$(PDat(N).PNam, 1) = "*" THEN PDat(N).PNam = RIGHT$(PDat(N).PNam, LEN(PDat(N).PNam) - 1)  FOR inl = 1 TO P   IF PDat(inl).PNam = PDat(N).PNam THEN count = count + 1  NEXT: IF count > 1 THEN alertSnd: cont = 0 LOOP UNTIL cont = 1: DoBeep cStat = 1: GOSUB Curs: ShowPrompts fld: upd = 0 IF PDefs(1) = N THEN  upd = 1 ELSEIF PDefs(2) = N THEN  upd = 2 END IF IF upd > 0 THEN  COLOR 10, 0: LOCATE 8 + (upd * 2 - 2), 22  PRINT PDat(PDefs(upd)).PNam; END IFRETURNDeletePlayer: 'þ What to do after the delete nextAction = 0 IF N = PDefs(opp) THEN 'þ Opposite player redefined  IF NOT (fld = 1 AND P > 2) THEN 'þ But not in this situation   nextAction = 1  END IF END IF IF PDefs(fld) > 0 THEN COLOR 10, 0: LOCATE 8 + (fld * 2 - 2), 22: PRINT PDat(PDefs(fld)).PNam; COLOR 0, 0 FOR l = 3 TO 7: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT ShowPrompts 11 LOCATE 3, 3: COLOR 4 PRINT "Do you want to delete the player `" + RTRIM$(PDat(N).PNam) + "'?" BEEP: DO: DO  i$ = INKEY$ LOOP UNTIL i$ <> "": i$ = UCASE$(i$): LOOP UNTIL i$ = "Y" OR i$ = "N" COLOR 0, 0: LOCATE 3: PRINT STRING$(80, " ") IF i$ = "Y" THEN  'þ Corrects PDefs (selected players) values and display  IF fld = 2 AND PDefs(fld) = 0 AND N = PDefs(opp) THEN   COLOR 8, 0: LOCATE 10, 22   PRINT "<undefined>      ";  END IF  FOR upd = 1 TO 2   IF PDefs(upd) = N THEN    COLOR 8, 0: LOCATE 8 + (upd * 2 - 2), 22    PRINT "<undefined>      ";    PDefs(upd) = 0   ELSEIF PDefs(upd) > N THEN    PDefs(upd) = PDefs(upd) - 1   END IF  NEXT   IF P = 2 AND PDefs(fld) = 0 AND PDefs(opp) > 0 THEN   COLOR 8, 0: LOCATE 8 + (fld * 2 - 2), 22   PRINT "<undefined>      ";  END IF   'þ Tidies up PDat (array of players)  Pt = P: P = P - 1: Nt = N  IF N < Pt THEN   FOR N = N TO P    PDat(N).PNam = PDat(N + 1).PNam    PDat(N).Rounds = PDat(N + 1).Rounds    PDat(N).Won = PDat(N + 1).Won    PDat(N).Accu = PDat(N + 1).Accu    IF PDefs(2 * (1 / fld)) = N THEN cStat = 2 ELSE cStat = 0    GOSUB Curs   NEXT  END IF  'þ This wipes all trace of the deleted player  PDat(Pt).Won = 0  PDat(Pt).PNam = "": PDat(Pt).Accu = 0: PDat(Pt).Rounds = 0       N = Pt: cStat = 0: GOSUB Curs  N = Nt  IF N > P THEN   N = N - 1: x = x - 1: IF x = 0 THEN x = 1: y = y - 1: IF y = 0 THEN y = 1  END IF  IF P > 0 THEN ShowPrompts fld   IF nextAction > 0 THEN   cStat = 0: GOSUB Curs 'þ Remove cursor bar  END IF  IF PDefs(fld) > 0 THEN   x = ((PDefs(fld) - 1) MOD 4) + 1: y = INT((PDefs(fld) - 1) / 4) + 1  ELSEIF N = PDefs(opp) THEN   IF N > 1 THEN    x = x - 1: IF x = 0 THEN y = y - 1: x = 4 'þ Back one player   ELSEIF N < P THEN    x = x + 1: IF x = 5 THEN y = y + 1: x = 1 'þ Fwd one player   END IF  END IF  IF nextAction = 1 THEN   active = 0: GOSUB SetupFields   SWAP fld, opp: active = 1: GOSUB SetupFields  END IF   'þ Ensure always 2 players minimum  IF P = 1 THEN cre = 1: GOSUB CreatePlayer: cre = 0 ELSE  ShowPrompts fld END IFRETURNRounds: ShowPrompts 3 COLOR 15, 9: numG$ = GET$(20, 51, numG$, 0, -99, FALSE): COLOR 15, 0 IF LEFT$(numG$, 1) = "*" THEN numG$ = RIGHT$(numG$, LEN(numG$) - 1) LOCATE 20, 51: PRINT numG$; SPC(3 - LEN(numG$));RETURNGravity: ShowPrompts 4 COLOR 15, 9: grav$ = GET$(22, 51, grav$, 0, -99, FALSE): COLOR 15, 0 IF LEFT$(grav$, 1) = "*" THEN grav$ = RIGHT$(grav$, LEN(grav$) - 1) ELSE complete = 1 LOCATE 22, 51: PRINT grav$; SPC(4 - LEN(grav$));RETURN'þþþþþþþþþþþþþþþþþþþþþ'þ SUPPORT SUBROUTINES' field displaySetupFields: IF fld = 1 AND active THEN GOSUB DrawBox IF fld = 2 AND NOT active THEN GOSUB DrawBox IF active THEN COLOR 15 ELSE COLOR 8 SELECT CASE fld  CASE IS = 0   FOR upd = 1 TO 2    LOCATE 8 + (upd * 2 - 2), 22    IF PDefs(upd) > 0 THEN     COLOR 10, 0: PRINT PDat(PDefs(upd)).PNam;    ELSE     COLOR 8, 0: PRINT "<undefined>"    END IF   NEXT  CASE IS = 1   LOCATE 8, 11: PRINT "Player 1 ="  CASE IS = 2   LOCATE 10, 11: PRINT "Player 2 ="  CASE IS = 3   tStr$ = "Maximum rounds? (1 - 99, Default =" + STR$(GSettings.defaultRoundQty) + "):"   LOCATE 20, 50 - LEN(tStr$): PRINT tStr$  CASE IS = 4   LOCATE 22, 13: PRINT "Gravity in m/sý (1 - 99, Earth = 10):" END SELECTRETURNDrawBox: COLOR 2, 0 IF active THEN  LOCATE 12, 1: PRINT "É"; STRING$(78, "Í"); "»";  LOCATE 18, 1: PRINT "È"; STRING$(78, "Í"); "¼";  FOR l = 13 TO 17: LOCATE l, 1: PRINT "º"; : LOCATE l, 80: PRINT "º"; : NEXT ELSE  LOCATE 12, 1: PRINT "Ú"; STRING$(78, "Ä"); "¿";  LOCATE 18, 1: PRINT "À"; STRING$(78, "Ä"); "Ù";  FOR l = 13 TO 17: LOCATE l, 1: PRINT "³"; : LOCATE l, 80: PRINT "³"; : NEXT END IFRETURN' cursor displayMove: 'þ Displays or removes cursor bar, calculating highlight colour which = 1 IF PDefs(2 / fld) = N THEN which = 0 IF PDefs(fld) = N THEN which = 2 SELECT CASE cur 'þ Blue (1) or black (0) background  CASE 1   IF which = 1 THEN    cStat = 1: GOSUB Curs   ELSEIF which = 0 THEN    cStat = 3: GOSUB Curs   ELSE    cStat = 5: GOSUB Curs   END IF  CASE 0   IF which = 1 THEN    cStat = 0: GOSUB Curs   ELSEIF which = 0 THEN    cStat = 2: GOSUB Curs   ELSE    cStat = 4: GOSUB Curs   END IF END SELECTRETURNCurs: 'þ Displays or removes cursor bar, being told the highlight colour SELECT CASE cStat  CASE 0   COLOR 15, 0  CASE 1   COLOR 11, 1  CASE 2   COLOR 4, 0  CASE 3   COLOR 4, 1  CASE 4   COLOR 2, 0  CASE 5   COLOR 2, 1 END SELECT LOCATE WHEREY(N), WHEREX(N): PRINT RTRIM$(PDat(N).PNam); IF N < P THEN  PRINT ","; ELSEIF N = P THEN  PRINT "."; ELSE  PRINT " "; END IF PRINT SPC(17 - LEN(RTRIM$(PDat(N).PNam)));RETURNEND SUB'GorillaIntro:'  Displays gorillas on screen for the first time'  allows the graphical data to be put into an array'Parameters:'  Player$() - The names of the players'  cIntro - Is introduction compulsory? (Yes for first ever game)'SUB GorillaIntro (player$(), cIntro)  IF cIntro = 1 THEN 'þ cIntro = 0 means introduction compulsory   LOCATE 1, 36: PRINT STRING$(10, " ")   RESTORE Ready: Slidy   COLOR 2: LOCATE 15, 31: PRINT "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ"   COLOR 9: LOCATE 17, 34: PRINT "= View Intro"   LOCATE 18, 34: PRINT "= Play Game"   LOCATE 19, 34: PRINT "= Quit Gorillas"   LOCATE 21, 34: PRINT "Your Choice?"   COLOR 12: LOCATE 17, 32: PRINT "V": LOCATE 18, 32: PRINT "P"   LOCATE 19, 32: PRINT "Q"   DO    Char$ = UCASE$(INKEY$)   LOOP UNTIL Char$ <> "" AND INSTR("QVP", Char$)   IF Char$ = "V" THEN cIntro = 0   IF Char$ = "Q" THEN    IF GamePlayedYN = 1 THEN Extro    COLOR 7: CLS : SYSTEM   END IF  END IF  IF Mode = 1 THEN    x = 125    y = 100  ELSE    x = 286    y = 175  END IF  SCREEN Mode  SetScreen  IF Mode = 1 THEN Center 5, "Please wait while gorillas are drawn."  VIEW PRINT 9 TO 24  IF Mode = 9 THEN PALETTE OBJECTCOLOR, BackColor   DrawGorilla x, y, ARMSDOWN  CLS 2  DrawGorilla x, y, LEFTUP  CLS 2  DrawGorilla x, y, RIGHTUP  CLS 2   VIEW PRINT 1 TO 25  IF Mode = 9 THEN PALETTE OBJECTCOLOR, 46   IF cIntro = 0 THEN    IF Mode = 9 THEN      Rad! = 100: yStep! = 1: DO        CIRCLE (319, 190), Rad!, 8, , , .5        CIRCLE (319, 187), Rad!, 11, , , .5        Rad! = Rad! + yStep!: yStep! = yStep! * 1.1      LOOP UNTIL 320 + Rad! >= 640      PAINT (0, 0), 8, 11      LINE (142, 20)-(491, 20), 3      LINE (491, 20)-(491, 95), 3      LINE (491, 95)-(317, 156), 3      LINE (317, 156)-(142, 95), 3      LINE (142, 95)-(142, 20), 3      PAINT (317, 40), 0, 3    END IF    COLOR 11: Center 2, " QBasic G O R I L L A S "    COLOR 9: Center 4, "STARRING:"    P$ = player$(1) + " AND " + player$(2)    COLOR 3: Center 5, STRING$(LEN(P$), "Ä")    COLOR 2: Center 6, P$: COLOR 9    PUT (x - 13, y), GorD&, PSET    PUT (x + 47, y), GorD&, PSET    rest 1    IF INKEY$ <> "" GOTO GetThisOverWith    PUT (x - 13, y), GorL&, PSET    PUT (x + 47, y), GorR&, PSET    IF GSettings.useSound THEN PLAY "t120o1l16b9n0baan0bn0bn0baaan0b9n0baan0b" ELSE restReal .18    rest .3    IF INKEY$ <> "" GOTO GetThisOverWith    PUT (x - 13, y), GorR&, PSET    PUT (x + 47, y), GorL&, PSET    IF GSettings.useSound THEN PLAY "o2l16e-9n0e-d-d-n0e-n0e-n0e-d-d-d-n0e-9n0e-d-d-n0e-" ELSE restReal .18    rest .3    IF INKEY$ <> "" GOTO GetThisOverWith    PUT (x - 13, y), GorL&, PSET    PUT (x + 47, y), GorR&, PSET    IF GSettings.useSound THEN PLAY "o2l16g-9n0g-een0g-n0g-n0g-eeen0g-9n0g-een0g-" ELSE restReal .18    rest .3    IF INKEY$ <> "" GOTO GetThisOverWith    PUT (x - 13, y), GorR&, PSET    PUT (x + 47, y), GorL&, PSET    IF GSettings.useSound THEN PLAY "o2l16b9n0baan0g-n0g-n0g-eeen0o1b9n0baan0b" ELSE restReal .18    rest .3    IF INKEY$ <> "" GOTO GetThisOverWith    FOR i = 1 TO 4      PUT (x - 13, y), GorL&, PSET      PUT (x + 47, y), GorR&, PSET      IF GSettings.useSound THEN PLAY "T160O0L32EFGEFDC" ELSE restReal .18      rest .1      PUT (x - 13, y), GorR&, PSET      PUT (x + 47, y), GorL&, PSET      IF GSettings.useSound THEN PLAY "T160O0L32EFGEFDC" ELSE restReal .18      rest .1      IF INKEY$ <> "" GOTO GetThisOverWith    NEXT    rest 1  END IFGetThisOverWith: ' Finally, the intro can be abortedEND SUB'Intro:'  Displays game introductionSUB Intro  IF GSettings.useSound THEN PLAY "MBT160O2" ' Initialise sound  WHILE INKEY$ <> "": WEND 'Clear keyboard buffer  RESTORE SlidyText  Slidy  SparklePause (3)  t$ = STRING$(80, " ")  FOR s = 5 TO 8: LOCATE s * 2, 1: PRINT t$; : NEXT  LOCATE 1, 1: PRINT t$: LOCATE 22, 1: PRINT t$  FOR s = 1 TO 22: LOCATE s, 1: PRINT " "; : LOCATE s, 80: PRINT " "; : NEXT  Slidy  SparklePause (0)   IF Mode = 1 THEN MaxCol = 40  END SUBSUB LoadSettingsDIM currLine$, eqPos, key$, value$, nBool 'þ set default settings GSettings.useSound = 1 GSettings.useOldExplosions = 0 GSettings.newExplosionRadius = 40 GSettings.useSlidingText = 0 '1 GSettings.defaultGravity = 17 GSettings.defaultRoundQty = 4 GSettings.showIntro = 1 lastErrCode = 0 ON ERROR GOTO FuckOff OPEN "GORILLAS.INI" FOR INPUT AS #1 IF lastErrCode > 0 THEN EXIT SUB WHILE NOT EOF(1)  LINE INPUT #1, currLine$  IF lastErrCode > 0 THEN CLOSE #1: EXIT SUB  GOSUB processLine WEND CLOSE #1 ON ERROR GOTO 0EXIT SUBprocessLine: eqPos = INSTR(currLine$, "=") IF eqPos = 0 THEN  RETURN END IF key$ = RTRIM$(LTRIM$(MID$(currLine$, 1, eqPos - 1))) value$ = RTRIM$(LTRIM$(RIGHT$(currLine$, LEN(currLine$) - eqPos))) SELECT CASE UCASE$(key$) CASE "USESOUND"  GOSUB getBool  IF nBool > -1 THEN GSettings.useSound = nBool CASE "USEOLDEXPLOSIONS"  GOSUB getBool  IF nBool > -1 THEN GSettings.useOldExplosions = nBool CASE "NEWEXPLOSIONRADIUS"  GSettings.newExplosionRadius = VAL(value$) CASE "USESLIDINGTEXT"  GOSUB getBool  IF nBool > -1 THEN GSettings.useSlidingText = nBool CASE "DEFAULTGRAVITY"  tVal = VAL(value$)  IF tVal > 0 AND tVal < 100 THEN GSettings.defaultGravity = tVal CASE "DEFAULTROUNDQTY"  tVal = VAL(value$)  IF tVal > 0 AND tVal < 100 THEN GSettings.defaultRoundQty = tVal CASE "SHOWINTRO"  GOSUB getBool  IF nBool > -1 THEN GSettings.showIntro = nBool END SELECT RETURNgetBool: IF UCASE$(value$) = "YES" OR value$ = "1" OR UCASE$(value$) = "TRUE" THEN  nBool = 1 ELSEIF UCASE$(value$) = "NO" OR value$ = "0" OR UCASE$(value$) = "FALSE" THEN  nBool = 0 ELSE  nBool = -1 END IF RETURNleave:END SUB'MakeCityScape:'  Creates random skyline for game'Parameters:'  BCoor() - a user-defined type array which stores the coordinates of'  the upper left corner of each building.SUB MakeCityScape (BCoor() AS XYPoint)  x = 2  'Set the sloping trend of the city scape. NewHt is new building height  Slope = FNRan(6)  SELECT CASE Slope    CASE 1: NewHt = 15                 'Upward slope    CASE 2: NewHt = 130                'Downward slope    CASE 3 TO 5: NewHt = 15            '"V" slope - most common    CASE 6: NewHt = 130                'Inverted "V" slope  END SELECT  IF Mode = 9 THEN    BottomLine = 335                   'Bottom of building    HtInc = 10                         'Increase value for new height    DefBWidth = 37                     'Default building height    RandomHeight = 120                 'Random height difference    WWidth = 3                         'Window width    WHeight = 6                        'Window height    WDifV = 15                         'Counter for window spacing - vertical    WDifh = 10                         'Counter for window spacing - horizontal  ELSE    BottomLine = 190    HtInc = 6    NewHt = NewHt * 20 \ 35            'Adjust for CGA    DefBWidth = 18    RandomHeight = 54    WWidth = 1    WHeight = 2    WDifV = 5    WDifh = 4  END IF  CurBuilding = 1  DO    SELECT CASE Slope      CASE 1        NewHt = NewHt + HtInc      CASE 2        NewHt = NewHt - HtInc      CASE 3 TO 5        IF x > ScrWidth \ 2 THEN          NewHt = NewHt - 2 * HtInc        ELSE          NewHt = NewHt + 2 * HtInc        END IF      CASE 4        IF x > ScrWidth \ 2 THEN          NewHt = NewHt + 2 * HtInc        ELSE          NewHt = NewHt - 2 * HtInc        END IF    END SELECT    'Set width of building and check to see if it would go off the screen    BWidth = FNRan(DefBWidth) + DefBWidth    IF x + BWidth > ScrWidth THEN BWidth = ScrWidth - x - 2    'Set height of building and check to see if it goes below screen    BHeight = FNRan(RandomHeight) + NewHt    IF BHeight < HtInc THEN BHeight = HtInc    'Check to see if Building is too high    IF BottomLine - BHeight <= MaxHeight + GHeight THEN BHeight = MaxHeight + GHeight - 5    'Set the coordinates of the building into the array    BCoor(CurBuilding).XCoor = x    BCoor(CurBuilding).YCoor = BottomLine - BHeight    IF Mode = 9 THEN BuildingColor = FNRan(3) + 4 ELSE BuildingColor = 2    'Draw the building, outline first, then filled    LINE (x - 1, BottomLine + 1)-(x + BWidth + 1, BottomLine - BHeight - 1), BACKGROUND, B    LINE (x, BottomLine)-(x + BWidth, BottomLine - BHeight), BuildingColor, BF    'Draw the windows    c = x + 3    DO      FOR i = BHeight - 3 TO 7 STEP -WDifV        IF Mode <> 9 THEN          WinColr = (FNRan(2) - 2) * -3        ELSEIF FNRan(4) = 1 THEN          WinColr = 8        ELSE          WinColr = WINDOWCOLOR        END IF        LINE (c, BottomLine - i)-(c + WWidth, BottomLine - i + WHeight), WinColr, BF      NEXT      c = c + WDifh    LOOP UNTIL c >= x + BWidth - 3    x = x + BWidth + 2    CurBuilding = CurBuilding + 1  LOOP UNTIL x > ScrWidth - HtInc  LastBuilding = CurBuilding - 1  'Set Wind speed  Wind = FNRan(10) - 5  IF FNRan(3) = 1 THEN    IF Wind > 0 THEN      Wind = Wind + FNRan(10)    ELSE      Wind = Wind - FNRan(10)    END IF  END IF  'Draw Wind speed arrow  IF Wind <> 0 THEN    WindLine = Wind * 3 * (ScrWidth \ 320)    LINE (ScrWidth \ 2, ScrHeight - 5)-(ScrWidth \ 2 + WindLine, ScrHeight - 5), ExplosionColor    IF Wind > 0 THEN ArrowDir = -2 ELSE ArrowDir = 2    LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 - 2), ExplosionColor    LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 + 2), ExplosionColor  END IFEND SUB'PlaceGorillas:'  PUTs the Gorillas on top of the buildings.  Must have drawn'  Gorillas first.'Parameters:'  BCoor() - user-defined TYPE array which stores upper left coordinates'  of each building.SUB PlaceGorillas (BCoor() AS XYPoint)      IF Mode = 9 THEN    XAdj = 14    YAdj = 30  ELSE    XAdj = 7    YAdj = 16  END IF  SclX# = ScrWidth / 320  SclY# = ScrHeight / 200      'Place gorillas on second or third building from edge  FOR i = 1 TO 2    IF i = 1 THEN BNum = FNRan(2) + 1 ELSE BNum = LastBuilding - FNRan(2)    BWidth = BCoor(BNum + 1).XCoor - BCoor(BNum).XCoor    GorillaX(i) = BCoor(BNum).XCoor + BWidth / 2 - XAdj    GorillaY(i) = BCoor(BNum).YCoor - YAdj    PUT (GorillaX(i), GorillaY(i)), GorD&, PSET  NEXT iEND SUB'PlayGame:'  Main game play routine'Parameters:'  Player$() - player names'  NumGames - number of games to playFUNCTION PlayGame (player$(), NumGames, P)  DIM BCoor(0 TO 30) AS XYPoint DIM minRounds DIM totalWins(1 TO 2) DIM avBan!(1 TO 2)                 ' mean accuracy DIM Throw(1 TO 2)                  ' throw counter DIM numHits(1 TO 2, 1 TO NumGames) ' number of throws needed to kill                                     '  opponent per win for each player J = 1 abortYN = FALSE minRounds = FIX(NumGames / 2) + 1 i = 1 DO  CLS  RANDOMIZE (TIMER)  CALL MakeCityScape(BCoor())  CALL PlaceGorillas(BCoor())  DoSun SUNHAPPY  GLeftAngle# = 0: GRightAngle# = 0  GLeftVeloc = 0: GRightVeloc = 0  Hit = FALSE: IF GSettings.useSound THEN PLAY "MBT160O1L8<G>CDEDCDL4ECC"  go = 1  DO WHILE Hit = FALSE   J = 1 - J   LOCATE 1, 2   IF Mode = 9 THEN COLOR 12   PRINT player$(1);   LOCATE 1, (MaxCol - LEN(player$(2)))   PRINT player$(2);   IF Mode = 9 THEN COLOR 9   Center 23, STR$(totalWins(1)) + " > Score < " + LTRIM$(STR$(totalWins(2)) + " ")   Tosser = J + 1: Tossee = 2 - J     'Plot the shot.  Hit is true if Gorilla gets hit.   Hit = DoShot(Tosser, GorillaX(Tosser), GorillaY(Tosser), go, GorillaX(Tossee), GorillaY(Tossee))   IF Hit = 1 THEN abortYN = TRUE: EXIT DO   'If the throw was fatal, Tosser now contains the player who WON     'If not hit self then increase number of hits   IF (J + 1) = Tosser THEN Throw(Tosser) = Throw(Tosser) + 1     IF Hit = TRUE THEN    'Update scores    totalWins(Tosser) = totalWins(Tosser) + 1    IF (J + 1) = Tosser THEN numHits(Tosser, totalWins(Tosser)) = Throw(Tosser)   END IF     go = go + 1   LOOP   IF abortYN THEN EXIT DO   Throw(1) = 0: Throw(2) = 0  SLEEP 1 i = i + 1 LOOP UNTIL i > NumGames OR totalWins(1) >= minRounds OR totalWins(2) >= minRounds 'þ If game played out then go through end game sequence IF NOT abortYN THEN  GamePlayedYN = 1  FOR l = 1 TO 2: Kills = 0  IF totalWins(l) > 0 THEN    FOR m = 1 TO totalWins(l)     IF numHits(l, m) > 0 THEN      avBan!(l) = avBan!(l) + numHits(l, m): Kills = Kills + 1     END IF    NEXT    IF avBan!(l) > 0 THEN avBan!(l) = avBan!(l) / Kills   END IF  NEXT END IF  SCREEN 0 WIDTH 80, 25 COLOR 7, 0 MaxCol = 80 CLS Stats totalWins(), player$(), avBan!(), P, abortYN CLS : RESTORE NowWhat: Slidy LOCATE 2, 1: COLOR 2: PRINT STRING$(80, "Í") LOCATE 4, 4: PRINT "Another game? [Y/N]"; DO  in$ = UCASE$(INKEY$) LOOP UNTIL in$ = "Y" OR in$ = "N" IF in$ = "Y" THEN PlayGame = 1 ELSE PlayGame = 0END FUNCTION'PlayGame:'  Plots banana shot across the screen'Parameters:'  StartX, StartY - starting shot location'  Angle - shot angle'  Velocity - shot velocity'  PlayerNum - the banana throwerFUNCTION PlotShot (StartX, StartY, angle#, velocity, PlayerNum, othX, othY)   angleChk = angle#: IF PlayerNum = 2 THEN angleChk = 180 - angleChk  angle# = angle# / 180 * pi#  'Convert degree angle to radians InitXVel# = COS(angle#) * velocity InitYVel# = SIN(angle#) * velocity oldx# = StartX oldy# = StartY ' draw gorilla toss IF PlayerNum = 1 THEN  PUT (StartX, StartY), GorL&, PSET ELSE  PUT (StartX, StartY), GorR&, PSET END IF ' throw sound IF GSettings.useSound THEN PLAY "MBO0L32A-L64CL16BL64A+" rest .1 ' redraw gorilla PUT (StartX, StartY), GorD&, PSET adjust = Scl(4)                   'For scaling CGA xedge = Scl(9) * (2 - PlayerNum)  'Find leading edge of banana for check Impact = FALSE SunHit = FALSE ShotInSun = FALSE OnScreen = TRUE 'þ FALSE if the banana is off side PlayerHit = 0 NeedErase = FALSE Bounced = FALSE 'þ Set up banana sound effect DoooMinVeloc = 40 pitch! = 9800 pitchDec! = 100 pitchDecDec! = (((InitYVel# - DoooMinVeloc) / (200 - DoooMinVeloc)) * 1.2) - .5  t2b# = 9999 'þ Used to store the time when the banana is to stop moving             '  when continuing off screen. 9999 means unused. StartXPos = StartX StartYPos = StartY - adjust - 3 IF PlayerNum = 2 THEN  StartXPos = StartXPos + Scl(25)  Direction = Scl(4) ELSE  Direction = Scl(-4) END IF IF velocity < 2 THEN              'Shot too slow - hit self  x# = StartX  y# = StartY  pointval = OBJECTCOLOR END IF  'þ Obtain predicted x-coordinate when banana reaches bottom of screen GOSUB PredictBottomOfScreen 'þ See if banana will overshoot (direction is +ve for left & -ve for right) 'þ MissedDist# is -ve for miss, and +ve for hit IF Direction > 0 THEN  MissedDist# = XPredicted# ELSE  MissedDist# = ScrWidth - XPredicted# END IF 'þ If shot is going backwards, then turns it into a miss IF SGN(Direction) = SGN(InitXVel#) THEN MissedDist# = 0 - MissedDist# DO WHILE (NOT Impact) AND OnScreen  rest .02  'Erase old banana, if necessary  IF NeedErase THEN    NeedErase = FALSE    CALL DrawBan(oldx#, oldy#, oldrot, FALSE)  END IF  x# = StartXPos + (InitXVel# * t#) + (.5 * (Wind / 5) * t# ^ 2)  y# = StartYPos + ((-1 * (InitYVel# * t#)) + (.5 * Gravity * t# ^ 2)) * (ScrHeight / 350)   IF y# > oldy# AND InitYVel# > DoooMinVeloc AND NOT Bounced AND MissedDist# > -175 THEN   'þ Play banana sound effect   IF GSettings.useSound THEN SOUND pitch!, 1   'þ Decrement banana sound effect pitch   IF (pitch! - pitchDec! >= 37) THEN    pitch! = pitch! - pitchDec!: pitchDec! = pitchDec! - pitchDecDec!   END IF  END IF    IF y# >= ScrHeight - 7 THEN   'þ If velocity is still high enough to bounce, and banana is on screen   IF InitYVel# > 2 AND t2b# = 9999 THEN    Bounced = TRUE    IF GSettings.useSound THEN PLAY "O4A64"    InitYVel# = SQR(InitYVel# ^ 2 - (2 * Gravity * (StartYPos - (ScrHeight - 7)))) * .4    StartXPos = x#    y# = ScrHeight - 7: StartYPos = y#    t# = 0   ELSE    'þ Terminate banana motion    OnScreen = FALSE    DoSun SUNHAPPY    IF t2b# = 9999 THEN 'þ Because its velocity ran out     IF GSettings.useSound THEN PLAY "O0A4"    ELSE 'þ Or because it bounced when off screen     IF SGN(Direction) <> SGN(InitXVel#) THEN GOSUB FailureMessage    END IF   END IF  END IF   'þ If banana leaves the screen  IF (x# >= ScrWidth - Scl(10)) OR (x# <= 3) THEN   'þ And banana will not return to the screen   IF (XPredicted# >= ScrWidth - Scl(10)) OR (XPredicted# <= 3) THEN    IF t# > t2b# THEN     OnScreen = FALSE     'þ Redraw sun as soon as poss     '  Ignore SunHit: bananas can still take pieces out of the sun unnoticed     DoSun SUNHAPPY     IF SGN(Direction) <> SGN(InitXVel#) THEN      GOSUB FailureMessage     END IF    ELSEIF t2b# = 9999 THEN     IF y# <= 0 THEN t2b# = t# + 1.5 ELSE t2b# = t# + 4    END IF   END IF  END IF  IF OnScreen AND y# > 0 AND (x# > 3 AND x# < (ScrWidth - Scl(10))) THEN   'check it   LookY = 0   LookX = Scl(8 * (2 - PlayerNum))      DO    pointval = POINT(x# + LookX, y# + LookY)    IF pointval = 0 THEN     Impact = FALSE     IF ShotInSun = TRUE THEN      IF ABS(ScrWidth \ 2 - x#) > Scl(20) OR y# > SunHt THEN ShotInSun = FALSE     END IF    ELSEIF pointval = SUNATTR AND y# < SunHt THEN     IF NOT SunHit THEN DoSun SUNSHOCK     SunHit = TRUE     ShotInSun = TRUE    ELSE     Impact = TRUE     DoSun SUNHAPPY    END IF    LookX = LookX + Direction    LookY = LookY + Scl(6)   LOOP UNTIL Impact OR LookX <> Scl(4)      IF NOT ShotInSun AND NOT Impact THEN    'plot it    rot = (t# * 10) MOD 4    CALL DrawBan(x#, y#, rot, TRUE)    NeedErase = TRUE   END IF              oldrot = rot  END IF   oldx# = x#  oldy# = y#  t# = t# + .1 LOOP IF pointval = OBJECTCOLOR THEN  IF x# < ScrWidth / 2 THEN PlayerHit = 1 ELSE PlayerHit = 2  IF PlayerHit = PlayerNum THEN COLOR 2: Center 1, "Now that was pretty dumb."  ExplodeGorilla x#, y#, PlayerHit  IF PlayerHit = PlayerNum THEN   tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .75   Center 1, SPACE$(25): GOSUB RestoreSun  END IF ELSEIF pointval <> OBJECTCOLOR AND Impact THEN  CALL DoExplosion(x# + adjust, y# + adjust)  'þ Reset values for shot's initial stage (before any bouncing)  InitXVel# = COS(angle#) * velocity  InitYVel# = SIN(angle#) * velocity  StartXPos = StartX: IF PlayerNum = 2 THEN StartXPos = StartXPos + Scl(25)  StartYPos = StartY - adjust - 3  GOSUB PredictReturnToHeight  'þ If shot went the right direction...  IF SGN(Direction) <> SGN(InitXVel#) THEN   'þ ...and if shot was too low powered:   IF (ABS(XPredicted# - StartX) < ABS((othX - StartX) / 3) AND angleChk > 60) OR ABS(XPredicted# - StartX) < ABS((othX - StartX) / 6) THEN    SELECT CASE FNRan(3)     CASE 1: Message$ = "Aren't your little muscles strong enough?"     CASE 2: Message$ = "Now that was feeble."     CASE 3: Message$ = "You can do better than that!"    END SELECT    IF GSettings.useSound THEN PLAY "MBO2L24BAGFEDCO1C2"    GOSUB DoMessage    GOSUB RestoreSun   END IF  END IF END IF 'redraw gorillas IF PlayerHit = 0 THEN  PUT (StartX, StartY), GorD&, PSET  PUT (othX, othY), GorD&, PSET END IF 'þ Message for backwards-tossed shot IF SGN(Direction) = SGN(InitXVel#) AND PlayerHit <> PlayerNum THEN  IF GSettings.useSound THEN PLAY "MBO1L24BAGFEDCO0C2"  Message$ = "You're not supposed to throw it that way."  GOSUB DoMessage  GOSUB RestoreSun END IF PlotShot = PlayerHitEXIT FUNCTION' When doing position calculation, don't forget -Gravity and Wind/5PredictReturnToHeight: ' Prediction of the banana's x-coordinate when it has come down to a level ' horizontally equal with the gorilla that fired it. t2# = (2 * InitYVel#) / Gravity XPredicted# = (InitXVel# * t2#) + (.5 * (Wind / 5) * t2# ^ 2) + StartXPos IF PlayerNum = 2 THEN XPredictedRet# = XPredictedRet# + Scl(25)RETURNPredictBottomOfScreen: ' Prediction of the x-coordinate of the shot when it reaches the bottom of ' the screen fallDist = StartYPos - (ScrHeight - 7) t2# = (-InitYVel# - SQR((InitYVel# ^ 2) + (2 * (-Gravity) * fallDist))) / (-Gravity) XPredicted# = (InitXVel# * t2#) + ((t2# ^ 2 * Wind) / 10) + StartXPos IF PlayerNum = 2 THEN XPredicted# = XPredicted# + Scl(25)RETURNFailureMessage: 'þ Select message based on distance beyond screen edge 'þ NOT calibrated for CGA GiveDist = 0 'þ Flag to indicate whether to show distance travelled 'þ If the player saw the banana leave the screen MissedDist# = ABS(MissedDist#) IF y# > 0 THEN  SELECT CASE MissedDist#   CASE 1 TO 155    SELECT CASE FNRan(2)     CASE 1: Message$ = "That went a wee bit far, didn't it?"     CASE 2: Message$ = "It seems you overdid that a little."    END SELECT   CASE 156 TO 640    SELECT CASE FNRan(4)     CASE 1: Message$ = "I think you need glasses."     CASE 2 TO 4: Message$ = "Hmmm...that wasn't good."    END SELECT   CASE 641 TO 1500: Message$ = "WHAT? That went MILES OFF!"   CASE IS > 1500    SELECT CASE FNRan(2)     CASE 1: Message$ = "WHAT ARE YOU PLAYING AT?"     CASE 2: Message$ = "Temper temper"    END SELECT  END SELECT ELSE  SELECT CASE MissedDist#   CASE 1 TO 155: Message$ = "A little nearer and you might stand a chance"   CASE 156 TO 640:    SELECT CASE FNRan(2)     CASE 1: Message$ = "Nope. That was too far off."     CASE 2: Message$ = CHR$(34) + "Hello? I'm over here!" + CHR$(34)    END SELECT   CASE 640 TO 1500    SELECT CASE FNRan(2)     CASE 1: Message$ = "Whoa! Go easy with it!"     CASE 2: Message$ = "You must be JOKING!"    END SELECT   CASE IS > 1500: Message$ = "You weren't supposed to put it into orbit."  END SELECT END IF IF GSettings.useSound THEN PLAY "MBO1L24BAGFEDCO0C2" COLOR 13 GOSUB DoMessage GOSUB RestoreSunRETURNDoMessage: COLOR 2 Center 1, Message$ tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + 2 Center 1, SPACE$(LEN(Message$))RETURNRestoreSun: sunX = ScrWidth \ 2: sunY = Scl(25) LINE (sunX, sunY - Scl(15))-(sunX, sunY), SUNATTR LINE (sunX - Scl(8), sunY - Scl(13))-(sunX, sunY), SUNATTR LINE (sunX, sunY)-(sunX + Scl(8), sunY - Scl(13)), SUNATTRRETURNEND FUNCTION'Rest:'  pauses the programSUB rest (t#)  s# = TIMER  t2# = 0  ' t2# = MachSpeed * t#' / SPEEDCONST  'þ Speed calibration disabled  DO  LOOP UNTIL TIMER - s# > t2#END SUBSUB restReal (t#)  s# = TIMER  DO  LOOP UNTIL TIMER - s# > t#END SUB'Scl:'  Pass the number in to scaling for cga.  If the number is a decimal, then we'  want to scale down for cga or scale up for ega.  This allows a full range'  of numbers to be generated for scaling.'  (i.e. for 3 to get scaled to 1, pass in 2.9)FUNCTION Scl (N!)  IF N! <> INT(N!) THEN      IF Mode = 1 THEN N! = N! - 1  END IF  IF Mode = 1 THEN      Scl = CINT(N! / 2 + .1)  ELSE      Scl = CINT(N!)  END IFEND FUNCTION'SetScreen:'  Sets the appropriate color statementsSUB SetScreen  IF Mode = 9 THEN    ExplosionColor = 2    BackColor = 1    PALETTE 0, 1    PALETTE 1, 46    PALETTE 2, 44    PALETTE 3, 54    PALETTE 5, 7    PALETTE 6, 4    PALETTE 7, 3    PALETTE 9, 63       'Display Color    PALETTE 10, 24    PALETTE 14, 55  ELSE    ExplosionColor = 2    BackColor = 0    COLOR BackColor, 2  END IFEND SUBSUB ShowPrompts (fieldNum) SELECT CASE fieldNum  CASE 1 TO 2   GOSUB pPlayers ' player list manipulation    CASE 11     GOSUB pDeletePlayer    CASE 12, -12     GOSUB pCreatePlayer    CASE 13     GOSUB pRenamePlayer  CASE 3   GOSUB pRounds  CASE 4   GOSUB pGravity END SELECTEXIT SUBpPlayers: COLOR , 0 FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT noOfDiams = 4: GOSUB Diamonds IF fieldNum = 1 THEN LOR$ = "LEFT" ELSE IF fieldNum = 2 THEN LOR$ = "RIGHT" COLOR 9: LOCATE 3, 5 PRINT "Use arrow keys to choose " + LOR$ + " HAND player and press [ENTER] to confirm." LOCATE 4, 5: PRINT "Type [N] to create a new player (up to 20 players)." LOCATE 5, 5: PRINT "Type [R] to rename a player." LOCATE 6, 5: PRINT "Type [DELETE] to delete a player."RETURNpDeletePlayer: noOfDiams = 3: GOSUB Diamonds LOCATE 4, 5: COLOR 9: PRINT "Press [Y] to delete the player, OR" LOCATE 5, 5: PRINT "Press [N] to cancel"RETURNpCreatePlayer: COLOR , 0 FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "): NEXT noOfDiams = 1: GOSUB Diamonds 'þ Used if the ESCAPE prompt is to be given IF fieldNum = 12 THEN LOCATE 6, 3: PRINT "" COLOR 9 LOCATE 3, 5: PRINT "Enter name of new player and press [ENTER] when done. You may as well" LOCATE 4, 5: PRINT "specify the player's full name as you only ever have to enter it" LOCATE 5, 5: PRINT "once." 'þ Signals whether ESCAPE can be pressed IF fieldNum = 12 THEN LOCATE 6, 5: PRINT "Or press [ESC] to cancel."RETURNpRenamePlayer: COLOR , 0 FOR l = 3 TO 6  LOCATE l, 1: PRINT STRING$(80, " ") NEXT noOfDiams = 3: GOSUB Diamonds: COLOR 9 LOCATE 3, 5: PRINT "Edit name of player and press [ENTER] when done." LOCATE 4, 5: PRINT "Pressing [DELETE] will clear the name field." LOCATE 5, 5: PRINT "Press [ESC] if you want to undo the changes."RETURN'pRounds: COLOR , 0 FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT noOfDiams = 1: GOSUB Diamonds COLOR 9 LOCATE 3, 5: PRINT "Enter input and press [ENTER] for the next field."RETURNpGravity: noOfDiams = 2: GOSUB Diamonds COLOR 9 LOCATE 3, 5: PRINT "Enter input and press [ENTER] to finish and play the game." LOCATE 4, 5: PRINT "Or press [TAB] to return to the first entry." LOCATE 6, 5: PRINT "Competition gravity is 17 m/sý."RETURN'Diamonds: COLOR 2 FOR l = 3 TO (3 + (noOfDiams - 1))  LOCATE l, 3: PRINT "" NEXTRETURNEND SUBSUB Slidy DIM q AS LONG READ N DIM t$(1 TO N): DIM i(1 TO N, 1 TO 3) FOR l = 1 TO N   READ P$: x = 40 - LEN(P$) / 2   P$ = STRING$(x, " ") + P$ + STRING$(x, " ")   READ i(l, 1), i(l, 2), i(l, 3)   t$(l) = P$ NEXT IF GSettings.useSlidingText THEN  FOR la = 1 TO 80   FOR lb = 1 TO N    IF i(lb, 2) < 0 THEN      P$ = LEFT$(t$(lb), la): x = 81 - la    ELSE      P$ = RIGHT$(t$(lb), la): x = 1    END IF    LOCATE i(lb, 3), x: COLOR i(lb, 1): PRINT P$;   NEXT   FOR q = 1 TO SLIDECONST: NEXT  NEXT ELSE  FOR lb = 1 TO N   LOCATE i(lb, 3), 1: COLOR i(lb, 1): PRINT t$(lb)  NEXT END IFEND SUB'SparklePause:'  Creates flashing border for intro and statistics screensSUB SparklePause (opt AS INTEGER)       DO: LOOP UNTIL INKEY$ = "" 'þ Clear keyboard buffer COLOR 12, 0 a$ = "*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    " t! = TIMER DO   FOR a = 1 TO 5     t1! = TIMER: DO: LOOP UNTIL TIMER > t1! + .001     LOCATE 1, 1                             'print horizontal sparkles     PRINT MID$(a$, a, 80);     LOCATE 22, 1     PRINT MID$(a$, 6 - a, 80);     FOR b = 2 TO 21                         'Print Vertical sparkles       c = (a + b) MOD 5       IF c = 1 THEN         LOCATE b, 80         PRINT "*";         LOCATE 23 - b, 1         PRINT "*";       ELSE         LOCATE b, 80         PRINT " ";         LOCATE 23 - b, 1         PRINT " ";       END IF     NEXT b   NEXT a LOOP UNTIL INKEY$ <> "" OR (opt > 0 AND TIMER > t! + opt)END SUBSUB Stats (Wins(), nam$(), Ban!(), P, abortYN) IF abortYN THEN  RESTORE Aborted: Slidy  LOCATE 4, 3: COLOR 2: PRINT STRING$(76, "Í") ELSE  'þ Update and sort the league table  RESTORE GameOver: Slidy  LOCATE 4, 3: COLOR 2: PRINT STRING$(76, "Í")  FOR l = 1 TO 2   PDat(PDefs(l)).Rounds = PDat(PDefs(l)).Rounds + Wins(1) + Wins(2)   PDat(PDefs(l)).Won = PDat(PDefs(l)).Won + Wins(l)   IF Ban!(l) > 0 THEN    IF PDat(PDefs(l)).Accu > 0 THEN     PDat(PDefs(l)).Accu = CINT(((PDat(PDefs(l)).Accu + Ban!(l)) / 2) * 10) / 10    ELSE     PDat(PDefs(l)).Accu = CINT(Ban!(l) * 10) / 10    END IF   END IF  NEXT    'þ routine to sort the player list  DO   complete = 1: tempW1 = 0: tempW2 = 0   FOR l = 1 TO P - 1    IF PDat(l).Rounds > 0 THEN tempW1 = (PDat(l).Won / PDat(l).Rounds * 100)    IF PDat(l + 1).Rounds > 0 THEN tempW2 = (PDat(l + 1).Won / PDat(l + 1).Rounds * 100)    IF (tempW1 < tempW2) OR (tempW1 = tempW2 AND PDat(l).Accu > PDat(l + 1).Accu) THEN     SWAP PDat(l).PNam, PDat(l + 1).PNam     SWAP PDat(l).Rounds, PDat(l + 1).Rounds     SWAP PDat(l).Won, PDat(l + 1).Won     SWAP PDat(l).Accu, PDat(l + 1).Accu     FOR PDl = 1 TO 2      IF PDefs(PDl) = l THEN       PDefs(PDl) = PDefs(PDl) + 1      ELSEIF PDefs(PDl) = l + 1 THEN       PDefs(PDl) = PDefs(PDl) - 1      END IF     NEXT         complete = 0    END IF   NEXT  LOOP UNTIL complete   FOR l = 1 TO 2   IF Wins(1) <> Wins(2) THEN    D = (Wins(l) >= Wins(2 / l))    COLOR (D + 2) * 2: LOCATE 6 + D, 7   ELSE    COLOR 9: LOCATE 4 + l, 7   END IF   PRINT nam$(l); " "; STRING$(20 - LEN(nam$(l)), "Ä"); ""; Wins(l);   IF (Wins(1) <> Wins(2)) THEN     IF D = -1 THEN PRINT CHR$(27); "ÄÄÄÄ Winner!";   ELSEIF l = 1 THEN    PRINT "   (The game was a draw)";   END IF   posn = 0: DO: posn = posn + 1: LOOP UNTIL nam$(l) = RTRIM$(PDat(posn).PNam)   IF posn > 10 THEN PRINT TAB(54); "(position"; RTRIM$(STR$(posn)); "th)"  NEXT END IF  'þ Show league table no matter what LOCATE 8, 20: COLOR 9: PRINT "STATISTICS"; LOCATE 9, 3: COLOR 2: PRINT "Ú"; STRING$(74, "Ä"); "¿"; FOR l = 10 TO 20: LOCATE l, 3: PRINT "³"; TAB(78); "³"; : NEXT LOCATE 21, 3: PRINT "À"; STRING$(74, "Ä"); "Ù"; COLOR 3 LOCATE 9, 5:  PRINT "Place"; LOCATE 9, 12: PRINT "Player"; LOCATE 9, 32: PRINT "Rounds"; LOCATE 9, 54: PRINT "Mean Accuracy"; LOCATE 9, 40: PRINT "Won"; COLOR 5: IF P > 9 THEN lim = 10 ELSE lim = P FOR l = 1 TO lim  LOCATE l + 10, 6:  IF (PDefs(1) = l OR PDefs(2) = l) AND NOT abortYN THEN COLOR 11 ELSE COLOR 5  IF l < 10 THEN PRINT "0";  PRINT LTRIM$(STR$(l)); " ÄÄ "; TAB(12); PDat(l).PNam  COLOR 5: LOCATE l + 10, 31: PRINT PDat(l).Rounds; TAB(39); PDat(l).Won; TAB(45);  IF PDat(l).Rounds = 0 THEN   PRINT "-"; TAB(53);  ELSE   IF (PDefs(1) = l OR PDefs(2) = l) AND NOT abortYN THEN COLOR 11 ELSE COLOR 13   PRINT ; "("; LTRIM$(RTRIM$(STR$(CINT(PDat(l).Won / PDat(l).Rounds * 100)))); "%)"; TAB(53);  END IF  COLOR 5  IF PDat(l).Accu = 0 THEN   PRINT ; " -"  ELSE   PRINT ; PDat(l).Accu;   IF PDat(l).Accu > 1! THEN PRINT "bananas" ELSE PRINT "banana"  END IF NEXT 'þ Only save stats if they have changed or if file absent IF NOT abortYN OR DoesFileExist = 0 THEN  COLOR 5: LOCATE 24, 3: PRINT "Saving stats...";  ON ERROR GOTO NoSaveStats  IF DoesFileExist = 1 THEN KILL "GORILLAS.LGE"  OPEN "GORILLAS.LGE" FOR OUTPUT AS #1  PRINT #1, P  FOR l = 1 TO P   PRINT #1, PDat(l).PNam   PRINT #1, PDat(l).Rounds, PDat(l).Won, PDat(l).Accu  NEXT  CLOSE #1  DoesFileExist = 1 END IF COLOR 15: LOCATE 24, 3: PRINT "Press a key... "; SparklePause (0)END SUB'VictoryDance:'  gorilla dances after he has eliminated his opponent'Parameters:'  Player - which gorilla is dancingSUB VictoryDance (player)  FOR i# = 1 TO 4    PUT (GorillaX(player), GorillaY(player)), GorL&, PSET    IF GSettings.useSound THEN PLAY "MFO0L32EFGEFDC" ELSE restReal .2    rest .2    PUT (GorillaX(player), GorillaY(player)), GorR&, PSET    IF GSettings.useSound THEN PLAY "MFO0L32EFGEFDC" ELSE restReal .2    rest .2  NEXTEND SUBFUNCTION WHEREX (num) WHEREX = ((num - 1) MOD 4) * 19 + 3END FUNCTIONFUNCTION WHEREY (num) WHEREY = INT((num - 1) / 4) + 13END FUNCTION
Quote:Original post by kryat
*** Source Snippet Removed ***


YAY
>wilhil<
Combat Tanks
I can't believe no one has mentioned OMF:2097 (download - 6mb).

Edit: Yes, it's completely legal.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
Risk
As it happens, all my three indie games can be played by more players on the same computer.

This topic is closed to new replies.

Advertisement