This repository was archived by the owner on Jan 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathgorillas.bas
More file actions
2579 lines (2231 loc) · 67.5 KB
/
gorillas.bas
File metadata and controls
2579 lines (2231 loc) · 67.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
'QBASIC GORILLAS 2.2
'Version 1.0 (c)1990 Microsoft Corp and/or IBM Corp
'Version 2.2 (c)1997-2007 Daniel Beardsmore
'See http://telcontar.net/Misc/Gorillas/ for more information
'Set default data type to integer for faster game play
DEFINT A-Z
'Sub Declarations
DECLARE 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 (Player$(), 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 TYPEs
TYPE settings
useSound AS INTEGER
useOldExplosions AS INTEGER
newExplosionRadius AS INTEGER
useSlidingText AS INTEGER
defaultGravity AS INTEGER
defaultRoundQty AS INTEGER
showIntro AS INTEGER
forceCGA AS INTEGER
END TYPE
TYPE XYPoint
XCoor AS INTEGER
YCoor AS INTEGER
END TYPE
TYPE PlayerData
PNam AS STRING * 17
Rounds AS INTEGER
Won AS INTEGER
Accu AS SINGLE
END TYPE
' Constants
CONST NPLAYERS = 20
CONST TRUE = -1
CONST FALSE = NOT TRUE
CONST HITSELF = 1
CONST BACKATTR = 0
CONST OBJECTCOLOR = 1
CONST WINDOWCOLOR = 14
CONST SUNHAPPY = FALSE
CONST SUNSHOCK = TRUE
CONST RIGHTUP = 1
CONST LEFTUP = 2
CONST ARMSDOWN = 3
' Global Variables
DIM SHARED GSettings AS settings
DIM SHARED lastErrCode
DIM SHARED SLIDECONST AS LONG
DIM SHARED GorillaX(1 TO 2) 'Location of the two gorillas
DIM SHARED GorillaY(1 TO 2)
DIM SHARED LastBuilding
DIM SHARED pi#
DIM SHARED LBan&(x), RBan&(x), UBan&(x), DBan&(x) 'Graphical picture of banana
DIM SHARED GorD&(120) 'Graphical picture of Gorilla arms down
DIM SHARED GorL&(120) 'Gorilla left arm raised
DIM SHARED GorR&(120) 'Gorilla right arm raised
DIM SHARED Gravity
DIM SHARED Wind
DIM SHARED GLeftAngle#
DIM SHARED GRightAngle#
DIM SHARED GLeftVeloc
DIM SHARED GRightVeloc
'Screen Mode Variables
DIM SHARED ScrHeight
DIM SHARED ScrWidth
DIM SHARED Mode
DIM SHARED MaxCol
' Screen Color Variables
DIM SHARED ExplosionColor
DIM SHARED SUNATTR
DIM SHARED BackColor
DIM SHARED SunHt
DIM SHARED GHeight
DIM SHARED MachSpeed AS DOUBLE
DIM SHARED PDefs(1 TO 2)
DIM Player$(1 TO 2)
DIM SHARED PDat(1 TO NPLAYERS) AS PlayerData
DIM SHARED GamePlayedYN
DIM SHARED DoesFileExist
DIM NumGames
' Load settings before initVars so we can look for forceCGA
LoadSettings
' 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
Gravity = GSettings.defaultGravity
NumGames = GSettings.defaultRoundQty
IF Mode = 1 THEN
REM CGA needs a half-size explosion radius
GSettings.newExplosionRadius = GSettings.newExplosionRadius \ 2
END IF
' 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
COLOR 7: CLS ' Else QBasic crashes here! lol
DEF SEG = 0 ' Restore NumLock state
POKE 1047, KeyFlags
DEF SEG
SYSTEM
' Banana sprite definitions
CGABanana:
'BananaLeft
DATA 327686, -252645316, 60
'BananaDown
DATA 196618, -1057030081, 49344
'BananaUp
DATA 196618, -1056980800, 63
'BananaRight
DATA 327686, 1010580720, 240
EGABanana:
'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 sprites
InitVars:
pi# = 4 * ATN(1#)
IF GSettings.forceCGA THEN
Mode = 1
ELSE
' Select best graphics mode
ON ERROR GOTO ScreenModeError
Mode = 9
SCREEN Mode
ON ERROR GOTO PaletteError
IF Mode = 9 THEN PALETTE 4, 0 'Check for 64K EGA
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 IF
RETURN
FuckOff:
lastErrCode = ERR
RESUME NEXT
ScreenModeError:
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 IF
PaletteError:
Mode = 1 '64K EGA cards will run in CGA mode.
RESUME NEXT
IsThereNoFile:
DoesFileExist = 0
RESUME NEXT
NoSaveStats:
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
CLOSE
SYSTEM
CorruptFile:
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: PRINT
SYSTEM
' Sliding text data store
SlidyText:
DATA 5
DATA " Q B a s i c G O R I L L A S v2.2",15,1,4
DATA "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ",7,-1,5
DATA "DELUXE EDITION",15,1,6
DATA "Original program (c)1990 Microsoft Corporation",3,1,10
DATA "Gorillas Deluxe (c)1997-2007 Daniel Beardsmore",2,-1,12
DATA 10
DATA "INSTRUCTIONS",9,1,8
DATA "Your mission is to hit your opponent with an exploding",11,1,10
DATA "banana by varying the angle and power of your throw, taking",11,-1,11
DATA "into account wind speed, gravity, and the city skyline.",11,1,12
DATA "The wind speed is shown by a directional arrow at the bottom",11,-1,14
DATA "of the playing field, its length relative to its strength.",11,1,15
DATA "Zero degrees is horizontal, towards your opponent, with 90 degrees",11,-1,16
DATA "being vertically upwards, and so on. Angles can be from 0 to",11,1,17
DATA "360 degrees and velocity can range from 1 to 200.",11,-1,18
DATA "Press any key to continue...",15,1,20
PartingMessage:
DATA 1
DATA "Thank you for playing Gorillas!",11,1,8
'Next number is the number of final phrases
DATA 5
DATA 1,"May the Schwarz be with you!",14,-1,14
DATA 1,"Live long and prosper.",14,-1,14
DATA 1,"Goodbye!",14,-1,14
DATA 1,"So long!",14,-1,14
DATA 1,"Adios!",14,-1,14
Ready:
DATA 1,"Prepare for battle!",12,1,1
Setup:
DATA 1,"Game Setup",14,-1,1
GameOver:
DATA 1,"Game Over!",14,-1,3
Aborted:
DATA 1,"Game aborted",12,-1,3
NowWhat:
DATA 1,"Now What?",14,1,1
VectorData:
DATA 39
DATA 0.582,0.988, 0.608,0.850, 0.663,0.788, 0.738,0.800
DATA 0.863,0.838, 0.813,0.713, 0.819,0.650, 0.875,0.588
DATA 1.000,0.563, 0.850,0.450, 0.825,0.400, 0.830,0.340
DATA 0.925,0.238, 0.775,0.243, 0.694,0.225, 0.650,0.188, 0.630,0.105
DATA 0.625,0.025, 0.535,0.150, 0.475,0.175, 0.425,0.150
DATA 0.325,0.044, 0.325,0.150, 0.315,0.208, 0.288,0.250, 0.225,0.275
DATA 0.053,0.288, 0.150,0.392, 0.175,0.463, 0.144,0.525
DATA 0.025,0.638, 0.163,0.650, 0.225,0.693, 0.250,0.775
DATA 0.225,0.905, 0.360,0.825, 0.450,0.823, 0.525,0.863
DATA 0.582,0.988
REM $STATIC
SUB 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 SUB
SUB 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
IF GSettings.useSound THEN PLAY "MBO0L32EFGEFDC"
'þ Draw grey smoke, EGA/VGA only
IF Mode = 9 THEN
CIRCLE (x#, y#), 1.175 * radii(1, 1), 10
PAINT (x#, y#), 10, 10
ELSE
CIRCLE (x#, y#), 1.175 * radii(1, 1), 1
PAINT (x#, y#), 0, 1
CIRCLE (x#, y#), 1.175 * radii(1, 1), 0
END IF
'? Draw vector explosion graphics
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
CIRCLE (x#, y#), 1.175 * radii(1, 1), 0
PAINT (x#, y#), 0, 0
END IF
EXIT SUB
DrawShape:
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, imageCol
RETURN
END 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 (Player$(), 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$)
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 3 ' Was 4
'LOCATE i, 1
'PRINT SPACE$(30 \ (80 \ MaxCol));
'LOCATE i, (50 \ (80 \ MaxCol))
'PRINT SPACE$(30 \ (80 \ MaxCol));
LOCATE i, 2: PRINT SPACE$(17)
LOCATE i, MaxCol - 17: PRINT SPACE$(17)
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 IF
EXIT FUNCTION
AbortGame:
cont = FALSE: cval = 1: tpause! = TIMER - 2
IF Mode = 9 THEN COLOR 14
DO
IF TIMER > tpause! + .5 THEN
IF cval = 1 THEN
Center 1, " Abort game? [Y/N] "
ELSE
Center 1, SPACE$(19)
GOSUB DSRestoreSun
END IF
cval = 2 / cval
tpause! = TIMER
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 = 2 THEN Center 1, SPACE$(19): DoSun SUNHAPPY
IF Mode = 1 THEN GOSUB CGARestNames
IF Mode = 9 THEN COLOR 15
RETURN
END IF
EXIT FUNCTION
DSRestoreSun:
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)), SUNATTR
RETURN
CGARestNames:
REM Under CGA, the Abort Game prompt can overwrite player names
LOCATE 1, 2: PRINT Player$(1)
LOCATE 1, MaxCol - LEN(Player$(2)): PRINT Player$(2)
RETURN
END 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), 0
END 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 banana
SUB 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&, XOR
END SELECT
END 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 down
SUB 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 i
END SUB
'ExplodeGorilla:
' Causes gorilla explosion when a direct hit occurs
'Parameters:
' X#, Y# - shot location
SUB 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 16 * SclX#
CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, i MOD 2 + 1, , , -1.57
NEXT i
timeStay! = TIMER: DO: LOOP UNTIL TIMER > timeStay! + .05
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 SUB
SUB Extro
COLOR 7: CLS
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$ <> ""
END SUB
FUNCTION 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 = 1
Get$ = 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 players
SUB 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 complete
Player$(1) = RTRIM$(PDat(PDefs(1)).PNam)
Player$(2) = RTRIM$(PDat(PDefs(2)).PNam)
NumGames = VAL(numG$)
Gravity = VAL(grav$)
'þ Clear most of the screen
COLOR , 0: FOR l = 3 TO 24: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT
EXIT SUB
'þþþþþþþþþþþþþþþþþþþþ
'þ FIELDS SUBROUTINES