Author Topic: Moon Lander by Richard Frost  (Read 3944 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
Moon Lander by Richard Frost
« on: May 19, 2020, 05:16:56 am »
Moon Lander

Author: @Richard Frost
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1022.0
Version: May 15, 2020
Tags: [Graphics], [Skill]

Description:
Lunar Lander based on a 1974 program running on a DEC PDP/11 with GT40 vector display terminal at the University of Alberta.  Initially written in QB4.5 (hence the convoluted code to save space), upgraded to use some QB64 features.  Updated May 15, 2020 -  More effects (at warp speeds) and cookies!

Controls:
The multifarious keyboard controls are given by pressing F1 (Help) when the program is run.

Source Code:
Code: QB64: [Select]
  1. ' Moon Lander by rfrost@mail.com
  2.  
  3. $EXEICON:'.\astro.ico'
  4.  
  5. DEFINT A-Z
  6. DIM SHARED a '                                                        angle of craft
  7. DIM SHARED a51i '                                                     Area 51 initializations
  8. DIM SHARED APdisengage '                                              AutoPilot disengage
  9. DIM SHARED ASO '                                                      ascent stage only
  10. DIM SHARED auto '                                                     autopilot
  11. DIM SHARED background '                                               for instrument panel
  12. DIM SHARED bh '                                                       black hole
  13. DIM SHARED bhx, bhy '                                                 black hole
  14. DIM SHARED bbit '                                                     blinking bit synced to time
  15. DIM SHARED bolthit, bolthitf, boltx '                                 Deathstar hit vehicle, feature
  16. DIM SHARED borgl, borgr, borgt '                                      left right top, distance
  17. DIM SHARED bstyle1, bstyle2 '                                         Borg matrix/lines/Moire
  18. DIM SHARED bw '                                                       black and white
  19. DIM SHARED c '                                                        usually color
  20. DIM SHARED canvas& '                                                  primary screen
  21. DIM SHARED cbh '                                                      constant black holes
  22. DIM SHARED center '                                                   varies according to gs (graphics start)
  23. DIM SHARED chs '                                                      parachute size
  24. DIM SHARED contact '                                                  landed
  25. DIM SHARED convo '                                                    conversation active LM/CM
  26. DIM SHARED cpal '                                                     color palette, normal/green/b&w (32 color kludge/fun)
  27. DIM SHARED craft '                                                    color
  28. DIM SHARED crash '                                                    layer of debris
  29. DIM SHARED cwd, cwsi, cwsd '                                          car wash distance, angles
  30. DIM SHARED cybilltime! '                                              time on screen
  31. DIM SHARED darkstarc '                                                deathstar color set
  32. DIM SHARED darkstars '                                                deathstar spin rate
  33. DIM SHARED darkstart '                                                   "      thickness
  34. DIM SHARED dead$ '                                                    end condition
  35. DIM SHARED debug$ '                                                   messages to God
  36. DIM SHARED demo '                                                     ground features compressed
  37. DIM SHARED doclock '                                                  it's Howdy Doody time
  38. DIM SHARED dosbox '                                                   flag
  39. DIM SHARED dsinit '                                                   deathstar
  40. DIM SHARED eou '                                                      end of universe
  41. DIM SHARED fb$ '                                                      landing feedback/analysis
  42. DIM SHARED flx '                                                      US/USSR flag position
  43. DIM SHARED fuel, fuel! '                                              color of, quantity left
  44. DIM SHARED gh, glmin, glmax '                                         ground height, level
  45. DIM SHARED grav! '                                                    gravity
  46. DIM SHARED gs '                                                       flight area x start
  47. DIM SHARED gstyle '                                                   ground style
  48. DIM SHARED inpause '                                                  flag
  49. DIM SHARED invincible '                                               impervious to threats
  50. DIM SHARED iscd '                                                     don't attempt to write!
  51. DIM SHARED jitter '                                                   shift-T to control
  52. DIM SHARED LEDc '                                                     color
  53. DIM SHARED LEDtri '                                                   tri-color flag
  54. DIM SHARED level '                                                    surface is
  55. DIM SHARED LGMc '                                                     Little Green Man color
  56. DIM SHARED liftoff '                                                  AS only
  57. DIM SHARED lmsl '                                                     LM shield/laser color
  58. DIM SHARED lob '                                                      landed on Borg
  59. DIM SHARED lockfuel '                                                 cheat!
  60. DIM SHARED lp, rp, xp, th1, th2 '                                     pads, radar, thrusters
  61. DIM SHARED magic '                                                    cheat! (instant landing)
  62. DIM SHARED mdelay '                                                   PgUp/PgDn controlled
  63. DIM SHARED msflag '                                                   making surfaces
  64. DIM SHARED mstar '                                                    make stars
  65. DIM SHARED nation '                                                   1 US, 2 USSR (flags & fireworks)
  66. DIM SHARED ok '                                                       at landing, to plant flag
  67. DIM SHARED okrick '                                                   diagnostics
  68. DIM SHARED osc '                                                      on screen count
  69. DIM SHARED oscar '                                                    semaphore land/sea flags
  70. DIM SHARED panelinit '                                                replot flag
  71. DIM SHARED paraf '                                                    parachute flag
  72. DIM SHARED pload '                                                    panel load flag
  73. DIM SHARED porb '                                                     pointers/bargraphs
  74. DIM SHARED ptk '                                                      points to kill (gasoline) ExplodeLM
  75. DIM SHARED px!, py! '                                                 vehicle position on screen
  76. DIM SHARED ra '                                                       random angle
  77. DIM SHARED radarf '                                                   radar on/off
  78. DIM SHARED rads '                                                     Luna radiation
  79. DIM SHARED radiationdeath '                                           flag
  80. DIM SHARED rdtime! '                                                  fun with high res screen (my picture)
  81. DIM SHARED regen '                                                    all star files
  82. DIM SHARED rfx, rfy '                                                 craft jigger
  83. DIM SHARED rick '                                                     debug flag
  84. DIM SHARED rmin, dmin '                                               stars
  85. DIM SHARED settings$ '                                                lander.set
  86. DIM SHARED sf '                                                       surface feature
  87. DIM SHARED shield '                                                   flag
  88. DIM SHARED shoot '                                                    flag
  89. DIM SHARED showmap '                                                  locations of things shown at top
  90. DIM SHARED sia '                                                      shells in air
  91. DIM SHARED skyoff '                                                   for faster performance
  92. DIM SHARED starship '                                                 Enterprise (double shift twice)
  93. DIM SHARED ufof '                                                     for ufo
  94. DIM SHARED sspinit1, sspinit2 '                                       Surveyor
  95. DIM SHARED starfiles '                                                use stars1,2 or 3 (few/med/lots)
  96. DIM SHARED starinit '                                                 flag
  97. DIM SHARED shipi&, shipx '                                            starship
  98. DIM SHARED starstatus '                                               0 off, 1 on, 234 more info
  99. DIM SHARED suri '                                                     surface index
  100. DIM SHARED sx0, sy0 '                                                 LM radar/laser location
  101. DIM SHARED sx1, sy1 '                                                 LM left landing pad
  102. DIM SHARED sx2, sy2 '                                                 LM right landing pad
  103. DIM SHARED temp '                                                     temperature
  104. DIM SHARED thrust! '                                                  0 - 100
  105. DIM SHARED tilef '                                                    tile variation
  106. DIM SHARED vx!, vy! '                                                 LM velocity
  107. DIM SHARED warp! '                                                    vx! >= 100
  108. DIM SHARED wi, wi2 '                                                  width (distance between pads)
  109. DIM SHARED wx!, wy! '                                                 vehicle position on screen
  110. DIM SHARED x '                                                        = suri + px!
  111. DIM SHARED xoff '                                                     offset for v=5-20, Surv & Etna
  112. DIM SHARED zoom '                                                     starfield
  113.  
  114. DIM SHARED blue, green, gunmetal, red, gasoline, gray2, white, gray
  115. DIM SHARED dred, gold, black2, orange, blue2, yellow, white2
  116.  
  117. DIM SHARED q1, q2, q3, q4, h, t, th, tsix, aspect!, pf! '             constants
  118.  
  119. q1 = 6400: q2 = 860: q3 = 639: q4 = 349: h = 100: th = 200: t = 10: tsix = 360
  120. pf! = .5: aspect! = 1.4: grav! = 1.6
  121.  
  122. qt = 2000 '                                                           3 arrays below weren't loading properly with q2
  123. DIM SHARED LMx(qt), LMy(qt), LMc(qt) '                                LM+exhaust x,y,color
  124.  
  125. DIM SHARED LMrx(1400), LMry(1400) '                                   LM+exhaust x,y after rotation
  126. DIM SHARED LMoc(705), LMci(3) '                                       LM colors,original colors, index
  127. DIM SHARED c!(360), s!(360) '                                         sines and cosines
  128. DIM SHARED ex(6), ey(6), exv(6), eyv(6), ei(6), ek(6), exl(6) '       sky objects
  129. DIM SHARED f$(40) '                                                   support files
  130. DIM SHARED mes$(1), omes$(1), sm!(1) '                                messages at screen top
  131. DIM SHARED sf(10, 2), sf$(10) '                                       surface features start/end/middle
  132. DIM SHARED shx(20), shy(20), sha(20) '                                shells (IBM weapons) x,y,angle
  133. DIM SHARED shvx(20), shvy(20), shd(20) '                              velocity, distance
  134. DIM SHARED rtl!(2), rtlc(2) '                                         radiation/temperature/lightning
  135. DIM SHARED gh(6400) '                                                 ground height
  136.  
  137. DIM clocka(2) '                                                       clock angles
  138. DIM cmp&(30) '                                                        CM patterns
  139. DIM convo$(50) '                                                      LM/CM
  140. DIM SHARED gbuff(800) '                                               DS liftoff
  141. DIM skyset1(t), skyset2(t) '                                          skycrud
  142. DIM SHARED p(127, 13), p2(127, 7) '                                   vga and cga fonts
  143. DIM SHARED tflags(30)
  144.  
  145. begin:
  146. GOSUB init1
  147.     GOSUB init2
  148.     WHILE LEN(INKEY$): WEND '                                         clear keyboard buffer
  149.     DO: _LIMIT mdelay
  150.         GOSUB Autopilot
  151.         GOSUB Plotscreen
  152.         GOSUB KeyAndMouse
  153.         IF restart THEN GOTO begin '                                  restore defaults
  154.         IF warp! < 1 THEN GOSUB CheckHit
  155.     LOOP UNTIL contact OR LEN(dead$)
  156.     GOSUB CheckDead
  157.     IF contact THEN
  158.         Evaluate savea, a + ma '                                      landing feedback contact/currentø
  159.         wu2! = TIMER + 1
  160.         GOSUB pause '                                                 landed, Enter for liftoff
  161.         IF restart THEN GOTO begin '                                  restore defaults
  162.         IF k <> 60 THEN GOSUB CheckDead '                             F2 demo restart
  163.     END IF
  164.  
  165. CheckDead:
  166. z$ = LEFT$(LEFT$(dead$, 1) + " ", 1)
  167. IF INSTR(" CBE", z$) = 0 THEN '                                       not Crashed, Borg, Eaten by BH
  168.     ExplodeLM
  169.     contact = 0
  170. dead$ = ""
  171.  
  172. Autopilot:
  173. aboveborg = 0
  174. IF (ek(2) = -1) OR (ek(2) > h) THEN borgt = 0
  175. IF (skyoff = 0) AND (sy1 < borgt) AND (px! > borgl) AND (px! < borgr) THEN aboveborg = 1
  176. super = 0
  177. IF vert OR hover THEN
  178.     GOSUB GetAlt
  179.     i! = alt! / 8 + pf! '                                             thrust target
  180.     IF jitter AND (alt! < t) THEN i! = i! * 2 '                       optional, faster
  181.     IF aboveborg THEN i! = 1
  182.     GOSUB idealthrust
  183.     thrust! = sbest!
  184.     super = -(sbest! > h) '                                           add side thusters
  185.     IF thrust! > h THEN thrust! = h
  186. IF thrust! < 0 THEN thrust! = 0
  187.  
  188. CutOrOutOfFuel:
  189. IF fuel! = 0 THEN shield = 0 '                                        shields need fuel
  190. IF cut = 0 THEN
  191.     cut = 1
  192.     cvy! = vy!
  193.     ctime! = TIMER
  194.     tfollow = 0 '                                                     terrain following
  195.     thrust! = 0
  196.  
  197. idealthrust: '                                                        for hover or descend
  198. IF (alt! < pf!) AND (jitter = 0) THEN i! = .05 '                      soft landing
  199. IF hover THEN i! = hoverc '                                           target
  200. hoverc = hoverc - SGN(hoverc) '                                       up/down
  201. fmin! = q1 '                                                          conventient large number (6400)
  202. ma! = (vmass + fuel!) / th '                                          mass (actually 54% fuel)
  203. ts! = s!((a + 270) MOD tsix) / ma! / power
  204. IF jitter THEN us! = RND * t + 1 ELSE us! = .1
  205. IF powerloss THEN us! = h
  206. FOR z! = 0 TO (h + t) STEP us! '                                      find best thrust 0-110
  207.     fo! = z! * ts!
  208.     aa! = ABS(vy! + grav! + fo! - i!)
  209.     IF aa! < fmin! THEN fmin! = aa!: sbest! = z!
  210.     IF aa! > fmin! THEN EXIT FOR
  211. NEXT z!
  212.  
  213. GoSkyObject:
  214. IF (ek(p) <> -1) AND (contact = 0) THEN
  215.     auto = 0
  216.     a = -ma
  217.     wa = -ma
  218.     lock1 = 0
  219.     suri = ex(p) - center
  220.     GOSUB slimit
  221.     IF p > 2 THEN ey(p) = th '                                        BH, worm, comet, alien
  222.     px! = center
  223.     IF p = 2 THEN py! = 130 '                                         above Borg
  224.     vx! = exv(p)
  225.     eyv(p) = 0
  226.  
  227. KeyAndMouse:
  228.     lb = ABS(_MOUSEBUTTON(1))
  229.     rb = ABS(_MOUSEBUTTON(2))
  230.     IF mouseswap THEN SWAP lb, rb '                                   whatever floats your boat
  231.     IF TIMER < ignoreuntil! THEN lb = 0: rb = 0 '                     2 lines for debouncing
  232.     IF lb OR rb THEN ignoreuntil! = TIMER + .25
  233.     ww = wa '                                                         stash current wanted angle
  234.     wa = wa + lb - rb '                                               want angle
  235.     IF wa <> ww THEN '                                                if changed
  236.         IF inpause THEN i$ = CHR$(13): GOTO gotit '                   either button to cause liftoff
  237.         apd = 1 '                                                     autopilot disconnect warning
  238.         auto = 0 '                                                    autopilot
  239.         GOTO endk '                                                   don't bother checking keys
  240.     END IF
  241.     mw = mw + _MOUSEWHEEL
  242. IF mw <> 0 THEN '                                                     wheel moved
  243.     thrust! = INT(thrust!) - mw
  244.     IF thrust! < 0 THEN thrust! = 0
  245.     IF thrust! > h THEN thrust! = h
  246.     apd = 1 '                                                         autopilot disconnect warning
  247.     auto = 0 '                                                        autopilot
  248.     hover = 0 '                                                       hover off
  249.     vert = 0 '                                                        vertical control off
  250.     mw = 0 '                                                          zap
  251.     GOTO endk '                                                       don't bother checking keys
  252.  
  253. DEF SEG = 0
  254. status = PEEK(&H417) '                                                7ins 6caps 5num 4scrl 3alt 2ctrl 1ls 0rs
  255.  
  256. IF ((status AND 1) > 0) AND ((status AND 2) > 0) THEN '               both shift (cookie!)
  257.     IF rdtime! > 0 THEN starship = 1 '                                must have pressed shift-shift twice, another cookie
  258.     rdtime! = TIMER + 5 '                                             Rick display time
  259.  
  260. IF status AND 8 THEN start1! = TIMER: mpass& = 0 '                    alt, reset speed timer
  261.  
  262. IF status AND 4 THEN '                                                ctrl
  263.     i$ = RIGHT$(" " + INKEY$, 1)
  264.     kk = ASC(i$)
  265.     IF (kk = 3) OR (kk = 19) THEN '                                   c or s
  266.         nfile:
  267.         image = image + 1
  268.         f$ = "CAP" + RIGHT$("0000" + LTRIM$(STR$(image)), 3) + ".BMP"
  269.         IF _FILEEXISTS(f$) THEN GOTO nfile
  270.         SaveImage f$
  271.         IF _FILEEXISTS(f$) THEN mes$(1) = "Screen captured to " + f$
  272.         GOTO endk
  273.     END IF
  274.  
  275. i$ = INKEY$ '                                                         consult human
  276. li = LEN(i$)
  277. IF li = 0 THEN RETURN
  278.  
  279. IF i$ = "|" THEN MakeStarFiles '                                      takes hours!
  280.  
  281. k = ASC(RIGHT$(i$, 1))
  282. IF k = 27 THEN Quit
  283. IF inpause AND (k = 32) THEN
  284.     k = 13 '                                                          transform spacebar to Enter
  285.     i$ = RIGHT$(CHR$(0) + CHR$(k), li) '                              gentlemen, we can rebuild him
  286.  
  287. gotit:
  288. IF (i$ = "\") AND (shx(0) = 0) AND (contact = 0) THEN '               LM drops bomb
  289.     IF (cwd < 50) AND (sy1 > 300) THEN dead$ = "Smooth move, Exlax!" 'kill self in car wash
  290.     sia = sia + 1 '                                                   shells in air
  291.     shvx(0) = vx! + 3 + RND * t
  292.     shvy(0) = 0
  293.     shx(0) = suri + sx0
  294.     shy(0) = sy0
  295.     shd(0) = 1
  296.  
  297. IF i$ = "[" THEN bw = bw XOR 1: Setcolor '                            crude method for b&w
  298. IF i$ = "]" THEN
  299.     ufof = ufof XOR 1
  300.     mes$(0) = "UFO " + OnOff$(ufof)
  301.     IF ufof THEN
  302.         GOSUB SkyStuff
  303.         p = 6: GOSUB GoSkyObject
  304.     END IF
  305.  
  306. IF i$ = "=" THEN GOSUB lmshow '                                       show LM data - pointless but amusing
  307. IF i$ = "'" THEN pdiv = (pdiv + 1) MOD 4 '                            Henon speed, also slows down thrust display
  308. IF radiationdeath THEN i$ = "": RETURN '                              you're dead and cannot pass this point
  309.  
  310. IF i$ = "`" THEN '                                                    Deathstar size - thought a smaller one wouuld be faster - it is - not by much
  311.     dsinit = 0
  312.     dstype = 2 + (MID$(f$(37), 6, 1) = "m")
  313.     MID$(f$(37), 6, 1) = MID$("sm", dstype, 1)
  314. IF i$ = "~" THEN darkstarc = darkstarc XOR 1 '                        color
  315. IF i$ = "@" THEN darkstart = darkstart XOR 1 '                        thickness
  316.  
  317. IF inpause THEN '                                                     hit "p" or landed
  318.     IF i$ = "b" THEN '                                                Big Dipper
  319.         rmin = 9 '                                                    right ascension
  320.         dmin = 30 '                                                   declination
  321.         starinit = 0
  322.         RETURN
  323.     END IF
  324.     IF li = 2 THEN '                                                  arrow keys move stars
  325.         rdol = rmin + dmin '                                          detect change
  326.         rmin = rmin + (k = 75) - (k = 77) '                           left right
  327.         rmin = (rmin + 24) MOD 24 '                                   RA limit 0 - 24
  328.         dmin = dmin - (k = 80) * t + (k = 72) * t '                   declination up down
  329.         IF dmin = h THEN dmin = -80 '                                 limit -90 - 90
  330.         IF dmin = -h THEN dmin = 80
  331.         IF (rmin + dmin) <> rdol THEN starinit = 0 '                  changed, replot stars
  332.     END IF
  333. IF li = 2 THEN GOTO is2 '                                             extended key
  334.  
  335. IF i$ = "_" THEN '                                                    star twinkle
  336.     twinkle = twinkle XOR 1
  337.     mes$(0) = "STAR TWINKLE " + OnOff$(twinkle)
  338. IF i$ = ";" THEN fpl = 1 '                                            force power loss
  339. IF k = 9 THEN ex(1) = (suri + px!) - SGN(exv(1)) * h '                TAB summon DS
  340. p = INSTR(")!@#$%^&*(", i$)
  341. IF p AND (contact = 0) THEN GetSurface p - 1 '                        shifted-number for 1 of 10 surfaces
  342. p = INSTR("01234", i$) '                                              stars off/on/info
  343. IF p THEN starstatus = p - 1
  344. IF k = 8 THEN '                                                       backspace, random star position
  345.     rmin = INT(RND * 24) '                                            random RA
  346.     dmin = (INT(RND * 18) - 9) * t '                                  random dec
  347.     starinit = 0
  348. IF i$ = "." THEN
  349.     tfollow = tfollow XOR 1
  350.     auto = 0
  351.     vert = 1
  352.     mes$(0) = "TERRAIN FOLLOWING " + OnOff$(tfollow)
  353. p = (i$ = "<") - (i$ = ">") '                                         jump left/right
  354. IF (contact = 0) AND (p <> 0) THEN
  355.     suri = suri + 40 * p '                                            surface index
  356.     GOSUB slimit '                                                    limit suri
  357.     IF lock1 THEN hover = 1: lock1 = 0
  358. IF (i$ = "+") AND (zoom < 2) THEN zoom = zoom + 1: starinit = 0
  359. IF (i$ = "-") AND (zoom > 0) THEN zoom = zoom - 1: starinit = 0
  360. IF i$ = "?" THEN rick = rick XOR 1 '                                  show speed of processing graph
  361. IF okrick AND (i$ = "U") THEN tilef = (tilef + 1) MOD 3 '             alternate tilings
  362. IF i$ = "/" THEN
  363.     cpal = (cpal + 1) MOD 4 '                                         cycle green/black & white/normal monitor
  364.     mes$(0) = "": mes$(1) = ""
  365.     IF cpal = 1 THEN mes$(0) = "GT40 mode"
  366.     IF cpal = 2 THEN mes$(1) = "Hyperion mode!"
  367.     IF cpal = 3 THEN mes$(1) = "Do not adjust your set.  We control the horizontal and the vertical!"
  368. IF k = 32 THEN '                                                      cycle thru features
  369.     IF lock1 > 0 THEN '                                               on auto, landing zone selected, abort landing
  370.         abort = 1
  371.         mes$(0) = "ABORT!"
  372.         IF vx! = 0 THEN vx! = .01
  373.         RETURN
  374.     END IF
  375.     IF convo THEN '                                                   or speed up rendesvous
  376.         sct! = .2
  377.         sc! = TIMER
  378.         RETURN
  379.     END IF
  380.  
  381.     IF skyoff THEN tmod = t ELSE tmod = 16
  382.     jf = (jf + 1) MOD tmod
  383.     '          01234567890123456
  384.     i$ = MID$("mtsiHg5wleObBWoR", jf + 1, 1) '                        cycle thru ground and sky features
  385.     k = ASC(i$)
  386.     IF demo AND (jf = 7) THEN i$ = "e" '                              skip LGM in demo, because it's on the grave
  387.  
  388. p = INSTR("RObBWo", i$) '                                             jump to CM, deathstar, etc.
  389. IF p AND (skyoff = 0) THEN p = p - 1: GOSUB GoSkyObject
  390.  
  391. IF i$ = "A" THEN
  392.     lam = lam XOR 1 '                                                 land at McDonalds
  393.     IF lam AND (auto = 0) THEN i$ = "a" '                             turn on autopilot
  394. IF i$ = "a" THEN '                                                    autopilot
  395.     abort = 0 '                                                       in case it was on
  396.     tfollow = 0
  397.     auto = auto XOR 1 '                                               toggle
  398.     IF auto AND (radarf = 0) THEN radarf = 2
  399.     IF auto = 0 THEN hover = 1 '                                      be nice, help user
  400.     pt! = TIMER '                                                     restart countdown
  401. IF i$ = "c" THEN GOSUB CutOrOutOfFuel
  402. IF i$ = "C" THEN doclock = doclock XOR 1
  403. IF i$ = "d" THEN dump = dump XOR 1 '                                  fuel
  404. IF i$ = "D" THEN restart = 1 '                                        restart with defaults
  405. IF (i$ = "E") AND (starstatus > 0) THEN '                             end of universe
  406.     IF eou = 0 THEN eou = -1 ELSE eou = eou + 1 '                     restart or speedup
  407. IF i$ = "F" THEN
  408.     fuel! = h
  409.     lockfuel = 1
  410. IF i$ = "f" THEN lockfuel = lockfuel XOR 1 '                          THIS cheat the GT40 had, using toggle switches!
  411. IF i$ = "G" THEN gstyle = (gstyle + 1) MOD 6 '                        ground style
  412. IF i$ = "h" THEN hover = hover XOR 1: apd = 1 '                       apd=autopilot disconnect warning
  413. IF i$ = "I" THEN
  414.     invincible = ABS(invincible) XOR 1
  415.     mes$(0) = "INVINCIBLE MODE " + OnOff$(invincible)
  416.     GOSUB ReadLM '                                                    to change thrusters
  417. IF i$ = "j" THEN
  418.     darkstars = (darkstars + 1) MOD 5
  419.     mes$(0) = "Deathstar rotation" + STR$(darkstars)
  420. IF i$ = "k" THEN '                                                    kill threats or, if none, shoot at ground feature
  421.     firel = 1 '                                                       fire laser
  422.     FOR z = 1 TO 20 '                                                 IBM shells
  423.         shd(z) = 1
  424.     NEXT z
  425. IF i$ = "L" THEN GetSurface -1 '                                      level ground
  426. IF (i$ = "M") AND ((contact + inpause) = 0) THEN '                    laser level & land
  427.     magic = magic + 1
  428. IF (i$ = "n") AND inpause THEN nation = ((nation - 1) XOR 1) + 1 '    flag 1 US, 2 USSR
  429. IF i$ = "p" THEN GOSUB pause '                                        pause LM movement
  430. IF (i$ = "P") AND (contact = 0) AND (warp! < 1) AND (paraf = 0) THEN
  431.     paraf = 1 '                                                       parachute!
  432.     chs = 0
  433.     a = 0
  434.     GOSUB CutOrOutOfFuel
  435. IF i$ = "q" THEN Quit
  436. IF i$ = "Q" THEN
  437.     oscar = oscar XOR 1 '                                            land or sea flags for LGM
  438.     IF oscar THEN z$ = "SEA" ELSE z$ = "LAND"
  439.     mes$(0) = "LGM flags: " + z$
  440. IF i$ = "r" THEN
  441.     IF cut THEN '                                                     restart engine
  442.         cut = 0
  443.         hover = 1
  444.         power = opower
  445.         powerloss = 0
  446.     ELSE
  447.         IF auto = 0 THEN
  448.             radarf = (radarf + 1) MOD 3
  449.             mes$(0) = "Radar " + MID$("OFFON FAT", radarf * 3 + 1, 3)
  450.         END IF
  451.     END IF
  452. IF i$ = "S" THEN MakeSur: restart = 1 '                               generate new surfaces
  453. IF i$ = "T" THEN jitter = jitter XOR 1 '                              thrust computation
  454. IF i$ = "u" THEN '                                                    instrument panel on/off
  455.     zz = gs
  456.     gs = (SGN(gs) XOR 1) * 85 '                                       graphics start
  457.  
  458.     panelinit = 0
  459.     pif = -1
  460.  
  461.     z = (gs + 30) - px!
  462.     IF (gs > 0) AND (z > 0) THEN
  463.         px! = px! + z
  464.         suri = suri - z
  465.         GOSUB slimit
  466.     END IF
  467. IF i$ = "v" THEN '                                                    vertical automatic
  468.     IF tfollow THEN
  469.         tfollow = 0
  470.         mes$(0) = "TERRAIN FOLLOWING OFF"
  471.     END IF
  472.     vert = vert XOR 1
  473.     apd = 1 '                                                         autopilot disconnect warning
  474. IF i$ = "x" THEN starinit = 0: starfiles = (starfiles + 1) MOD 3 '    star density
  475. IF i$ = "X" THEN starinit = 0: regen = 1: Stars '                     regenerate single star file
  476. IF i$ = "y" THEN
  477.     mouseswap = mouseswap XOR 1
  478.     IF mouseswap THEN z$ = "reversed" ELSE z$ = "normal"
  479.     mes$(0) = "Mouse buttons " + z$
  480. IF i$ = "Y" THEN min = 3: sec = 45 '                                  black hole at 3:50
  481. IF (i$ = "z") AND (crash = 0) THEN
  482.     mes$(0) = "" '
  483.     mes$(1) = "" '                                                    erase radiation messages
  484.     dead$ = "SELF-DESTRUCT"
  485.  
  486. IF i$ = "}" THEN
  487.     GOSUB CutOrOutOfFuel
  488.     sgs = gs: gs = 0
  489.     srf = radarf: radarf = 0
  490.     GOSUB Plotscreen
  491.     dissolve
  492.     dead$ = " "
  493.     gs = sgs: radarf = srf
  494.  
  495. '          1234567890
  496. p = INSTR("5wlemtsiHg", i$) '                                         jump to feature
  497. IF p AND (contact = 0) THEN
  498.     sf = p
  499.     IF demo AND sf = 9 THEN sf = t
  500.     IF (sf(sf, 1) >= suri) AND (sf(sf, 0) < (suri + q3)) THEN '       already in vicinity of IBM
  501.         IF sf = 8 THEN shoot = 1 '                                    tell IBM to fire
  502.         IF demo THEN '                                                IBM at special location in demo mode, deal with it
  503.             px! = sf(sf, 2) - 3130
  504.             suri = 3130
  505.         END IF
  506.     ELSE
  507.         px! = center '                                                move ship to screen center
  508.         suri = sf(sf, 0) - center - 30 - (sf = 9) * h '               move ground to IBM
  509.     END IF
  510.     a = -ma '                                                         angle = -malfunction angle
  511.     abort = 0
  512.     wa = -ma '                                                        want angle
  513.     lock1 = 0 '                                                       radar lock
  514.     tmt! = 0 '                                                        to move total
  515.     vx! = 0 '                                                         not moving
  516.     warp! = 0 '                                                       cancel warp
  517. GOTO endk '                                                           done with ordinary keys
  518.  
  519. is2: '                                                                extended key
  520. z = mdelay '                                                          master delay
  521. mdelay = mdelay - (k = 73) + (k = 81) '                               PgUp/PgDn
  522. IF mdelay < 1 THEN mdelay = 1
  523. IF mdelay <> z THEN '                                                 changed
  524.     mes$(0) = "_LIMIT " + OnOff$(SGN(mdelay))
  525.     IF mdelay THEN mes$(0) = mes$(0) + LTRIM$(STR$(mdelay))
  526. IF status AND 3 THEN '                                                left or right shift
  527.     IF k = 72 THEN k = 201 '                                          LM up
  528.     IF k = 75 THEN k = 203 '                                          LM left
  529.     IF k = 77 THEN k = 204 '                                          LM right
  530. IF (inpause = 0) AND ((k = 72) OR (k = 80)) THEN '                    up and down arrow
  531.     apd = 1 '                                                         autopilot disconnect
  532.     hover = 0
  533.     vert = 0
  534.     thrust! = thrust! + (k = 80) - (k = 72) '                         true = -1
  535. thrust! = INT(thrust! * t) / t '                                      t = 10
  536. IF (hover = 0) AND (vert = 0) THEN thrust! = INT(thrust!)
  537. IF thrust! > h THEN thrust! = h
  538. IF (dump = 0) AND (fuel! > 0) AND (contact = 0) THEN '                side thrust/angle
  539.     IF inpause = 0 THEN wa = a - (k = 75) + (k = 77) '                                    left/right arrows
  540.     IF ABS(wa) > 99 THEN wa = 99 * SGN(wa) '                          want angle, limit 99
  541.     IF a <> wa THEN apd = 1 '                                         autopilot disconnect
  542. IF k = 59 THEN '                                                      F1 help
  543.     mHelp
  544.     start1! = TIMER: mpass& = 0 '                                     reset speed timer
  545. IF k = 60 THEN '                                                      F2 demo
  546.     demo = demo XOR 1
  547.     GOSUB init2
  548.     cbh = demo '                                                      constant black holes
  549. IF k = 61 THEN '                                                      F3, sky feature toggle
  550.     skyoff = skyoff XOR 1
  551.     IF skyoff = 0 THEN convo = 0
  552.     mes$(0) = "SKY OBJECTS " + OnOff$(1 - skyoff)
  553. IF k = 62 THEN '                                                      F4 endless bh
  554.     cbh = cbh XOR 1
  555.     exv(3) = 0
  556.     mes$(0) = "CONSTANT BLACK HOLES " + OnOff$(cbh)
  557. IF k = 63 THEN '                                                      F5 instrument background
  558.     f5toggle = f5toggle XOR 1
  559.     IF f5toggle = 0 THEN background = background XOR 1
  560.     IF f5toggle = 1 THEN porb = porb XOR 1
  561.     pload = 0
  562. IF (k = 64) AND ((ASO + inpause) = 0) THEN '                          F6 seperate AS/DS
  563.     GOSUB liftoff
  564.     RETURN
  565. IF k = 65 THEN showmap = showmap XOR 1 '                              F7 map
  566. IF k = 66 THEN '                                                      F8 shields
  567.     shield = shield XOR 1
  568.     geof = shield * t
  569. IF k = 67 THEN '                                                      F9 LED color
  570.     z$ = RIGHT$("0" + LTRIM$(STR$(LEDc)), 2)
  571.     z = INSTR(LED$, z$): IF z = 11 THEN z = -1
  572.     LEDc = VAL(MID$(LED$, z + 2, 2))
  573.     LEDtri = 0
  574. IF k = 68 THEN '                                                      F10 LED tri-color
  575.     LEDtri = LEDtri XOR 1
  576.     IF LEDtri THEN LEDc = green
  577. IF k = 71 THEN rmin = 0: dmin = 0: starinit = 0 '                     Home, star RA/dec to 0
  578.  
  579. endk:
  580. IF k = 201 THEN hoverc = hoverc - t '                                 move up
  581. IF k = 203 AND (left = 0) THEN left = 16 '                            move left
  582. IF k = 204 AND (right = 0) THEN right = 16 '                          move right
  583. IF apd OR (k = 201) OR (k = 203) OR (k = 204) THEN '                  blink AUTO
  584.     IF auto THEN APdisengage = 20 '                                   blink 20 times
  585.     auto = 0 '                                                        turn it off
  586.     apd = 0 '                                                         reset flag
  587.  
  588. pause:
  589. IF inpause THEN RETURN '                                              already doing this....
  590. dead$ = ""
  591. inpause = 1
  592. pt! = TIMER '                                                         for demo mode
  593. wu! = pt! + 1 '                                                       delay before planting flag
  594. DO: _LIMIT mdelay
  595.     GOSUB KeyAndMouse
  596.     IF k = 60 THEN RETURN '                                           F2 demo
  597.     IF (i$ > "") AND (INSTR("zD", i$)) THEN RETURN '                  self-destruct or restart
  598.     GOSUB Plotscreen
  599.     IF LEN(dead$) THEN RETURN
  600.     IF auto AND contact THEN '                                        countdown to blast off
  601.         IF TIMER < pt! THEN pt! = TIMER '                             midnite crossing fix
  602.         z! = TIMER - pt!
  603.         z = t - z!
  604.         IF z < 0 THEN z = 0
  605.         TextOnLM$ = LTRIM$(STR$(z))
  606.         IF z! > t THEN i$ = CHR$(13) '                                like pressing the key
  607.     END IF
  608.     GOSUB CalcFuel
  609. LOOP UNTIL (i$ = CHR$(13)) OR (i$ = "p")
  610. ctime! = TIMER
  611. fb$ = "" '                                                            feedback
  612. inpause = 0
  613. c = (contact = 1) AND (crash = 0) AND (liftoff = 0) AND (ABS(a) < 31)
  614. IF c THEN GOSUB liftoff
  615.  
  616. CalculateMotion:
  617. i = 0
  618. IF (power = opower) AND (RND < .0003) THEN
  619.     i = ((auto + contact + liftoff + vert) = 0) AND ((min * 60 + sec) > t)
  620. IF fpl OR i THEN '                                                    force power loss
  621.     fpl = 0
  622.     powerloss = t + RND * t + ASO * 30 '                              10 TO 20%, 50% ASO
  623.     power = opower + powerloss / h * opower
  624.     mes$(0) = LTRIM$(STR$(powerloss)) + "% POWER LOSS - DUMP FUEL!"
  625.  
  626. IF lob THEN px! = px! + exv(2) '                                      landed on Borg
  627. IF contact OR inpause THEN GOTO other
  628.  
  629. ta = ((a + ma) + 270) MOD tsix '                                       temp angle = a+malfunction angle
  630. ma! = (vmass + fuel!) / th '                                          actually 54% fuel
  631. fo! = ((thrust! + super * 5) / ma!) / power '                         f = ma
  632. IF fuel! = 0 THEN fo! = 0 '                                           nix any force if running on empty
  633. fx! = fo! * c!(ta) / 2
  634. IF dump AND (ABS(a) < 5) THEN fx! = 0
  635. fy! = fo! * s!(ta) + grav! '                                          thrust + gravity
  636. IF warp! > 0 THEN fx! = fx! * (warp! * 2 + 1) '                       get thru warp msgs faster
  637. vx! = vx! - fx!
  638. IF a <> 0 THEN vx! = vx! + (RND - pf!) / h '                          help get to integer vx
  639. IF ABS(vx!) < .01 THEN vx! = 0
  640. avx = ABS(vx!)
  641. IF (avx > 5) AND (avx < 20) THEN xoff = vx! ELSE xoff = 0
  642. IF cut AND (magic = 0) THEN
  643.     cel! = TIMER - ctime! '                                           time since cut
  644.     vy! = cvy! + grav! * (cel! * cel!) '                              v = at^2  velocity = acceleration times time squared
  645.     fy! = 0 '                                                         null y force since it's a different situation
  646. vy! = vy! + fy!
  647. IF warp! >= 1 THEN vy! = 0
  648.  
  649. px! = px! + vx! - lob * exv(2)
  650. py! = py! + vy!
  651.  
  652. IF (liftoff = 0) AND (py! < 55) THEN '                                stop going off screen top
  653.     IF convo = 0 THEN mes$(0) = "Too high - reduce thrust!"
  654.     py! = 55
  655.     vy! = 0
  656.  
  657. other:
  658. GOSUB CalcFuel
  659. IF liftoff AND (lob = 0) THEN RETURN
  660. nomove = demo AND (((suri \ q3) + 1) = 5)
  661.  
  662. zz = px! - center
  663. z! = ABS(vx!)
  664.  
  665. IF (nomove = 0) AND ((rlink > 0) OR (z! < 3) OR (z! > 20)) THEN
  666.     dx! = px! - center
  667.     px! = center
  668.     tmt! = tmt! + dx!
  669.     zq = 0 '                                                          was 30 woof woof
  670.     c1 = (px! <= (gs + zq))
  671.     c2 = (px! >= (q3 - zq))
  672.     IF c1 OR c2 THEN
  673.         IF c1 THEN z = q3 - zq ELSE z = gs + zq
  674.         z = z - px!
  675.         tmt! = tmt! - z
  676.         px! = px! + z
  677.     ELSEIF (zz <> 0) AND (ABS(vx!) <= 5) AND (nomove = 0) THEN
  678.         z = zz \ 2 + 1
  679.         tmt! = tmt! + z
  680.         px! = px! - z
  681.     END IF
  682. IF ABS(tmt!) >= q3 THEN tmt! = SGN(tmt!) * q3 - 1
  683.  
  684. IF left THEN '                                                        jog left (shift left arrow)
  685.     IF left = 16 THEN sv! = vx!
  686.     IF left > 8 THEN a = 4 ELSE a = -4
  687.     left = left - 1
  688.     IF left = 0 THEN a = 0: vx! = sv!
  689. IF right THEN '                                                       jog right (shift right arrow)
  690.     IF right = 16 THEN sv! = vx!
  691.     IF right > 8 THEN a = -4 ELSE a = 4
  692.     right = right - 1
  693.     IF right = 0 THEN a = 0: vx! = sv!
  694.  
  695. CalcFuel:
  696. IF cut THEN thrust! = 0
  697. IF lockfuel = 0 THEN
  698.     ta = ABS(a): IF ta > 5 THEN ta = 5 '                              main angle, up to 5
  699.     z! = (ta + super + ABS(fst)) * t '                                plus 10% for thrusters
  700.     used! = (thrust! + z!) / 8000
  701.     IF ASO THEN used! = used! * 2 '                                   burn faster for AS
  702.     IF inpause THEN used! = 0
  703.     IF shield THEN used! = used! + .001
  704.     fuel! = fuel! - used! * 4
  705.     IF fuel! <= 0 THEN fuel! = 0: GOSUB CutOrOutOfFuel
  706.  
  707. Plotscreen:
  708. IF bit! = 0 THEN bit! = TIMER + pf!
  709. IF TIMER > bit! THEN
  710.     bbit = bbit XOR 1 '                                               toggles twice per second, used all over - instruments, IBM hazard lights, clock colon, LGM ear wiggle
  711.     bit! = 0
  712.  
  713. bolthit = 0
  714. bolthitf = 0
  715. IF (crash = 0) AND (ABS(vx!) >= h) THEN warp! = ABS(vx!) / h ELSE warp! = 0
  716. IF warp! >= 1 THEN paraf = 0 '                                        reckon parachute can be dropped at warp speeds
  717.  
  718. ' change styles every 10/30 seconds
  719. IF style! = 0 THEN style! = TIMER + t
  720. IF style! > 86400 THEN style! = 1 '                                   midnite xing
  721. IF TIMER > style! THEN
  722.     bstyle1 = (bstyle1 + 1) MOD 3 '                                   Borg guts every 10s
  723.     IF bstyle1 = 0 THEN bstyle2 = bstyle2 XOR 1 '                     Borg exhaust
  724.     style! = 0
  725.  
  726. IF (starstatus > 0) AND (eou = 0) AND (vert = 0) AND (RND > .9999) THEN '  stars on+not already falling+WHY?+rarely
  727.     mes$(0) = "THE SKY IS FALLING!  THE SKY IS FALLING!"
  728.     eou = 1
  729. GOSUB CalculateMotion
  730.  
  731. IF gs THEN '                                                          graphics start not 0, instruments are visible
  732.     VIEW
  733.     pif = (pif + 1) MOD (pdiv + 1)
  734.     IF pif THEN timemachine ELSE GOSUB Instruments '                  INSTRUMENTS
  735. IF starstatus THEN
  736.     VIEW SCREEN(gs, SGN(LEN(mes$(0))) * 20)-(q3, q4)
  737.     Stars '                                                           STARS
  738.     VIEW SCREEN(gs, 0)-(q3, q4)
  739.     VIEW SCREEN(gs, 0)-(q3, q4)
  740.     CLS
  741.  
  742. IF LEN(mes$(0)) THEN
  743.     VIEW SCREEN(gs, 0)-(q3, 20)
  744.     CLS
  745.     VIEW SCREEN(gs, 0)-(q3, q4)
  746.  
  747. Info '                                                                INFO show timed messages at top, if any
  748. IF warp! < 1 THEN '                                                   no sky features except star streaks at warp speeds
  749.     IF skyoff = 0 THEN GOSUB SkyStuff '                               CM/DS/Bo/BH/Wo/Co
  750.     GOSUB PlotGround '                                                GROUND/FEATURES
  751.     Shells '                                                          SHELLS
  752.     IF (invincible = 0) AND (shield = 0) AND (skyoff = 0) THEN GOSUB FiveWaysToDie
  753. IF platform THEN PUT (pminx, pminy), gbuff(), OR '                    falling descent stage
  754. IF LEN(dead$) = 0 THEN GOSUB PlotVehicle '                            VEHICLE
  755. IF (warp! < 1) AND showmap AND (crash = 0) THEN
  756.     VIEW
  757.     Map '                                                             LM, ground & sky features
  758.     VIEW SCREEN(gs, 0)-(q3, q4)
  759. IF bolthit THEN '                                                     lightning zap from Deathstar
  760.     boltc = boltc + 1 + (boltc = 9999)
  761.     rtl!(2) = TIMER + 5
  762.     rtlc(2) = boltc
  763.     IF ((invincible + shield) = 0) AND (boltc >= t) THEN dead$ = "Zapped!" '   by EPCOR!"
  764.  
  765. IF okrick AND (LEN(debug$) > 0) THEN LOCATE 1, 12: PRINT debug$;
  766. timemachine
  767.  
  768.  
  769. SkyStuff:
  770. IF (min = 3) AND (sec = 50) THEN '                                    Tree-fiddy! (Southpark), do black hole
  771.     ex(3) = suri + t
  772.     ey(3) = h
  773.     exv(3) = t
  774.     eyv(3) = 1
  775.  
  776. IF cmleaving THEN
  777.     exv(0) = exv(0) + 2
  778.     IF exv(0) = 0 THEN exv(0) = 1
  779.  
  780. RESTORE skycrud
  781. IF eou THEN mi = 2 ELSE mi = 5 '                                      end of universe, no celestial events
  782. FOR i = 0 TO mi '                                                     0CM 1DS 2Borg 3BH 4Worm 5Comet 6Al
  783.     READ g$, skyset1(i), skyset2(i)
  784.  
  785. FOR i = 0 TO mi + ufof '                                              0CM 1DS 2Borg 3BH 4Worm 5Comet 6Alien
  786.     xplus = skyset1(i): xminus = skyset2(i)
  787.     IF (i = 3) AND cbh THEN ek(i) = 0 '                               constant black hole
  788.     IF ek(i) = -1 THEN GOTO ni2
  789.  
  790.     IF (ey(i) > (q4 + 50)) OR (ey(i) < -50) OR (exv(i) = 0) THEN
  791.         ei(i) = 0 '                                                   ini
  792.         ek(i) = 9999
  793.         nx:
  794.         ex(i) = RND * q1
  795.         IF ABS(ex(i) - (px! + suri)) < q3 THEN GOTO nx '              start away from craft
  796.         IF ABS(ex(i) - px!) < q3 THEN GOTO nx '                       start away from craft
  797.         IF i = 2 THEN ex(i) = (ex(1) + 3200) MOD q1
  798.         ey(i) = 120 + RND * h '                                       random y 120-220
  799.         IF i = 0 THEN ey(i) = 22 '                                    CM
  800.         IF i = 1 THEN ey(i) = 170 '                                   DS
  801.         IF i = 2 THEN ey(i) = th '                                    Borg
  802.         '              0 1 2 3 4 5
  803.         '              CMDeBoBHWoCoAl
  804.         c1 = VAL(MID$("04010210120502", i * 2 + 1, 2)) '              min x velocity
  805.         c2 = VAL(MID$("09030210171005", i * 2 + 1, 2)) '              max x velocity
  806.         exv(i) = RND * (c2 - c1) + c1 '                               random in range
  807.         IF RND > pf! THEN exv(i) = -exv(i)
  808.  
  809.         z = VAL(MID$("00000003020100", i * 2 + 1, 2)) '               top range y velocity
  810.         eyv(i) = 0
  811.         IF z THEN eyv(i) = RND * (z - 1) + 1 '                        random in range
  812.  
  813.         IF RND > pf! THEN exv(i) = -exv(i)
  814.         IF RND > pf! THEN eyv(i) = -eyv(i)
  815.         IF (i = 3) AND cbh THEN
  816.             IF RND > pf! THEN
  817.                 ex(i) = suri - t
  818.                 exv(i) = t
  819.             ELSE
  820.                 ex(i) = suri + q3 + t
  821.                 exv(i) = -t
  822.             END IF
  823.         END IF
  824.     END IF
  825.  
  826.     ex(i) = ex(i) + exv(i)
  827.     ey(i) = ey(i) + eyv(i)
  828.  
  829.     IF ex(i) < 0 THEN
  830.         IF (i = 0) AND cmleaving THEN
  831.             ek(i) = -1: cmleaving = 0
  832.         ELSE
  833.             ex(i) = ex(i) + q1
  834.         END IF
  835.     END IF
  836.     IF ex(i) > q1 THEN
  837.         IF (i = 0) AND cmleaving THEN
  838.             ek(i) = -1: cmleaving = 0
  839.         ELSE
  840.             ex(i) = ex(i) - q1
  841.         END IF
  842.     END IF
  843.  
  844.     exl(i) = localize(ex(i), xplus, xminus)
  845.     IF (i = 3) AND cbh AND (exl(i) = 9999) THEN exv(i) = 0
  846.  
  847.     IF ek(i) <> -1 THEN ek(i) = 9999
  848.     IF exl(i) <> 9999 THEN
  849.         dx! = ABS(px! - exl(i))
  850.         dy! = ABS(py! - ey(i))
  851.         ek(i) = SQR(dx! * dx! + dy! * dy!)
  852.  
  853.         IF i = 0 THEN GOSUB CommandModule
  854.         IF i = 1 THEN DeathStar exl(i), f$(37)
  855.         IF i = 2 THEN Borg exl(i), ey(i)
  856.         IF i = 3 THEN
  857.             IF (LEN(mes$(0)) = 0) AND (showmap = 0) AND (cbh = 0) THEN
  858.                 mes$(0) = "DANGER, WILL ROBINSON, DANGER!"
  859.             END IF
  860.             IF sas = 0 THEN BlackHole 0
  861.             sas = 0
  862.         END IF
  863.         IF i = 4 THEN WormHole
  864.         IF i = 5 THEN
  865.             tx = localize(ex(5), 0, 0)
  866.             ty = ey(5)
  867.             Comet tx, ty
  868.         END IF
  869.         IF i = 6 THEN '                                               traditional alien - too silly
  870.             j = RND * h - h \ 2
  871.             z = ey(6) + j
  872.             IF (RND > .9) AND (z > h) AND (z < 250) THEN
  873.                 ey(6) = z
  874.                 alien = alien XOR 1
  875.                 ex(6) = ex(6) + 20 * SGN(alien - pf!)
  876.             END IF
  877.             UFO exl(6), ey(6), exv(6)
  878.         END IF
  879.     END IF
  880.     ni2:
  881.  
  882. FiveWaysToDie:
  883. IF (ek(2) >= 0) AND (ek(2) < 20) THEN '                               Borg
  884.     wu! = TIMER + 5
  885.     DO: _LIMIT mdelay
  886.         CLS
  887.         mes$(0) = "YOU ARE BORG"
  888.         Info
  889.         Borg exl(2), ey(2)
  890.         FOR i = 1 TO rp
  891.             p = POINT(LMrx(i), LMry(i))
  892.             IF p = black2 THEN c = green ELSE c = black2
  893.             PSET (LMrx(i), LMry(i)), c
  894.         NEXT i
  895.         timemachine
  896.     LOOP UNTIL TIMER > wu!
  897.     dead$ = "BORG"
  898.  
  899. IF (ek(3) >= 0) AND (ek(3) < 30) THEN '                               black hole
  900.     dead$ = "EATEN"
  901.     BlackHoleDoom
  902.  
  903. IF (ek(4) >= 0) AND (ek(4) < 30) THEN '                               wormhole
  904.     wu! = TIMER + 5
  905.     spx! = exl(4)
  906.     spy! = ey(4)
  907.     exv(4) = 0
  908.     eyv(4) = 0
  909.     wradar = radarf
  910.     radarf = 1
  911.     cut = 1
  912.     DO: _LIMIT mdelay
  913.         CLS
  914.         fb$ = ""
  915.         mes$(0) = "HOLY CRAP, BATMAN!"
  916.         mes$(1) = ""
  917.         Info
  918.         a = RND * 359
  919.         px! = spx! + (RND - pf!) * 20
  920.         py! = spy! + (RND - pf!) * 5
  921.         WormHole
  922.         LMdistort '                                                   optional
  923.         GOSUB PlotVehicle
  924.         timemachine
  925.     LOOP UNTIL TIMER > wu!
  926.     radarf = wradar
  927.     dead$ = "BATMAN"
  928.  
  929. IF (ek(5) >= 0) AND (ek(5) < 15) THEN dead$ = "HIT BY COMET"
  930. IF ufof AND (ek(6) >= 0) AND (ek(6) < 45) THEN dead$ = "HIT BY ALIEN"
  931.  
  932. GetAlt:
  933. alt! = (gety(-(rxm + wi2)) - ((sy1 + sy2) \ 2)) / 5
  934.  
  935. Instruments:
  936. osc = 8
  937. IF gs THEN LoadPanel '                                                graphics start not zero, instrument panel is on
  938. IF (warp! > 0) AND (contact = 0) THEN
  939.     IF warp! >= t THEN
  940.         dead$ = "WARP 10"
  941.         RETURN
  942.     END IF
  943.     RESTORE warp
  944.     FOR i = 1 TO INT(warp!)
  945.         READ z$
  946.     NEXT i
  947.     w$ = LTRIM$(STR$(INT(warp! * h) / h))
  948.     IF LEN(w$) = 1 THEN w$ = w$ + ".00"
  949.     IF LEN(w$) = 3 THEN w$ = w$ + "0"
  950.     mes$(0) = "WARP " + w$ + " - " + z$
  951.     IF gs AND ((TIMER MOD t) > 5) THEN
  952.         Henonp f
  953.         Wave '                                                        osc = 5 if commented out
  954.         AuHoVe auto, hover, vert, lam
  955.         GOTO clock
  956.     END IF
  957.  
  958. IF gs = 0 THEN RETURN '                                               graphics start of 0 means the instrument panel is off
  959.  
  960. IF panelinit = 0 THEN
  961.     IF crash THEN f = 15 ELSE f = ((f + 1) MOD 5) + t '               title graphic/face
  962.  
  963. Henonp f '                                                            title graphic
  964.  
  965. LINE (0, 0)-(gs - 1, 3), blue2, BF '                                  clear map area
  966.  
  967. IF pdiv THEN '                                                        instrument update frequency 1-4, mainly a way to slow down erratic thrust display
  968.     j = 0
  969.     FOR i = 1 TO 18 '                                                 my name in Morse
  970.         p = VAL(MID$("002032023222300032", i, 1)) '                   Frost
  971.         IF p < 3 THEN LINE (14 + j, 2)-(14 + j + p, 2), white
  972.         j = j + p + 2
  973.     NEXT i
  974.  
  975. IF (contact + auto + hover + vert + liftoff) = 0 THEN
  976.     IF (vy! > .6) AND (-fy! < 0) THEN PrintVGA CHR$(24), 5, 241, red, black2
  977.     IF (vy! < .4) AND (-fy! > -.01) THEN PrintVGA CHR$(25), 5, 250, yellow, black2
  978.  
  979. AuHoVe auto, hover, vert, lam
  980.  
  981. IF tfollow THEN '                                                     terrain following!
  982.     FOR ty = glmax - 20 TO glmax
  983.         FOR tx = 0 TO gs - 1
  984.             IF POINT(tx, ty) = blue THEN PSET (tx, ty), red '         red bg
  985.         NEXT tx
  986.     NEXT ty
  987.     FOR i = 0 TO 4 '                                                  TF
  988.         p& = VAL("&H" + MID$("E744464444", i * 2 + 1, 2))
  989.         LINE (2, 339 + i)-(10, 339 + i), green, , p& * 128
  990.     NEXT i
  991.  
  992. osc = 0
  993. c = LEDc
  994. IF (sbest! >= h) OR powerloss THEN c = red
  995. z! = thrust!: IF z! > h THEN z! = h '                                 200 at liftoff, show 100
  996. PrepAndShowLED z!, 3, 1 '                                             thrust osc1
  997. PrintCGA "T", 5, -1, c, -blue, 0 '                                    T is for flame
  998. i = LEDc: j = black
  999. IF jitter THEN SWAP i, j '                                            thrust calc type
  1000. LINE (4, 231)-(5, 232), i, B '                                        left light  (on = slow)
  1001. LINE (13, 231)-(14, 232), j, B '                                      right light (on = fast)
  1002. Bar z! / h, 0
  1003.  
  1004. c = dcolor(vy!, 2, 3, 1) '                                            vy osc2
  1005. z! = vy!
  1006. IF ABS(z!) > 99.97 THEN z! = 99.99
  1007. PrepAndShowLED z!, 3, 2
  1008. PrintCGA "V", 5, -1, c, -blue2, 0
  1009. z! = (z! + 3) / 6
  1010. Bar z!, 1
  1011.  
  1012. c = dcolor(vx!, 2, 3, 1) '                                            vx osc3
  1013. IF warp! THEN
  1014.     z! = warp!
  1015.     z! = vx! + rfs!
  1016. PrepAndShowLED z!, 3, 2
  1017. PrintCGA "H", 5, -1, c, -blue, 0
  1018. z! = (z! + 3) / 6
  1019. Bar z!, 1
  1020.  
  1021. GOSUB GetAlt '                                                        alt osc4
  1022. IF contact AND (alt! > 0) THEN alt! = 0
  1023. c = dcolor(alt!, t, 3, -1)
  1024. PrepAndShowLED alt!, 4, 1
  1025. PrintCGA "A", 5, -1, c, -blue2, 0
  1026. IF warp! OR (radarf = 0) THEN z! = 0 ELSE z! = alt! / 60
  1027. Bar z!, 0
  1028.  
  1029. c = dcolor(fuel!, t, 5, -1) '                                         fuel osc5
  1030. PrepAndShowLED fuel!, 4, 1
  1031. PrintCGA "F", 5, -1, c, -blue, 0
  1032. z! = fuel! / h
  1033. Bar z!, 0
  1034.  
  1035. clock:
  1036. IF TIMER < start2! THEN start2! = TIMER '                             midnite crossing
  1037. IF crash = 0 THEN el! = el! + (TIMER - start2!) '                     elapsed time
  1038. start2! = TIMER
  1039. IF el! >= 1 THEN
  1040.     WHILE el! >= 1 '                                                  catch-up
  1041.         el! = el! - 1
  1042.         sec = (sec + 1) MOD 60
  1043.         IF sec = 0 THEN min = (min + 1) MOD 99
  1044.     WEND
  1045.     IF sec MOD 5 = 0 THEN '                                           change title graphic
  1046.         IF crash THEN f = 15 ELSE f = ((f + 1) MOD 5) + t
  1047.     END IF
  1048. z$ = RIGHT$("0" + LTRIM$(STR$(min)), 2) + RIGHT$("0" + LTRIM$(STR$(sec)), 2)
  1049. osc = 6
  1050. LEDdisplay z$ '                                                       clock osc6
  1051.  
  1052. i = suri + px!
  1053. j = ABS(i - sf(5, 2))
  1054. k = sf(5, 2) + (q1 - i)
  1055. IF j <= 3200 THEN dtm! = j ELSE dtm! = k
  1056. PrepAndShowLED dtm!, 4, 0 '                                           dtm osc7
  1057. PrepAndShowLED CSNG(speed), 4, 0 '                                    speed osc8
  1058. ShowAngle a '                                                         angle osc9
  1059. panelinit = 1
  1060.  
  1061. LMcolors: '                                                           optional
  1062. IF contact OR (vx! = 0) THEN lbit = 0
  1063. IF (contact + vx!) = 0 THEN
  1064.     v1 = RND * 3
  1065.     v2 = RND * 3
  1066.     SWAP LMci(v1), LMci(v2)
  1067. FOR i = 1 TO rp '                                                     right pad
  1068.     oc = LMoc(i)
  1069.     LMc(i) = oc
  1070.     IF (oc = craft) OR (oc = red) THEN '                              shadow
  1071.         zx = LMrx(i) - px! + 2 - xoff * (inpause = 0)
  1072.         zy = LMry(i) - py!
  1073.         IF (oc = craft) AND ((warp! > 0) OR (zy > zx)) THEN
  1074.             tc = gray2
  1075.         ELSE
  1076.             tc = oc
  1077.         END IF
  1078.         LMc(i) = tc
  1079.     END IF
  1080.     IF (i < 279) AND (LMoc(i) = black2) THEN '                        Ascent stage cycle
  1081.         lbit = (lbit + 5) MOD 4
  1082.         LMc(i) = LMci(lbit)
  1083.     END IF
  1084. lbit = lbit - (vx! > 0) * 2 + ASO * t
  1085.  
  1086. PlotVehicle:
  1087. IF warp! < 1 THEN
  1088.     wda = 0
  1089.     px! = wx!: py! = wy!
  1090.     wda = warp! * 5 * s!((px! + 40) MOD tsix)
  1091.  
  1092. IF crash THEN
  1093.     FOR i = 1 TO rp
  1094.         PSET (LMrx(i), LMry(i)), LMc(i)
  1095.     NEXT i
  1096.     GOTO endproc
  1097.  
  1098. IF bolthit = 0 THEN GOSUB LMcolors
  1099.  
  1100. i = sf(4, 2) - 50 '                                                   left of volcano
  1101. j = sf(4, 2) + 50 '                                                   right of volcano
  1102. k = suri + px! '                                                      LM position
  1103. IF (k > i) AND (k < j) THEN '                                         in the locality?
  1104.     c = 0 '                                                           count
  1105.     FOR ty = py! + 8 TO py! + 18 '                                    leg/nozzle area
  1106.         FOR tx = px! - 17 TO px! + 17
  1107.             p = POINT(tx, ty) '                                       what color is the pixel?
  1108.             c = c - (p = orange) '                                    hot lava
  1109.         NEXT tx
  1110.     NEXT ty
  1111.     ' LINE (px! - 17, py! + 8)-(px! + 17, py! + 18), yellow, B '      diagnostics
  1112.     IF c THEN '                                                       contacted some lava
  1113.         FOR i = rp TO 1 STEP -1 '                                     from the bottom
  1114.             IF LMoc(i) = craft THEN '                                 is normal color?
  1115.                 LMoc(i) = red '                                       make red
  1116.                 nred = nred + 1 '                                     keep track of count
  1117.                 c = c - 1
  1118.                 IF c = 0 THEN EXIT FOR '                              enough
  1119.             END IF
  1120.         NEXT i
  1121.     END IF
  1122.  
  1123. IF nred = 0 THEN '                                                    number red
  1124.     temp = 0
  1125.     rtlc(1) = 0
  1126.     IF ASO THEN z = 115 ELSE z = 223 '                                max that COULD be normal
  1127.     otemp = temp
  1128.     temp = (nred * h / z) MOD 101 '                                   temperature
  1129.     rtlc(1) = temp
  1130.     IF temp > otemp THEN rtl!(1) = TIMER + 5
  1131.     c = 24 '                                                          gasoline
  1132.     IF temp > 30 THEN c = 32 '                                        dark red
  1133.     IF temp > 60 THEN c = 4 '                                         red
  1134.     IF temp = h THEN c = 15 '                                         white
  1135.     IF bw = 0 THEN PALETTE gasoline, c
  1136.     IF (temp = h) AND (invincible = 0) THEN dead$ = "FRIED BY VOLCANO"
  1137.     FOR i = 0 TO 20 '                                                 cool down some
  1138.         j = RND * rp
  1139.         IF LMoc(j) = red THEN LMoc(j) = craft: nred = nred - 1
  1140.     NEXT i
  1141.  
  1142. n = rp '                                                              last pixel = right pad
  1143. IF fuel! > 0 THEN GOSUB Exhaust '                                     maybe vehicle only
  1144.  
  1145. IF n > maxn THEN maxn = n
  1146.  
  1147. ta = a + ma '                                                         temp a = a + malfunction
  1148. zz = ta * -(ABS(ta) > 4) '                                            rotate beyond 5 degrees
  1149. ta = (zz + wda + tsix) MOD tsix '                                             keep in array bounds
  1150. c! = c!(ta) '                                                         cosine
  1151. s! = s!(ta) '                                                         sine
  1152. ta = zz '                                                             angle to use
  1153.  
  1154. rfx = 0 '                                                             optional craft jitter
  1155. rfy = 0
  1156. rfs! = 0 '                                                            random change in vx
  1157. IF (jitter = 1) AND (cut = 0) THEN '                                  not slow or engine cut
  1158.     IF (RND > .9) AND (a = 0) THEN '                                  a = angle
  1159.         IF RND > pf! THEN rfx = 1 ELSE rfx = -1 '                     half right, half left
  1160.         rfs! = rfx * .01 * (INT(RND * 9) + 1) '                       how much? .01 - .09
  1161.     END IF
  1162.     IF RND > .9 THEN '                                                y jitter, 1 chance in 10
  1163.         IF RND > pf! THEN rfy = 1 ELSE rfy = -1 '                     half down, half up
  1164.     END IF
  1165.  
  1166. IF doclock THEN
  1167.     i = VAL(MID$(TIME$, 1, 2))
  1168.     j = VAL(MID$(TIME$, 4, 2))
  1169.     k = VAL(MID$(TIME$, 7, 2))
  1170.     clocka(0) = (i + j / 60) * 30 '                                   hour hand
  1171.     clocka(1) = j * 6 '                                               minute hand
  1172.     clocka(2) = k * 6 '                                               seconds
  1173.     FOR z = 0 TO 2 '                                                  prep for radians
  1174.         clocka(z) = (clocka(z) + 270) MOD tsix
  1175.     NEXT z
  1176.     ao = 0 '                                                          angle offset
  1177.     ao = (ao + 1) MOD 361
  1178.  
  1179. tvx = SGN(vx!): IF tvx = 0 THEN tvx = 1
  1180. tao = ao * tvx
  1181. sco = sco XOR 1
  1182. IF doclock THEN sco = 0
  1183. IF sco THEN tc = red ELSE tc = lmsl
  1184. z3 = tsix + (shield = 0) * 361
  1185. FOR z2 = 0 TO z3
  1186.     a2 = (z2 + tao * 5 + tsix0) MOD tsix
  1187.     tx = px! + 50 * c!(a2) * aspect!
  1188.     ty = py! + 50 * s!(a2)
  1189.     IF ty < gety(tx) THEN
  1190.         IF (z2 MOD 30) = 0 THEN
  1191.             CIRCLE (tx, ty), 1, tc, , , .75
  1192.             IF geof THEN
  1193.                 FOR i = z2 - 120 TO z2 STEP 30
  1194.                     j = (i + tsix) MOD tsix
  1195.                     tx2 = px! + 60 * c!(j) * aspect!
  1196.                     ty2 = py! + 60 * s!(j)
  1197.                     LINE (tx, ty)-(tx2, ty2), tc
  1198.                 NEXT i
  1199.             END IF
  1200.         END IF
  1201.         IF doclock THEN
  1202.             FOR i = 0 TO 2
  1203.                 IF a2 = clocka(i) THEN
  1204.                     c = VAL(MID$("021404", i * 2 + 1, 2))
  1205.                     CIRCLE (tx, ty), 4 - i, c, , , .75
  1206.                     PAINT (tx, ty), c, c
  1207.                 END IF
  1208.             NEXT i
  1209.         END IF
  1210.     END IF
  1211. NEXT z2
  1212.  
  1213. FOR i = 1 TO rp '                                                     rp = craft right pad
  1214.     LMrx(i) = px! + LMx(i) * c! + LMy(i) * s! + rfx '                 x rotated
  1215.     LMry(i) = py! - LMx(i) * s! + LMy(i) * c! + rfy '                 y rotated
  1216.     IF LMry(i) > glmax THEN LMry(i) = glmax '                         not below ground
  1217.     IF i = xp THEN sx0 = LMrx(i): sy0 = LMry(i) '                     save radar loc
  1218.     IF i = lp THEN sx1 = LMrx(i): sy1 = LMry(i) '                     save left pad loc
  1219.     IF i = rp THEN sx2 = LMrx(i): sy2 = LMry(i) '                     save right pad loc
  1220.     IF bolthit THEN LMc(i) = white
  1221.     PSET (LMrx(i), LMry(i)), LMc(i)
  1222.  
  1223. IF fuel! < 95 THEN GOSUB flevel
  1224.  
  1225. eflag = 0 '                                                           determine flame climb
  1226. fx1 = 0 ' initialize for deflect
  1227. fx2 = 0
  1228. phg = (sx1 + sx2) \ 2 + ta * 2 '                                      point hit ground
  1229.  
  1230. tty! = py! + 26
  1231.  
  1232. FOR i = rp + 1 TO n '                                                 flame/fuel dump
  1233.     x = px! + LMx(i) * c! + LMy(i) * s! + rfx '                       x rotated
  1234.     y = py! - LMx(i) * s! + LMy(i) * c! + rfy '                       y rotated
  1235.     c = LMc(i) '                                                      fuel dump/flame
  1236.     IF warp! < 1 THEN GOSUB deflect '                                 deflect off ground
  1237.     c = ABS(c) '                                                      color
  1238.     PSET (x, y), c '                                                  flame particle
  1239.     IF i <= n3 THEN '                                                 main exhaust
  1240.         IF (i MOD t) = 1 THEN '                                       every 10th pixel
  1241.             LINE (x - 1, y)-(x + 1, y), c '                           make "+"
  1242.             LINE (x, y - 1)-(x, y + 1), c
  1243.         END IF
  1244.     END IF
  1245.  
  1246. IF rfx AND dump AND (a = 0) THEN vx! = vx! + rfs! '                   make jitter real
  1247. IF rfx AND (dump = 0) AND (a <> 0) THEN vx! = vx! + rfs!
  1248.  
  1249. endproc:
  1250.  
  1251. IF doclock THEN TextOnLM$ = LEFT$(TIME$, 5)
  1252. IF LEN(TextOnLM$) THEN GOSUB TextOnLM
  1253.  
  1254. GOSUB radar
  1255.  
  1256. fc = 0 '                                                              LGM flame count
  1257. IF (sf(3, 1) >= suri) AND (sf(3, 0) < (suri + q3)) THEN
  1258.     x1 = sf(3, 0) - suri
  1259.     y1 = gety(x1) - 14
  1260.     FOR x = x1 + 5 TO x1 + 15
  1261.         FOR y = y1 - 9 TO y1 + 12
  1262.             IF POINT(x, y) = yellow THEN fc = fc + 1
  1263.         NEXT y
  1264.     NEXT x
  1265.  
  1266. GOSUB KillThreats
  1267.      
  1268. geof = geof - 1 - (geof = 0)
  1269.  
  1270. IF ok AND (TIMER > wu2!) AND (INSTR(mes$(0), "IN CAR") = 0) THEN FlagandFireworks
  1271.  
  1272. mpass& = mpass& + 1
  1273. IF TIMER <= start1! THEN start1! = TIMER: mpass& = 1
  1274. speed = ((TIMER - start1!) / mpass&) * h * t
  1275.  
  1276. IF rick THEN GraphSpeed
  1277.  
  1278. IF magic = 1 THEN '                                                   magic landing, 1st step laser the surface to level
  1279.     sf = 0
  1280.     z = suri + px!
  1281.     IF z > q1 THEN z = z - q1
  1282.     sf(0, 0) = z - 35 '                                               cut out a swath 70 units wide
  1283.     sf(0, 1) = z + 35
  1284.     GOSUB lsurface '                                                  apply laser
  1285.     a = 0 '                                                           angle
  1286.     auto = 0 '                                                        autopilot
  1287.     vx! = 0 '                                                         cancel any x velocity
  1288.     vy! = 0 '                                                         cancel any y velocity
  1289.     py! = 331 + ASO * 9 '                                             ground has been cut to the lowest
  1290.     cut = 1 '                                                         signal engine off
  1291.     magic = 2
  1292.  
  1293. '                                                                     kill surface feature
  1294. IF firel AND ksf AND (contact = 0) AND (sf(sf, 2) > 0) THEN
  1295.     GOSUB lsurface
  1296. firel = ks '                                                          ks = keep shooting
  1297.  
  1298. '                                                                     terrain following
  1299. IF tfollow AND (contact = 0) AND (dump = 0) AND (liftoff = 0) THEN
  1300.     hover = 1
  1301.     hp = q1
  1302.     svx = SGN(vx!)
  1303.     IF svx < 0 THEN tx = sx1 ELSE tx = sx2
  1304.     la = ABS(vx!) * t
  1305.     IF la < t THEN la = t
  1306.     IF la > h THEN la = h
  1307.     FOR i = -(wi + 5) TO la
  1308.         j = tx + i * svx
  1309.         k = j
  1310.         IF k < 0 THEN k = k + q1
  1311.         IF k > q1 THEN k = k - q1
  1312.         z = gety(k)
  1313.         IF z < hp THEN hp = z: sx = j
  1314.     NEXT i
  1315.     cx = ABS(sx - tx)
  1316.     IF cx THEN
  1317.         cy = hp - t - ABS(a / 2) - sy1
  1318.         st! = cy / cx * (ABS(vx!) + 1)
  1319.         IF st! > 2 THEN st! = 2
  1320.         IF st! < -t THEN st = -t
  1321.         fst = -SGN(st!) * 2
  1322.         py! = py! + st!
  1323.         IF py! < 250 THEN py! = 250
  1324.     END IF
  1325. IF paraf THEN
  1326.     IF py! > 150 THEN mes$(0) = "Parachutes don't work in a vacuum!"
  1327.     Parachute
  1328.  
  1329.  
  1330. TextOnLM:
  1331. IF (ASO = 0) AND (ABS(ta) < t) THEN
  1332.     lt = LEN(TextOnLM$)
  1333.     tx = px! - lt * 2 + rfx
  1334.     ty = py! + rfy
  1335.     IF ty > 340 THEN ty = 340
  1336.     TinyFont TextOnLM$, tx, ty, white
  1337. TextOnLM$ = ""
  1338.  
  1339. KillThreats:
  1340. killed = 0
  1341. FOR i = 0 TO 20 '                                                     shells
  1342.     c1 = shield AND (shx(i) > 0) AND (shd(i) < 70) '                  shield on and shell close to LM
  1343.     c2 = firel AND (shx(i) > 0) '                                     fire laser and shell in air
  1344.     IF c1 OR c2 THEN
  1345.         killed = 1 '                                                  found something to kill
  1346.         tx = shx(i) - suri
  1347.         ty = shy(i)
  1348.         GOSUB LMfl '                                                  fl = fire laser
  1349.         IF LEN(dead$) THEN RETURN
  1350.         ExplodeShell i
  1351.     END IF
  1352.  
  1353. ks = 0
  1354. FOR i = 1 TO 6
  1355.     IF skyoff OR (ek(i) = -1) THEN GOTO ni3
  1356.     '                   CM DS BO BH WO Co
  1357.     IF firel AND (exl(i) > gs) AND (exl(i) < q3) THEN
  1358.         killed = 1
  1359.         ks = 1
  1360.         tx = exl(i)
  1361.         ty = ey(i)
  1362.         IF laserb = 0 THEN laserb = 5
  1363.         IF laserb > 0 THEN
  1364.             GOSUB LMfl
  1365.             IF LEN(dead$) THEN RETURN
  1366.             k = (5 - laserb) * 4
  1367.             IF i > 1 THEN
  1368.                 CIRCLE (tx, ty), k, yellow
  1369.                 PAINT (tx, ty), yellow, yellow
  1370.             END IF
  1371.             laserb = laserb - 1
  1372.         END IF
  1373.         IF laserb = 0 THEN
  1374.             ks = 0
  1375.             IF i = 1 THEN
  1376.                 mes$(1) = "The Dark Side has cookies!"
  1377.             ELSE
  1378.                 FOR a2 = 0 TO tsix STEP 2
  1379.                     x2 = tx + RND * h * c!(a2) * aspect!
  1380.                     y2 = ty + RND * h * s!(a2)
  1381.                     LINE (tx, ty)-(x2, y2), gold
  1382.                 NEXT a2
  1383.                 ek(i) = -1
  1384.                 exv(i) = 0
  1385.                 exl(i) = -1
  1386.                 IF (i = 2) AND lob THEN dead$ = "SELF-DESTRUCT"
  1387.             END IF
  1388.         END IF
  1389.     END IF
  1390.     ni3:
  1391. IF killed THEN ksf = 0 ELSE ksf = 1
  1392.  
  1393. lsurface: '                                                           laser surface feature
  1394. z = (RND > .9) OR (magic = 1) '                                       1 out of 10 destroys, magic always
  1395. FOR i = sf(sf, 0) TO sf(sf, 1)
  1396.     tx = i - suri
  1397.     IF tx < 0 THEN tx = tx + q1
  1398.     ty = gety(tx)
  1399.     IF sf <> 3 THEN ty = ty + RND * (q4 - ty)
  1400.     IF i MOD 2 THEN GOSUB LMfl '                                      fire laser
  1401.     IF z THEN gh(i) = glmax '                                         level
  1402.     Smooth sf(sf, 0) - 1 '                                            smooth transition from where the ground has been leveled, left side
  1403.     Smooth sf(sf, 1) '                                                                                                        , right side
  1404.     sf(sf, 2) = -1
  1405.  
  1406. LMfl: '                                                               fire laser
  1407. IF (cwd < 50) AND (sy1 > szs) THEN '                                  in car wash?
  1408.     dead$ = "REFLECTED LASER"
  1409.     cwd = 999
  1410.     firel = 0
  1411.     laserb = 0
  1412.     ks = 0
  1413.     RETURN
  1414. FOR zx = -1 TO 1
  1415.     FOR zy = -1 TO 1
  1416.         LINE (sx0 + zx, sy0 + zy)-(tx, ty), lmsl
  1417.     NEXT zy
  1418. NEXT zx
  1419. geof = t
  1420.  
  1421. flevel: '                                                             make fuel level when angle > 4
  1422. IF ASO THEN RETURN '                                                  no fuel shown with AS
  1423. ptk = (h - fuel!) * 2.7 '                                             pixels to kill
  1424. z = ptk '                                                             ptk used by ExplodeLM
  1425. x1 = px! - 16
  1426. x2 = px! + 14
  1427. y1 = py! - 15
  1428. y2 = py! + 15
  1429. FOR y = y1 TO y2
  1430.     FOR x = x1 TO x2
  1431.         IF POINT(x, y) = fuel THEN
  1432.             PSET (x, y), black2
  1433.             z = z - 1
  1434.         END IF
  1435.     NEXT x
  1436.     IF z <= 0 THEN EXIT FOR
  1437.  
  1438. deflect: '                                                            flame bounce
  1439. oz = gety(-x)
  1440. IF deflectat > 0 THEN oz = deflectat
  1441. z = oz
  1442.  
  1443. '       dump           side t      st in pause
  1444. IF (c = fuel) OR (c = -yellow) OR (c = -blue) THEN
  1445.     IF (fx1 > 0) AND (x < fx1) THEN z = 0
  1446.     IF (fx2 > 0) AND (x > fx2) THEN z = 0
  1447.     rf1 = RND * t + 1
  1448.     rf2 = RND * 20 - t
  1449.     IF y >= (z - 1) THEN '                                            yep, deflect it
  1450.         IF x < sx1 THEN
  1451.             IF fx1 = 0 THEN fx1 = x: fy1 = LMry(th1)
  1452.             x = fx1 + rf1
  1453.             y = fy1 + rf2
  1454.         ELSE
  1455.             IF fx2 = 0 THEN fx2 = x: fy2 = LMry(th2)
  1456.             x = fx2 - rf1
  1457.             y = fy2 + rf2
  1458.         END IF
  1459.     END IF
  1460.     RETURN
  1461.  
  1462. IF y >= (z - 1) THEN '                                                yep, deflect it
  1463.     IF sy1 < borgt THEN ky1 = 1: GOTO isborg
  1464.     IF eflag = 0 THEN '                                               limit flame climbing
  1465.         eflag = 1 '                                                   only once per position
  1466.         xmin2 = phg - thrust! * 1.5 '                                 point hit ground
  1467.         xmax2 = phg + thrust! * 1.5
  1468.         u1 = 0 '                                                      up count l of nozzle
  1469.         u2 = 0 '                                                      up count r of nozzle
  1470.         wu1 = 0 '                                                     worst l up count
  1471.         wu2 = 0 '                                                     worst r up count
  1472.         ky1 = 0 '                                                     keep y
  1473.         ky2 = 0 '                                                     keep y
  1474.         FOR zz = phg TO phg - h STEP -1 '                             from LM center left
  1475.             z2 = gety(-zz): IF zz = phg THEN lz = z2
  1476.             k1 = z2 - lz
  1477.             lz = z2
  1478.             IF k1 > 0 THEN '                                          down
  1479.                 u1 = 0
  1480.             ELSE
  1481.                 u1 = u1 - k1 '                                        up
  1482.                 IF u1 > wu1 THEN wu1 = u1 '                           worst up
  1483.             END IF
  1484.             IF u1 > 20 THEN xmin2 = zz + 2: EXIT FOR
  1485.             IF ABS(k1) > 20 THEN ky1 = 1 '                            90 degrees TMA etc
  1486.         NEXT zz
  1487.         FOR zz = phg TO phg + h '                                     from LM center right
  1488.             z2 = gety(-zz): IF zz = phg THEN lz = z2
  1489.             k2 = z2 - lz
  1490.             lz = z2
  1491.             IF k2 > 0 THEN '                                          down
  1492.                 u2 = 0
  1493.             ELSE
  1494.                 u2 = u2 - k2 '                                        up
  1495.                 IF u2 > wu2 THEN wu2 = u2 '                           worst up
  1496.             END IF
  1497.             IF u2 > 20 THEN xmax2 = zz - 2: EXIT FOR
  1498.             IF ABS(k2) > 20 THEN ky2 = 1 '                            90 degrees TMA etc
  1499.         NEXT zz
  1500.     END IF
  1501.  
  1502.     isborg:
  1503.     r = thrust! * 2 + (RND - pf!) * 80
  1504.     x = (phg - r) + RND * (r * 2)
  1505.     k = ABS(x - phg + a * 2) / 4
  1506.  
  1507.     tx = x + suri '                                                   McDonalds
  1508.     IF (tx >= sf(5, 0)) AND (tx <= sf(5, 1)) AND (py! > 250) THEN
  1509.         ky1 = 0: ky2 = 0
  1510.     END IF
  1511.  
  1512.     IF (ky1 = 1) OR (ky2 = 1) THEN '                                  keep
  1513.         y = z - RND * k - 1: RETURN
  1514.     END IF
  1515.  
  1516.     x2 = (RND - pf!) * 20
  1517.     IF x < xmin2 THEN x = xmin2 + RND * (xmax2 - xmin2) + x2
  1518.     IF x > xmax2 THEN x = xmin2 + RND * (xmax2 - xmin2) - x2
  1519.  
  1520.     IF (platform > 0) AND (ABS(px! - (pminx + 17)) < 20) THEN
  1521.         y = y - platform
  1522.     ELSE
  1523.         y = gety(-x) - RND * k - 1
  1524.     END IF
  1525.  
  1526.     IF (deflectat > 0) AND (y > deflectat) THEN y = deflectat - (y - deflectat)
  1527.  
  1528. CWceiling: '                                                          car wash
  1529. cwd = ABS((suri + px!) - sf(2, 2)) '                                  car wash distance
  1530. IF ASO THEN szs = 323 ELSE szs = 340 '                                safe zone start
  1531. IF (cwd < 69) AND (sy1 > 304) THEN '                                  lower than top of building
  1532.     IF sy1 >= q4 THEN '                                               touched down inside
  1533.         cc1 = -1
  1534.     ELSEIF sy2 >= q4 THEN '                                           touched down inside
  1535.         cc2 = -1
  1536.     ELSEIF sy1 > szs THEN '                                           in safe zone
  1537.         cc1 = 0
  1538.         cc2 = 0
  1539.         IF cwd < 50 THEN mes$(0) = "Washee washee no starchee!"
  1540.     ELSE
  1541.         IF (sy1 > (szs - t)) AND (sy1 <= szs) THEN '                  bouncing off ceiling
  1542.             cc1 = 0
  1543.             cc2 = 0
  1544.             vy! = 1
  1545.             py! = py! + 2
  1546.             'hover = 1
  1547.         END IF
  1548.     END IF
  1549.  
  1550. CheckHit: '                                                           contact with ground
  1551. cc1 = ((sy1 + 1) >= gety(-sx1)) '                                     left pad
  1552. cc2 = ((sy2 + 1) >= gety(-sx2)) '                                     right pad
  1553. mingx = 0
  1554. mingy = q1
  1555. FOR zx = sx1 TO sx2 '                                                 check between pads
  1556.     zy = sy1 - 2
  1557.     p = POINT(zx, zy)
  1558.     IF p = gray THEN '                                                got 1
  1559.         ty = gety(-zx)
  1560.         IF ty < mingy THEN mingx = zx: mingy = ty
  1561.     END IF
  1562. NEXT zx
  1563. IF mingx THEN
  1564.     i = mingx - sx1
  1565.     j = sx2 - mingx
  1566.     IF i < j THEN cc1 = -1 ELSE cc2 = -1
  1567.  
  1568. GOSUB CWceiling '                                                     car wash
  1569. IF vy! < 0 THEN RETURN '                                              going UP
  1570.  
  1571. IF cc1 OR cc2 THEN '                                                  pad(s) on ground
  1572.     contact = 1
  1573.     tmt! = 0
  1574.     py! = py! + rfy '                                                 no time to correct jitter
  1575.     TexOnLM$ = ""
  1576.     warp! = 0
  1577.     GOSUB CutOrOutOfFuel
  1578.  
  1579.     IF (vy! > 0) AND ABS(sy1 - (ey(2) - 40)) < t THEN
  1580.         lob = 1 '                                                     landed on Borg
  1581.         vx! = vx! - exv(2)
  1582.     END IF
  1583.  
  1584.     IF (ABS(vx!) > t) OR (vy! > 20) THEN
  1585.         dead$ = "HIGH SPEED IMPACT!"
  1586.         RETURN
  1587.     END IF
  1588.  
  1589.     dp = 8 + (h - fuel!) \ 25 '                                       8 - 12
  1590.     IF (vy! > dp) OR (ABS(vx!) > 8) THEN '                            too fast given load
  1591.         crash = 1
  1592.         panelinit = 0
  1593.         shield = 0
  1594.         dead$ = "CRASHED"
  1595.         z = ABS(vx!) * t + ABS(vy!) * t
  1596.         FOR i = 1 TO rp '                                             create layer of debris
  1597.             LMrx(i) = LMrx(i) + RND * z - (z \ 2)
  1598.             LMry(i) = gety(LMrx(i)) - RND * 2 - 1
  1599.         NEXT i
  1600.         IF bw = 0 THEN
  1601.             PALETTE green, 0 '                                            blank instruments
  1602.             PALETTE yellow, 0
  1603.         END IF
  1604.         RETURN
  1605.     END IF
  1606.  
  1607.     IF (vy! > 3) OR (ABS(vx!) > 3) THEN fb$ = "vehicle damaged"
  1608.  
  1609.     IF (vy! > 4) OR (ABS(vx!) > 4) THEN
  1610.         fb$ = "vehicle severely damaged"
  1611.         LMdistort '                                                   randomly vary structure
  1612.         vsd = 1 '                                                     vehicle severely damaged
  1613.     END IF
  1614.  
  1615.     savea = a + ma
  1616.  
  1617.     IF lob THEN '                                                     landed on Borg
  1618.         a = 0
  1619.         IF sx1 < borgl THEN a = 45
  1620.         IF sx2 > borgr THEN a = -45
  1621.         py! = py! - t * (ABS(a) = 45)
  1622.         RETURN
  1623.     END IF
  1624.  
  1625.     '                                                                 optional, allow ANY part of pad
  1626.     IF cc1 THEN cd = -1: cpx = sx2: cpy = sy2 + 1
  1627.     IF cc2 THEN cd = 1: cpx = sx1: cpy = sy1 + 1
  1628.     FOR i = 1 TO 4
  1629.         cpx = cpx + cd
  1630.         IF (cpy >= gety(-cpx)) THEN
  1631.             IF cc1 THEN cc2 = 1 ELSE cc1 = 1
  1632.         END IF
  1633.     NEXT i
  1634.  
  1635.     IF NOT (cc1 AND cc2) THEN '                                       only 1 pad down
  1636.         npass = 0
  1637.         DO: _LIMIT mdelay * 2 '                                       settle LM
  1638.             a = a + (cc1 - cc2)
  1639.             pa:
  1640.             npass = npass + 1
  1641.             IF npass > 150 THEN EXIT DO
  1642.             GOSUB Plotscreen '                                        show change
  1643.             IF LEN(dead$) THEN EXIT DO
  1644.             IF ABS(a) > 40 THEN
  1645.                 a = 180 '                                             upside down
  1646.                 py! = glmax - ny
  1647.                 LMdistort '                                           optional
  1648.                 EXIT DO
  1649.             END IF
  1650.             IF cc1 AND (sy1 < gety(-sx1)) THEN py! = py! + 1: GOTO pa
  1651.             IF cc2 AND (sy2 < gety(-sx2)) THEN py! = py! + 1: GOTO pa
  1652.             cc3 = ((sy1 + 1) >= gety(-sx1))
  1653.             cc4 = ((sy2 + 1) >= gety(-sx2))
  1654.             IF ABS(a) > 80 THEN py! = glmax - wi2
  1655.  
  1656.             z = gety(INT(px!)) - py! - ny + 5
  1657.             IF (z < 0) AND (paraf = 0) THEN
  1658.                 dead$ = "PUNCTURE DAMAGE"
  1659.                 RETURN
  1660.             END IF
  1661.         LOOP UNTIL (cc1 AND cc4) OR (cc2 AND cc3)
  1662.     END IF
  1663.  
  1664. slimit: '                                                             surface index bounds
  1665. z = 0
  1666. IF suri < 0 THEN z = q1
  1667. IF suri >= q1 THEN z = -q1
  1668. suri = suri + z
  1669. IF lock1 THEN lock1 = lock1 + z
  1670.  
  1671. radar: '                                                              autopilot landing here too
  1672. IF contact OR liftoff THEN RETURN
  1673. z = SGN(vx!): IF z = 0 THEN z = 1
  1674. IF z = -1 THEN sbl = -280 ELSE sbl = 220
  1675. bt = (bt MOD 4) + 1
  1676. div = ABS(alt!) \ 2 + bt
  1677.  
  1678. IF right OR left THEN tvx! = sv! ELSE tvx! = vx!
  1679. IF ABS(tvx!) > 99 THEN tvx! = 99 * SGN(tvx!)
  1680. IF (tfollow = 0) AND (aboveborg OR ((radarf = 0) AND (auto = 0))) THEN tvx! = 0
  1681. bl = sbl * ABS(tvx!) + (sx1 - sx2)
  1682. IF ABS(bl) > ABS(sbl) THEN bl = sbl
  1683. IF auto = 0 THEN lock1 = 0
  1684. IF lock1 = 0 THEN rxm = sx2 + bl ELSE rxm = lock1 - suri
  1685.  
  1686. level = 1
  1687. FOR j = 0 TO wi '                                                     width (distance between pads)
  1688.     tx = rxm + j
  1689.     ty = gety(-tx)
  1690.     IF aboveborg AND (sx1 >= borgl) AND (sx2 <= borgr) THEN ty = borgt
  1691.     IF j = 0 THEN cmp = ty
  1692.     IF ABS(cmp - ty) > 1 THEN level = 0
  1693.  
  1694. IF level THEN
  1695.     IF auto AND (lock1 = 0) THEN '                                    automatic yet no current lock
  1696.         lock1 = suri + rxm - SGN(rxm) * 2 * (vx! <> 0) '              lock onto level ground
  1697.     END IF
  1698.     rbeam = green '                                                   radar beam color
  1699.     lock1 = 0 '                                                       not level, cancel lock
  1700.     rbeam = red '                                                     radar beam color
  1701.  
  1702. rpass = rpass XOR 1
  1703. IF level AND (vx! = 0) THEN
  1704.     div = div \ 2
  1705.     IF div < 1 THEN div = 1
  1706.     IF rpass THEN rbeam = 0
  1707.  
  1708. FOR i = 0 TO (wi + 1) STEP 5
  1709.     IF vx! > 0 THEN tx = rxm + i ELSE tx = rxm + wi - i
  1710.     IF aboveborg THEN
  1711.         tx = sx1 + i
  1712.         ty = borgt
  1713.     ELSE
  1714.         ty = gety(tx)
  1715.     END IF
  1716.     IF (warp! < 1) AND (ty > sy0) AND (radarf > 0) THEN GOSUB rbeam
  1717.  
  1718. IF auto = 0 THEN GOTO end6
  1719. IF aboveborg OR (abort = 0) THEN GOTO skipit
  1720.  
  1721. abort:
  1722. hover = 1
  1723. hoverc = 0
  1724. lock1 = 0
  1725.  
  1726. i = (py! > 120) '                                                     too low
  1727. j = NOT ((vx! = 0) AND (level = 1)) AND (ABS(vx!) < (ideal! - .05)) ' too slow
  1728. k = (ABS(vx!) > (ideal! + .05)) '                                     too fast
  1729. IF i THEN wa = -ma: hoverc = -3
  1730. IF j THEN wa = 4 * -z + ma
  1731.     wa = ABS(vx!) * z - ma
  1732.     IF ABS(wa) > 20 THEN wa = 20 * z
  1733. IF i OR j OR k THEN abort = 1: GOTO end6
  1734. abort = 0
  1735.  
  1736. skipit:
  1737. IF lam THEN '                                                         land at McDonalds
  1738.     dis = ABS((suri + rxm) - sf(5, 2))
  1739.     IF dis > 80 THEN level = 0: lock1 = 0
  1740. wa = -ma ' want angle = -malfunction angle
  1741.  
  1742. IF dflag THEN dump = 0: dflag = 0
  1743. IF level = 0 THEN '                                                   locked onto a target
  1744.     abort = 1
  1745.     ddd = ABS(px! - rxm)
  1746.     IF (ddd < 120) AND (lock1 > 0) AND (auto = 1) AND (fuel! > 70) THEN
  1747.         dump = 1
  1748.         dflag = 1
  1749.     END IF
  1750.     IF ddd < h THEN '                                                 100 clicks away
  1751.         hover = 0 '                                                   stop hovering
  1752.         vert = 1 '                                                    start moving down
  1753.         dist = sx1 - rxm '                                            distance to target
  1754.         thv! = ABS(dist) / 27 '                                       to horizontal velocity
  1755.         IF thv! < .08 THEN mu = 1 ELSE mu = 4
  1756.         IF thv! < .01 THEN mu = 0
  1757.         IF aboveborg = 0 THEN
  1758.             IF ABS(vx!) > thv! THEN wa = wa + mu * z
  1759.         END IF
  1760.     END IF
  1761. end6:
  1762. GOSUB angle
  1763.  
  1764. rbeam:
  1765. dx! = (tx - sx0) / div
  1766. dy! = (ty - sy0) / div
  1767. FOR j = 1 TO q1
  1768.     tx = sx0 + j * dx!
  1769.     ty = sy0 + j * dy!
  1770.     my = gety(-tx)
  1771.     IF ty >= my THEN
  1772.         IF (tx < rxm) OR (tx > (rxm + wi + 1)) THEN level = 0: rbeam = red
  1773.         EXIT FOR
  1774.     END IF
  1775.     IF i AND (rbeam > 0) THEN
  1776.         PSET (tx, ty), rbeam
  1777.         IF radarf = 2 THEN PSET (tx + 1, ty), rbeam
  1778.     END IF
  1779.  
  1780. angle:
  1781. cf = 0
  1782. IF a <> wa THEN '                                                     current angle, wanted angle
  1783.     w = a '                                                           was = angle
  1784.     a = a + SGN(wa - a)
  1785.     change = a - w
  1786.     IF change THEN
  1787.         cf = 1
  1788.         a1 = ABS(w + ma)
  1789.         a2 = ABS(a + ma)
  1790.         IF (a1 > 4) OR (a2 > 4) THEN wan = 3 '                        activate up/down
  1791.     END IF
  1792.      
  1793. IF liftoff OR ((auto = 0) AND (vert = 1) AND (ma = 0)) THEN RETURN
  1794. cp = (a <> 0) AND (RND < .01) '                                       clear problem
  1795.  
  1796. IF cf OR cp THEN
  1797.     IF cp OR (RND < .01) THEN
  1798.         z = ma
  1799.         IF cp THEN ma = 0 ELSE ma = a
  1800.         IF ma <> z THEN '                                             new malfunction angle
  1801.             IF ma THEN
  1802.                 z$ = LTRIM$(STR$(-ma))
  1803.                 IF ma < 0 THEN z$ = "+" + z$
  1804.                 mes$(0) = "DANGER! STUCK THRUSTER " + z$
  1805.                 IF auto THEN a = a - ma: wa = a - ma '                immediate correct
  1806.             ELSE
  1807.                 mes$(0) = "THRUSTERS OK"
  1808.                 IF auto THEN a = a + z: wa = a + z '                  immediate correct
  1809.             END IF
  1810.         END IF
  1811.     END IF
  1812.  
  1813. Exhaust:
  1814. IF inpause THEN tflame = blue ELSE tflame = flame
  1815.  
  1816. IF cut THEN thrust! = 0
  1817. d = thrust! - (RND * 20 - t) * (thrust! > 0)
  1818. x = (LMx(lp) + LMx(rp)) \ 2 '                                         halfway between pads
  1819.  
  1820. IF ASO THEN '                                                         ascent stage only
  1821.     i = 30 '                                                          divisor for exhaust width
  1822.     j = 1 '                                                           throwing x off up to this amount
  1823.     k = 3 '                                                           flame decrement
  1824.     y = ny + 1 '                                                      starting y
  1825.     i = 20 '                                                          divisor for exhaust width
  1826.     j = 2 '                                                           throwing x off up to this amount
  1827.     k = 2 '                                                           flame decrement
  1828.     y = ny - 3 '                                                      starting y
  1829.  
  1830. WHILE d > 0 '                                                         until thrust decremented to 0
  1831.     p = d \ i
  1832.     FOR z = -1 TO 1 STEP 2
  1833.         FOR jj = 0 TO 3
  1834.             n = n + 1 '                                               add to vehicle daa
  1835.             IF n > 1400 THEN END '                                    beyond array size
  1836.             LMx(n) = x + p * z + RND * (j * 2) - j
  1837.             LMy(n) = y + RND * 2
  1838.             IF (powerloss > 0) AND (RND < .3) THEN zz = orange ELSE zz = tflame
  1839.             LMc(n) = zz '                                             yellow normally, blue during pause
  1840.             IF RND > .95 THEN '                                        some way off plume for realism
  1841.                 LMx(n) = LMx(n) - RND * 80 + 40
  1842.                 LMy(n) = LMy(n) + 5
  1843.             END IF
  1844.         NEXT jj
  1845.     NEXT z
  1846.     y = y + 1 '                                                       next flame row
  1847.     d = d - k '                                                       decrement temp thrust
  1848. n3 = n '                                                              main/side thrusters
  1849.  
  1850. '                                                                     if there's a thruster malfunction, may have both thrusters active
  1851. IF (ma = 0) OR (a = 0) OR (SGN(a) = SGN(ma)) THEN
  1852.     ta = a + ma
  1853.     pass = 1
  1854.     ta = a
  1855.     pass = 2
  1856. IF dump THEN ta = t
  1857.  
  1858. dors: '                                                               dump fuel or sideways motion
  1859. IF liftoff THEN ta = 0
  1860. IF rfx AND (dump = 0) THEN ta = rfs! * 50
  1861. IF (contact = 1) AND (dump = 0) THEN ta = 0: wan = 0: super = 0
  1862. IF ta <> 0 THEN
  1863.     IF ta < 0 THEN th0 = th1: z! = -2
  1864.     IF ta > 0 THEN th0 = th2: z! = 2
  1865.     zz = ta: IF zz > t THEN ta = t
  1866.     tt = ABS(zz * 4 + 4 * SGN(ta))
  1867.     IF ABS(zz) > 20 THEN tt = t
  1868.     DO
  1869.         n = n + 1
  1870.         LMx(n) = LMx(th0) + z! + RND * 2 - 1
  1871.         LMy(n) = LMy(th0) + (RND * 2 - 1) * (ABS(ta) > 2)
  1872.         IF dump THEN
  1873.             tc = fuel
  1874.             z = 20 - 20 * s!(90 + (LMx(n) - LMx(th0)) * 1.8)
  1875.             IF a = 180 THEN z = -z
  1876.             LMy(n) = LMy(n) + z
  1877.         ELSE
  1878.             tc = -tflame
  1879.         END IF
  1880.         LMc(n) = tc
  1881.         tt = tt - 1
  1882.         z! = z! * 1.15
  1883.     LOOP UNTIL (tt = 0) OR (ABS(z!) > 40)
  1884.     IF dump THEN
  1885.         ta = -ta
  1886.         IF lockfuel = 0 THEN fuel! = fuel! - .1 + (fuel! > 5) * 2
  1887.         IF ta = -t THEN GOTO dors
  1888.         IF fuel! < 1 THEN dump = 0
  1889.     END IF
  1890. pass = pass - 1
  1891. IF pass THEN ta = ma: GOTO dors
  1892. noside:
  1893.  
  1894. '                                                                     super - use side thrusters to augment main thrust when more than
  1895. '                                                                     100% thrust is called for
  1896. IF fst OR super OR (wan > 0) THEN '                                   up/down to change angle beyond 5 degrees
  1897.     IF change > 0 THEN th1d = -1: th2d = 1
  1898.     IF change < 0 THEN th2d = -1: th1d = 1
  1899.     IF super THEN th1d = 1: th2d = 1
  1900.     IF fst THEN th1d = fst: th2d = fst: fst = 0
  1901.     FOR z = 0 TO 6
  1902.         n = n + 1
  1903.         LMx(n) = LMx(th1) + RND * 2
  1904.         LMy(n) = LMy(th1) + th1d * (z + RND * 2) + 2
  1905.         LMc(n) = tflame '                                             blue flame in pause
  1906.         n = n + 1 '                                                   other thruster opposite
  1907.         LMx(n) = LMx(th2) + RND * 2 - 2
  1908.         LMy(n) = LMy(th2) + th2d * (z + RND * 2) + 2
  1909.         LMc(n) = tflame
  1910.     NEXT z
  1911.     wan = wan - 1
  1912.     IF wan = 1 THEN change = -change
  1913.  
  1914.  
  1915. init1: '                                                              only done once
  1916. DATA convo,f1,f2,lmx1,lmy1,lmc1,lmx2,lmy2,lmc2
  1917. DATA h1,h2,h3,h4,h5,h6,cybill,surv2,cm,rad,af2,sf2,panel
  1918. DATA sd,sl,s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,panel0,panel1
  1919. DATA dstarm,stars,lanblank,alien
  1920.  
  1921. RESTORE init1
  1922. IF _FILEEXISTS("rick.") THEN okrick = 1
  1923. tc$ = UCASE$(COMMAND$ + "   ")
  1924. IF LEFT$(tc$, 1) = "/" THEN tc$ = "   "
  1925. IF INSTR(tc$, "DOS") THEN dosbox = 0 '                                use large star file
  1926. IF INSTR(tc$, "BOX") THEN dosbox = 1 '                                use small star file
  1927. IF INSTR(tc$, "CD ") THEN iscd = 1 '                                  simulate CD
  1928. IF INSTR(tc$, "UFO ") THEN ufof = 1 '
  1929. IF _FILEEXISTS("cd.dat") THEN iscd = 1 '                              include/create this file for CD/DVD distribution (read only)
  1930.  
  1931. z = 0
  1932. FOR i = 1 TO 40
  1933.     READ f$(i)
  1934.     IF i = 38 THEN '                                                  stars
  1935.         j = 2 - dosbox '                                              1=small, 2=medium, 3=huge
  1936.         f$(i) = f$(i) + CHR$(48 + j)
  1937.     END IF
  1938.     IF i THEN
  1939.         f$(i) = f$(i) + ".dat" '                                      try lowercase first
  1940.         IF _FILEEXISTS(f$(i)) = 0 THEN
  1941.             f$(i) = UCASE$(f$(i)) '                                   try uppercase (Linux cares!)
  1942.             IF _FILEEXISTS(f$(i)) = 0 THEN
  1943.                 z = z + 1
  1944.                 IF z = 1 THEN CLS
  1945.                 PRINT f$(i)
  1946.             END IF
  1947.         END IF
  1948.     END IF
  1949.     PRINT
  1950.     PRINT "Above file(s) missing"
  1951.     SLEEP
  1952.     SYSTEM
  1953.  
  1954. s& = VARSEG(p(0, 0))
  1955. o& = VARPTR(p(0, 0))
  1956. DEF SEG = s&
  1957. BLOAD "F1.dat", o&
  1958. z$ = "386C6C38" '                                                    degree symbol
  1959. FOR i = 0 TO 3
  1960.     p(0, i) = VAL("&H" + MID$(z$, i * 2 + 1, 2))
  1961.  
  1962. s& = VARSEG(p2(0, 0))
  1963. o& = VARPTR(p2(0, 0))
  1964. DEF SEG = s&
  1965. BLOAD "F2.dat", o&
  1966.  
  1967. canvas& = _NEWIMAGE(640, 350, 9)
  1968. SCREEN canvas&
  1969. _TITLE "Lander"
  1970. auto = 0 '                                                            full automatic
  1971. background = 1 '                                                      textured LED displays
  1972. cbh = 0 '                                                             constant black holes
  1973. darkstars = 1 '                                                       spin
  1974. darkstart = 1 '                                                       thickness of lines
  1975. demo = 0 '                                                            cram onto one page
  1976. doclock = 0 '                                                         shield effect
  1977. gh = 9
  1978. gs = 85 '                                                             graphics start
  1979. glmax = q4 '                                                          ground level max
  1980. glmin = glmax - 49 '                                                  ground level min
  1981. gs = 85 '                                                             graphics start (flying area)
  1982. 'gstyle = 5
  1983. invincible = 1 '                                                      easier for beginner, thrusters gold
  1984. jitter = 1 '                                                          thrust calc
  1985. LED$ = "021404120115" '                                               color sequence - gr ye re or gun wh
  1986. LEDc = green '
  1987. LEDtri = 0 '                                                          off
  1988. mdelay = t '                                                          master delay
  1989. opower = 62 '                                                         original thrust factor
  1990. pdiv = 0 '                                                            instrument update
  1991. radarf = 1
  1992. restart = 0 '                                                         shift-d load defaults
  1993. segs$ = "abcdefg" '                                                   for 7 segment displays
  1994. settings$ = "LANDER.SET"
  1995. shield = 0 '                                                          Star Trek!
  1996. showmap = 0 '                                                         silly legend at top
  1997. skyoff = 1 '                                                          DS, BH, Wo, Co
  1998. starfiles = 1 '                                                       dat1, dat2, dat3
  1999. starstatus = 1 '                                                      show stars only, no names/info
  2000. twinkle = 0
  2001. zoom = 1 '                                                            starfield 6 hours 45 degrees
  2002.  
  2003. black = 0: blue = 1: green = 2: gunmetal = 3: red = 4: gasoline = 5
  2004. gray2 = 6: white = 7: gray = 8: dred = 9: gold = 10: black2 = 11
  2005. orange = 12: blue2 = 13: yellow = 14: white2 = 15
  2006.  
  2007. craft = white: flame = yellow: fuel = gasoline: LEDc = green
  2008. LMci(0) = gray2 '                                                     ASO shifting colors
  2009. LMci(1) = gold
  2010. LMci(2) = gray2
  2011. LMci(3) = black2
  2012.  
  2013. IF _FILEEXISTS(settings$) THEN
  2014.     OPEN settings$ FOR INPUT AS #1
  2015.     nflags = 0
  2016.     DO
  2017.         IF EOF(1) THEN EXIT DO
  2018.         INPUT #1, g$
  2019.         IF EOF(1) THEN EXIT DO
  2020.         nflags = nflags + 1
  2021.         INPUT #1, tflags(nflags)
  2022.     LOOP
  2023.     CLOSE #1
  2024.  
  2025. auto = tflags(1)
  2026. background = tflags(2)
  2027. cbh = tflags(3)
  2028. demo = tflags(4)
  2029. doclock = tflags(5)
  2030. invincible = tflags(6)
  2031. jitter = tflags(7)
  2032. LEDc = tflags(8)
  2033. LEDtri = tflags(9)
  2034. radarf = tflags(10)
  2035. shield = tflags(11)
  2036. showmap = tflags(12)
  2037. starstatus = tflags(13)
  2038. zoom = tflags(14)
  2039. skyoff = tflags(15)
  2040. gstyle = tflags(16)
  2041. mouseswap = tflags(17)
  2042. porb = tflags(18)
  2043. starfiles = tflags(19)
  2044. mdelay = tflags(20)
  2045. fsf = tflags(21)
  2046.  
  2047. IF fsf THEN
  2048.  
  2049. FOR i = 0 TO tsix '                                                    table faster
  2050.     s!(i) = SIN(_D2R(i))
  2051.     c!(i) = COS(_D2R(i))
  2052.  
  2053. clines = 0
  2054. OPEN f$(1) FOR INPUT AS #1 '                                          convo.dat, LM/CM chatter
  2055.     clines = clines + 1
  2056.     LINE INPUT #1, convo$(clines)
  2057.  
  2058. s& = VARSEG(cmp&(0)) '                                                Command Module
  2059. o& = VARPTR(cmp&(0))
  2060. DEF SEG = s& '                                                        cm.dat
  2061. BLOAD f$(18), o&
  2062.  
  2063. IF (RND > .95) AND (okrick = 0) AND (INSTR(COMMAND$, "NOS") = 0) THEN MakeSur
  2064.  
  2065. start1! = TIMER
  2066.  
  2067. init2: '                                                              each cycle
  2068. a = 0 '                                                               angle
  2069. a51i = 0
  2070. ASO = 0 '                                                             ascent stage only = false
  2071. boltc = 0 '                                                           lightning count
  2072. center = 362
  2073. contact = 0 '                                                         with ground
  2074. convo = 0 '                                                           with CM
  2075. crash = 0
  2076. cut = 0 '                                                             engine
  2077. dump = 0 '                                                            fuel
  2078. eou = 0 '                                                             end of universe
  2079. fb$ = "" '                                                            landing feedback
  2080. flx = 0 '                                                             where to plot flag
  2081. fuel! = h
  2082. hover = 1 '                                                           start safe
  2083. ideal! = 2.7 '                                                        autopilot speed
  2084. inpause = 0
  2085. jf = -1 '                                                             jump to feature
  2086. LGMc = 1 '                                                            little green man color
  2087. lmsl = blue '                                                         LM shield & laser
  2088. lob = 0 '                                                             landed on Borg
  2089. lock1 = 0 '                                                           radar tracking
  2090. lockfuel = 0
  2091. ma = 0 '                                                              malfunction angle
  2092. magic = 0 '                                                           landing
  2093. mes$(0) = "" '                                                        messages ^ landing eval
  2094. mes$(1) = "" '                                                        radiation, landing comments
  2095. ok = 0 '                                                              landing status
  2096. panelinit = 0 '                                                       instruments
  2097. paraf = 0 '                                                           parachute flag
  2098. pif = -1 '                                                            counter for instruments
  2099. platform = 0 '                                                        for detached DS
  2100. power = opower '                                                      thrust factor
  2101. powerloss = 0 '                                                       random malfunction
  2102. px! = 320 '                                                           vehicle x
  2103. py! = 70 '                                                            vehicle y
  2104. radiationdeath = 0 '                                                  rads > 1000
  2105. rads = 0 '                                                            radiation count
  2106. rlink = 0 '                                                           LM/CM radio link
  2107. rmin = RND * 23 '                                                     stars right ascension 0 - 23
  2108. dmin = (INT(RND * 18) - 9) * t '                                      stars declination -90 to 90
  2109. sia = 0 '                                                             shells in air
  2110. sspinit1 = 0
  2111. sspinit2 = 0
  2112. starinit = 0
  2113. tfollow = 0 '                                                         terrain following
  2114. tmt! = 0 '                                                            to move total
  2115. wa = 0 '                                                              wanted angle
  2116. vert = 1 '                                                            vertical autopilot on
  2117. vsd = 0 '                                                             vehicle severely damaged
  2118.  
  2119. Setcolor
  2120. GetSurface gh
  2121.  
  2122. IF demo THEN
  2123.     auto = 0
  2124.     px! = sf(6, 2) - 3130 '                                           TMA
  2125.     py! = 130
  2126.     sf = 6 '                                                          surface feature
  2127.     suri = 3130 '                                                     surface index
  2128.     vx! = 0 '                                                         not moving
  2129.     vy! = 0
  2130.     a = RND + t
  2131.     IF RND > pf! THEN a = -a
  2132.     sf = 4
  2133.     suri = RND * q1
  2134.     px! = 320
  2135.     thrust! = 95
  2136.     vx! = SGN(a) * 5
  2137.     vy! = RND + 1
  2138.  
  2139. ERASE exv, ei, ek, rtl!, rtlc, shx, shd
  2140.  
  2141. mes$(0) = "F1 FOR HELP AND INFORMATION"
  2142. IF ufof > 0 THEN mes$(1) = "Alien on the loose!" '                    10% active
  2143. IF LEDtri THEN LEDc = green
  2144. GOSUB ReadLM
  2145. start2! = TIMER '                                                     elapsed time clock
  2146. sec = 0
  2147. min = 0
  2148.  
  2149. PlotGround:
  2150. IF crash = 0 THEN
  2151.     surd = SGN(tmt!) '                                                direction
  2152.     tomo = INT(ABS(tmt!)) '                                           to move
  2153.     IF tomo > (q3 - gs) THEN tomo = q3 - gs
  2154.     tmt! = tmt! - tomo * surd '                                       to move total
  2155.     suri = suri + tomo * surd '                                       surface index
  2156.     GOSUB slimit '                                                    limit values to 0-6399
  2157.          
  2158. IF gh = -1 THEN '                                                     ground height = flat
  2159.     LINE (gs, q4)-(q3, q4), gray
  2160.     GOTO stuff
  2161.  
  2162. FOR x = gs TO q3 '                                                    graphics start to 639
  2163.     z = (suri + x) MOD q1
  2164.     tc = gray
  2165.     IF (z >= sf(5, 0)) AND (z <= sf(5, 1)) THEN
  2166.         PSET (x, glmax), tc '                                         optional McD fix
  2167.     ELSE
  2168.         IF (z >= sf(7, 0)) AND (z <= sf(7, 1)) THEN '                 Surveyor
  2169.             y = glmax
  2170.         ELSE
  2171.             y = gety(x)
  2172.         END IF
  2173.         SELECT CASE gstyle
  2174.             CASE IS = 0 '                                             solid
  2175.                 LINE (x, y)-(x, glmax), tc
  2176.             CASE IS = 5 '                                             solid
  2177.                 LINE (x, y)-(x, glmax), tc
  2178.             CASE IS = 1 '                                             fancy
  2179.                 LINE (x, glmax)-(x, y), black2
  2180.                 LINE -(x, glmax), tc, , z + y
  2181.                 PSET (x, y), tc
  2182.             CASE IS = 2
  2183.                 LINE (x, y)-(x, glmax), tc
  2184.                 ty = y + 5
  2185.                 IF ty < glmax THEN
  2186.                     LINE (x, ty)-(x, glmax - 1), black, , &HFEFE
  2187.                 END IF
  2188.             CASE ELSE '                                               minimal or tiling
  2189.                 LINE (x, glmax)-(x, y), black2
  2190.                 LINE -(x, y + 3), tc
  2191.         END SELECT
  2192.     END IF
  2193.  
  2194. IF gstyle > 3 THEN Tile
  2195.  
  2196. stuff:
  2197. FOR i = 1 TO t
  2198.     ' Surv before IBM+TMA, IBM before TMA, LGM last
  2199.     '              1 2 3 4 5 6 7 8 9 0
  2200.     j = VAL(MID$("01070802040506091003", (i - 1) * 2 + 1, 2))
  2201.     z = VAL(MID$("80000080000080000000", (j - 1) * 2 + 1, 2))
  2202.     fb = sf(j, 0) - z
  2203.     fe = sf(j, 1) + z
  2204.     c1 = (fe >= (suri + gs)) AND (fb <= (suri + q3))
  2205.     c2 = ((fe + q1) >= (suri + gs)) AND ((fb + q1) <= (suri + q3))
  2206.     IF c1 OR c2 THEN
  2207.         sf = 0
  2208.         IF sf(j, 2) = -1 THEN GOTO nf
  2209.         sf = j
  2210.         x = sf(sf, 0) - suri
  2211.         z = sf(sf, 1) - suri
  2212.  
  2213.         IF (j = 1) AND (x < 0) AND (suri > 3000) THEN x = x + q1: z = z + q1
  2214.         bolthitf = (skyoff = 0) AND (boltx >= x) AND (boltx <= z) AND (exl(1) <> 9999)
  2215.         IF j = 1 THEN
  2216.             Area51 f$(40)
  2217.             IF (cut = 0) AND (LEFT$(mes$(1), 7) = "AREA 51") THEN
  2218.                 GOSUB CutOrOutOfFuel
  2219.             END IF
  2220.         END IF
  2221.         IF j = 2 THEN CarWash
  2222.         IF j = 3 THEN LGM fc
  2223.         IF j = 4 THEN Volcano
  2224.         IF j = 5 THEN McD
  2225.         IF j = 6 THEN TMA
  2226.         IF j = 7 THEN Surveyor
  2227.         IF j = 8 THEN IBM
  2228.         IF j = 9 THEN Hollywood
  2229.         IF j = t THEN Grave x, fb$
  2230.     END IF
  2231.     nf:
  2232.  
  2233. CommandModule: '                                                      27 * 9
  2234. IF ek(0) = -1 THEN RETURN
  2235. cminview = 1
  2236. tx = localize(ex(0), 14, 14)
  2237. IF tx = 999 THEN cminview = 0: GOTO nocm
  2238. x1 = tx - 14
  2239. x2 = tx + 14
  2240.  
  2241. VIEW SCREEN(gs + 1, 0)-(q3, q4) '                                     protect panel
  2242. LINE (x1 + 0, 18)-(x1 + 26, 26), black2, BF
  2243. FOR z = 1 TO 27
  2244.     LINE (x1 + z, 17)-(x1 + z, 26), white, , cmp&(z)
  2245.  
  2246. CMshadow tx, x1, x2 '                                                 optional
  2247.  
  2248. sd! = ABS(exv(0)) - ABS(vx!) '                                        speed diff
  2249. dbc = ABS(px! - tx)
  2250.  
  2251. IF (py! < h) AND (dbc < 50) AND (ABS(sd!) < .06) THEN
  2252.     rlink = t
  2253.     LINE (LMrx(1), LMry(1))-(tx + 8, 27), green, , RND * &H7FFF
  2254.     IF (cmleaving + convo) = 0 THEN
  2255.         mes$(0) = "Establishing link with Campbell soup cans and string"
  2256.         sct! = 2
  2257.         convo = 1
  2258.     END IF
  2259.     IF sc! = 0 THEN sc! = TIMER + sct! '                              start conversation in xs
  2260.     IF TIMER > sc! THEN
  2261.         convo = convo + 1
  2262.         IF convo > (clines + 1) THEN
  2263.             sc! = 0
  2264.             convo = 0
  2265.             cmleaving = 1
  2266.         ELSE
  2267.             mes$(0) = convo$(convo)
  2268.             sc! = TIMER + sct!
  2269.         END IF
  2270.     END IF
  2271.      
  2272. nocm:
  2273. rlink = rlink - 1 - (rlink = 0) '                                     allows brief radio interruption
  2274. IF rlink = 0 THEN '                                                   lost awhile ago
  2275.     IF convo THEN mes$(0) = " " '                                     clear current dialogue
  2276.     convo = 0 '                                                       stop conversation
  2277.     sc! = 0 '                                                         talk timer
  2278.  
  2279. IF cmleaving AND cminview THEN '                                      CM exhaust
  2280.     ty = 22
  2281.     LINE (x1, ty - 2)-(x1, ty + 2), yellow
  2282.     LINE -(x1 - 15, ty), yellow
  2283.     LINE -(x1, ty - 2), yellow
  2284.  
  2285. liftoff: '                                                            forced seperation or surface launch
  2286. IF (contact OR liftoff) AND (cwd < 69) AND (py! > 322) THEN
  2287.     dead$ = "HIT CAR WASH"
  2288.     RETURN
  2289.  
  2290. IF contact THEN vx! = 0
  2291. IF lob THEN vx! = exv(2): a = 0 '                                     landed on Borg
  2292.  
  2293. goy = -h '                                                            AS go y
  2294. IF ASO THEN '                                                         ascent stage only
  2295.     IF fuel! = 0 THEN RETURN
  2296.     thrust! = h
  2297.     falling = 0
  2298.     platform = 0
  2299.     IF lob THEN pminy = borgt
  2300.     power = opower
  2301.     thrust! = th '                                                    simulate explosive seperation
  2302.     platform = 22 '                                                   deflect flame from DS
  2303.     IF contact THEN
  2304.         falling = 0 '                                                 DS already on surface
  2305.     ELSE
  2306.         falling = 1 '                                                 DS in air
  2307.         goy = py! - 20 '                                              go y - not to screen top
  2308.     END IF
  2309.     LINE (gs, 30)-(q3, q4), 0, BF '                                   erase "space" area
  2310.     pminx = q1: pmaxx = -pminx
  2311.     pminy = q1: pmaxy = -pmaxy
  2312.     FOR i = 279 TO rp '                                               draw descent stage
  2313.         c = LMc(i)
  2314.         IF c < 0 THEN c = fuel
  2315.         PSET (LMrx(i), LMry(i)), c
  2316.         IF LMrx(i) < pminx THEN pminx = LMrx(i)
  2317.         IF LMrx(i) > pmaxx THEN pmaxx = LMrx(i)
  2318.         IF LMry(i) < pminy THEN pminy = LMry(i)
  2319.         IF LMry(i) > pmaxy THEN pmaxy = LMry(i)
  2320.     NEXT i
  2321.     GOSUB flevel
  2322.     IF platform > 0 THEN deflectat = pminy
  2323.     zz = pmaxy - pminy
  2324.     GET (pminx, pminy)-(pmaxx, pmaxy), gbuff() '                      save descent stage
  2325.     LINE (gs, 30)-(q3, q4), 0, BF '                                   erase "space" area
  2326.  
  2327.     ta = (a + tsix) MOD tsix
  2328.     px! = px! - t * s!(ta)
  2329.     py! = py! - 15 * c!(ta) '                                         explosive seperation
  2330.  
  2331. wASO = ASO
  2332. ASO = 1
  2333. GOSUB ReadLM
  2334. IF wASO = 0 THEN fuel! = h
  2335. IF vsd THEN LMdistort
  2336.  
  2337. IF contact THEN
  2338.     dropvx! = 0
  2339.     IF lob AND (ABS(px! - center) > 2) THEN dropvx! = exv(1)
  2340.     dropvy! = 0
  2341.     dropvx! = vx!
  2342.     dropvy! = vy!
  2343.  
  2344. IF lob OR (contact = 0) THEN
  2345.     wa = 0
  2346.     wa = SGN(-exv(0)) * 20 '                                          want angle
  2347.     IF wa = 0 THEN wa = -20
  2348.  
  2349. sauto = auto: auto = 1
  2350. contact = 0
  2351. cut = 0
  2352. dump = 0
  2353. hover = 0
  2354. liftoff = 1
  2355. lminx = pminx
  2356. lock1 = 0
  2357. lockfuel = 0
  2358. lpass = 0
  2359. IF wASO = 0 THEN ma = 0
  2360. mes$(0) = ""
  2361. mes$(1) = ""
  2362. np = 0
  2363. paraf = 0
  2364. pcontact = 0
  2365. powerloss = 0
  2366. psuri = suri
  2367. py! = py! - 2 '                                                       fool CheckHit
  2368. svert = vert
  2369. vert = 0
  2370.  
  2371. DO: _LIMIT mdelay * 1.5
  2372.     IF py! < 280 THEN GOSUB angle '                                   make a=wa (angle=wanted)
  2373.     GOSUB Plotscreen
  2374.     np = np + 1
  2375.     IF np >= t THEN GOSUB CheckHit
  2376.     z = (sy1 + sy2) / 2 - 2
  2377.     IF (deflectat > 0) AND (z > deflectat) AND (z > deflectat) THEN contact = 1
  2378.     IF contact THEN dead$ = "NOT YOUR DAY": EXIT DO
  2379.     lpass = lpass + 1
  2380.     IF thrust! = th THEN thrust! = h
  2381.     IF vsd THEN '                                                     very severe damage
  2382.         thrust! = h - (lpass + RND) '                                 slowly drop power
  2383.         IF thrust! < 50 THEN thrust! = 50 + RND
  2384.         IF RND > .95 THEN
  2385.             dead$ = "STRUCTURAL FAILURE"
  2386.             EXIT DO
  2387.         END IF
  2388.     END IF
  2389.     GOSUB KeyAndMouse
  2390.     IF LEN(dead$) THEN GOTO endl
  2391.     IF lob OR ((platform > 0) AND (falling = 1)) THEN
  2392.         pminx = pminx + dropvx!
  2393.         pmaxx = pmaxx + dropvx!
  2394.         pminy = pminy + dropvy!
  2395.         pmaxy = pmaxy + dropvy!
  2396.         IF lob = 0 THEN
  2397.             dropvy! = dropvy! + .6
  2398.             dropy! = gety(-(pminx + nx))
  2399.             IF pmaxy < dropy! THEN
  2400.                 lminx = pminx
  2401.                 lminy = dropy! - zz
  2402.                 deflectat = pminy
  2403.             ELSE
  2404.                 pminx = lminx
  2405.                 pminy = lminy
  2406.                 psuri = suri
  2407.                 pcontact = 1
  2408.                 falling = 0
  2409.             END IF
  2410.         END IF
  2411.     ELSE
  2412.         pminx = lminx + (psuri - suri)
  2413.     END IF
  2414.     IF cut THEN lpass = 0
  2415.     IF wASO THEN
  2416.         IF (py! <= goy) AND (cut = 0) THEN EXIT DO
  2417.     ELSE
  2418.         IF pcontact OR (pminx < gs) OR (pminx > 580) THEN EXIT DO
  2419.         IF (cut = 0) AND (py! <= goy) THEN
  2420.             hover = 1
  2421.             GOSUB Autopilot
  2422.             IF falling = 0 THEN EXIT DO
  2423.         END IF
  2424.     END IF
  2425. LOOP UNTIL (alt! > h) OR LEN(dead$)
  2426.  
  2427. endl:
  2428. auto = sauto
  2429. crash = 0
  2430. deflectat = 0
  2431. liftoff = 0
  2432. lock1 = 0
  2433. platform = 0
  2434. vert = svert
  2435.  
  2436. ReadLM:
  2437. LMbloads
  2438. IF ASO THEN '                                                         ascent stage only
  2439.     lp = 294
  2440.     nx = 16
  2441.     ny = 9
  2442.     rp = 302
  2443.     th1 = 170
  2444.     th2 = 198
  2445.     vmass = 60
  2446. ELSE '                                                                AS&DS 34*36
  2447.     lp = 696 '                                                        left pad
  2448.     nx = 17 '                                                         center x (for rotating)
  2449.     ny = 18 '                                                         center y
  2450.     rp = 705 '                                                        right pad
  2451.     th1 = 449 '                                                       left thruster
  2452.     th2 = 483 '                                                       right thruster
  2453.     vmass = h '                                                       full mass
  2454.  
  2455. nred = 0 '                                                            number red (volcanic heating)
  2456. temp = 0 '                                                            temperature
  2457. IF bw = 0 THEN PALETTE gasoline, 24
  2458. xp = 97 ' radar
  2459. wi = LMx(rp) - LMx(lp) + 1 '                                          width
  2460. wi2 = wi \ 2
  2461.  
  2462. IF invincible THEN c = gold ELSE c = gray '                           thruster color
  2463. FOR i = 1 TO rp
  2464.     LMx(i) = LMx(i) - nx
  2465.     LMy(i) = LMy(i) - ny
  2466.     IF (LMc(i) = gray) OR (LMc(i) = gold) THEN LMc(i) = c '           thrusters
  2467.     IF LMc(i) < 0 THEN LMc(i) = fuel '                                fuel
  2468.     LMoc(i) = LMc(i)
  2469. GOSUB LMcolors
  2470. ' --------------------------------------------------------------------------
  2471. d1:
  2472. DATA 27,"Elapsed time"
  2473. DATA 36,"Distance to McD"
  2474. DATA 45,"CPU"
  2475. DATA 54,"Rads/temperature"
  2476. DATA 86,"Fuel"
  2477. DATA 126,"Altitude"
  2478. DATA 166,"Horizontal velocity"
  2479. DATA 206,"Vertical velocity"
  2480. DATA 244,"Main thrust"
  2481. DATA 277,"Sideways thrust"
  2482. DATA 307,"Autopilot (full)"
  2483. DATA 322,"Hover control"
  2484. DATA 337,"Vertical automatic"
  2485.  
  2486. DATA "Scored on vertical & horizontal speed:"
  2487. DATA "0.00 - 0.50 Excellent"
  2488. DATA "0.51 - 1.00 Good"
  2489. DATA "1.01 - 2.00 Fair"
  2490. DATA "2.01 - 3.00 Poor"
  2491. DATA ""
  2492. DATA "Landing surface should be near flat,"
  2493. DATA with required ending angle under 5ø.
  2494. DATA ""
  2495. DATA Based on a 1974 program running on a
  2496. DATA DEC PDP/11 with GT40 vector display
  2497. DATA terminal at the University of Alberta.
  2498. DATA The graphic at top left is usually a Henon
  2499. DATA "plot, dealing with the stability of orbits."
  2500. DATA The face appearing in TMA-1 when it shoots
  2501. DATA "is Cybill Shepherd. If you land on TMA-1,"
  2502. DATA it displays a Mandelbrot. The semaphores
  2503. DATA "use proper flag positions, and the Morse"
  2504. DATA code in the McDonalds sign is real too.
  2505. DATA "Little Green Man can be turned into a pile"
  2506. DATA of ashes.  Beware the beach balls of IBM!
  2507. DATA ""
  2508. DATA F2 for a demo mode showing most features.
  2509. DATA ""
  2510. DATA "Esc or <: Back to Lander   > Next page"
  2511.  
  2512. d2:
  2513. DATA "ud        main thrust"
  2514. DATA "<>        side thrust/angle"
  2515. DATA "Shift ud  move up"
  2516. DATA "Shift <>  move left/right"
  2517. DATA "<>        ground back/forward"
  2518. DATA "space     abort/feature cycle"
  2519. DATA "Bkspace   random star position"
  2520. DATA "Esc       quit"
  2521. DATA "01234     stars off/on/info"
  2522. DATA "aA        autopilot on/off/McD"
  2523. DATA "b         goto Borg"
  2524. DATA "B         goto black hole"
  2525. DATA "c         cut engine"
  2526. DATA "C         clock(s) on/off"
  2527. DATA "d         dump fuel"
  2528. DATA "D         restart with defaults"
  2529. DATA "fF        fuel lock/unlimited"
  2530. DATA "G         new ground"
  2531. DATA "h         hover"
  2532. DATA "I         invincible mode"
  2533. DATA "k         kill (fire laser)"
  2534. DATA "wlemtsiHg goto surface feature"
  2535. DATA "L         level ground"
  2536. DATA "M         Magic landing!"
  2537. DATA "n         nation (flag)"
  2538. DATA "o         goto comet"
  2539. DATA "O         goto EPCOR"
  2540. DATA "p         pause"
  2541. DATA "P         parachute"
  2542. DATA "r         radar"
  2543. DATA "R         rendesvous with CM"
  2544. DATA "T         thrust accuracy"
  2545. DATA "u         instruments"
  2546. DATA "v         vertical automatic"
  2547. DATA "y         swap mouse buttons"
  2548. DATA "z         self-destruct"
  2549. DATA ".         terrain following"
  2550. DATA "F2        demo mode (compressed)"
  2551. DATA "F3        sky features"
  2552. DATA "F4        constant black holes"
  2553. DATA "F5        panel/instruments"
  2554. DATA "F6        drop descent stage"
  2555. DATA "F7        map at top"
  2556. DATA "F8        shields (uses fuel)"
  2557. DATA "F9/F10    LED color/tri-color"
  2558. DATA "PgDn/Up   slower/faster"
  2559. DATA "< Previous page   > Next page"
  2560.  
  2561. d3:
  2562. DATA "/  green/amber/b&w/regular screen"
  2563. DATA "+  zoom in starfield"
  2564. DATA "-  zoom out starfield"
  2565. DATA "\  drop bomb"
  2566. DATA ".  terrain following"
  2567. DATA "_  star twinkle"
  2568. DATA "j  DeathStar rotation"
  2569. DATA "|  generate all star files (hours!)"
  2570. DATA "x  more/less stars"
  2571. DATA "X  regenerate current star file"
  2572. DATA "Q  oscar (LGM flag colors)"
  2573. DATA "=  show LM data"
  2574. DATA "[  crude black & white"
  2575. DATA "]  UFO toggle"
  2576. DATA "U  ground tiling style"
  2577. DATA "ctrl-c or -s: SCREEN capture"
  2578. DATA "alt-Enter: fullscreen toggle"
  2579. DATA ""
  2580. DATA "< Previous page   > Next page"
  2581.  
  2582. d4:
  2583. DATA "      Programmed by:   R. Frost"
  2584. DATA "                       Edmonton, Alberta, Canada"
  2585. DATA ""
  2586. DATA "                       rfrost@mail.com "
  2587. DATA ""
  2588. DATA ""
  2589. DATA " 1) 2001 A Space Odyssey: TMA-1, HAL, CM/LM chatter"
  2590. DATA " 2) Star Trek: warp messages, phasers, shield, Borg"
  2591. DATA " 3) Lost in Space: black hole warning"
  2592. DATA " 4) Southpark: black hole at 3:50 (Tree-fiddy! - Chef)"
  2593. DATA " 5) Simpsons: LGM saying he has semaphore flags"
  2594. DATA " 6) Rocky & Bullwinkle: a hall of Montezuma (car wash)"
  2595. DATA " 7) Bonanza: car wash traverse generates a Hop Sing quote"
  2596. DATA " 8) SCTV: CM/LM chatter"
  2597. DATA " 9) a McDonalds on the Moon, and an instrument for it"
  2598. DATA "10) Little Green Man wiggles ears & reacts to LM exhaust"
  2599. DATA "11) pirate books & movies: CM/LM chatter"
  2600. DATA "12) Command Module leaves you stranded"
  2601. DATA "13) a Steve Martin quote precedes black hole death"
  2602. DATA "14) half the time the USSR flag is planted"
  2603. DATA "15) Cybil Shepherd's face appears in TMA-1 when it fires"
  2604. DATA "16) Halley's Comet is renamed Halle Berry"
  2605. DATA "17) digital, analog, and binary clocks!"
  2606. DATA "18) End Of The Universe is signaled by Chicken Little"
  2607. DATA "19) Mt. Etna spews volcanic cheese"
  2608. DATA "20) a parachute that doesn't work in a vacuum"
  2609. DATA "21) Area 51 is the first level landing zone"
  2610. DATA "22) IBM weapon is a fishing float or beach ball"
  2611. DATA ""
  2612. DATA "< Previous page   Esc or >: Back to Lander"
  2613.  
  2614. leds:
  2615. DATA a,0,-2,1,-2
  2616. DATA b,1,-2,1,-1
  2617. DATA c,1,-1,1,0
  2618. DATA d,0,0,1,0
  2619. DATA e,0,-1,0,0
  2620. DATA f,0,-2,0,-1
  2621. DATA g,0,-1,1,-1
  2622.        
  2623. DATA 0,abcdef,1,bc,2,abged,3,abgcd,4,fgbc,5,acdfg,6,acdefg,7,abc,8,abcdefg,9,abcdfg,10,g,11,def
  2624.  
  2625. features:
  2626. '               x   y  lz
  2627. DATA "Area 51",65,40,45
  2628. DATA "Car Wash",100,44,130
  2629. DATA "Little Green Man",12,0,70
  2630. DATA "Etna",10,49,20
  2631. DATA "McDonalds",38,0,80
  2632. DATA "TMA-1",45,71,80
  2633. DATA "Surveyor",28,0,80
  2634. DATA "IBM",50,45,90
  2635. DATA "Hollywood",170,0,0
  2636. DATA "a grave",68,49,98
  2637.  
  2638. MorseData:
  2639. DATA a,.-,b,-...,c,-.-.,d,-..,e,.,f,..-.,g,--.
  2640. DATA h,....,i,..,j,.---,k,-.-,l,.-..,m,--,n,-.
  2641. DATA o,---,p,.--.,q,--.-,r,-.-,s,...,t,-,u,..-
  2642. DATA v,...-,w,.--,x,-..-,y,-.--,z,--..,1,.----,2,..---
  2643. DATA 3,...--,4,....-,5,.....,6,-...,7,--..,8,---..,9,----.
  2644. DATA 0,-----,!,..--.,$,...-..-,&,.-...
  2645.  
  2646. warp:
  2647. DATA "The Rockwell warranty is now void"
  2648. DATA "Hope we don't collide with Klingons!"
  2649. DATA "You need a vacation, Jim!  - Bones!"
  2650. DATA "It's a long way to Tipperary!"
  2651. DATA "Do we know this universe?  - Spock"
  2652. DATA "My miniskirt is getting shorter! - Uhuru"
  2653. DATA "Da engines kanna tayke much more! - Scotty"
  2654. DATA "Keptin, are you insane? - Chekhov"
  2655. DATA "Hit 10 and we die!"
  2656.  
  2657. radcomments:
  2658. DATA "has caused genetic damage"
  2659. DATA "causes glowing in the dark"
  2660. DATA "5 years"
  2661. DATA "1 year"
  2662. DATA "6 months"
  2663. DATA "1 month"
  2664. DATA "1 week"
  2665. DATA "8 hours"
  2666. DATA "5 minutes"
  2667. DATA "has killed you - press Esc"
  2668.  
  2669. skycrud:
  2670. DATA CM,14,14
  2671. DATA DS,150,150
  2672. DATA BO,58,46
  2673. DATA BH,200,200
  2674. DATA Wo,90,90
  2675. DATA Co,20,100
  2676. DATA AL,40,40
  2677. DATA ZZ,1,1
  2678.  
  2679. semadata:
  2680. DATA a 1,225,180
  2681. DATA b 2,270,180
  2682. DATA c 3,315,180
  2683. DATA d 4,0,180
  2684. DATA e 5,180,45
  2685. DATA f 6,180,90
  2686. DATA g 7,180,135
  2687. DATA h 8,270,225
  2688. DATA i 9,225,315
  2689. DATA j,0,90
  2690. DATA k 0,225,0
  2691. DATA l,225,45
  2692. DATA m,225,90
  2693. DATA n,225,135
  2694. DATA o,270,315
  2695. DATA p,270,0
  2696. DATA q,270,45
  2697. DATA r,270,90
  2698. DATA s,270,135
  2699. DATA t,315,0
  2700. DATA u,315,45
  2701. DATA v,0,135
  2702. DATA w,45,90
  2703. DATA x,45,135
  2704. DATA y,315,90
  2705. DATA z,135,90
  2706. DATA " ",180,180
  2707. DATA !,0,0
  2708.  
  2709. say:
  2710. DATA "The time is 1234"
  2711. DATA "Welcome to the Moon"
  2712. DATA "I am a little green man"
  2713. DATA "I have semaphore flags"
  2714. DATA "R Frost is a nerd!"
  2715. DATA "abcdefghijklmnopqrstuvwxyz"
  2716.  
  2717. BigM: '                                                               37 * 16
  2718. DATA "          X               X          "
  2719. DATA "         X X             X X         "
  2720. DATA "        X   X           X   X        "
  2721. DATA "       X     X         X     X       "
  2722. DATA "      X       X       X       X      "
  2723. DATA "     X         X     X         X     "
  2724. DATA "     X         X     X         X     "
  2725. DATA "    X           X   X           X    "
  2726. DATA "    X           X   X           X    "
  2727. DATA "   X             X X             X   "
  2728. DATA "   X             X X             X   "
  2729. DATA "  X              XXX              X  "
  2730. DATA " X                                 X "
  2731. DATA " X                                 X "
  2732. DATA "X                                   X"
  2733. DATA "X                                   X"
  2734. '     1234567890123456789012345678901234567
  2735. '              1         2         3
  2736. tinyfontd:
  2737. DATA 0,7,5,5,5,7
  2738. DATA 1,2,6,2,2,7
  2739. DATA 2,7,1,7,4,7
  2740. DATA 3,7,1,7,1,7
  2741. DATA 4,5,5,7,1,1
  2742. DATA 5,7,4,7,1,7
  2743. DATA 6,7,4,7,5,7
  2744. DATA 7,7,1,1,1,1
  2745. DATA 8,7,5,7,5,7
  2746. DATA 9,7,5,7,1,7
  2747. DATA .,0,0,0,0,2
  2748. DATA -,0,0,1,0,0
  2749. DATA ":",0,2,0,2,0
  2750. DATA " ",0,0,0,0,0
  2751.  
  2752. lmshow:
  2753. FOR pass = 1 TO 2
  2754.     CLS
  2755.     FOR i = 1 TO rp
  2756.         x = (LMx(i) + 17 - ASO) * 16 + 30 + (pass = 2)
  2757.         y = (LMy(i) + 18 - ASO * 9) * 8 + t
  2758.         IF pass = 1 THEN z$ = LTRIM$(STR$(LMc(i))) ELSE z$ = RIGHT$("  " + STR$(i), 3)
  2759.         IF LEN(z$) = 1 THEN z$ = "0" + z$
  2760.         c = LMc(i)
  2761.         TinyFont z$, x + 3, y + 3, c
  2762.     NEXT i
  2763.     FOR i = 1 TO 35 '                                                 line of numbers at top
  2764.         z$ = RIGHT$(" " + LTRIM$(STR$(i)), 2)
  2765.         TinyFont z$, (i - 1) * 16 + 33, 4, gray
  2766.         x = (i - 1) * 16 + 30 + 16
  2767.         LINE (x, 0)-(x, 320), red
  2768.     NEXT i
  2769.     FOR i = 1 TO 36 '                                                 columb of numbers at left
  2770.         z$ = RIGHT$(" " + LTRIM$(STR$(i)), 2)
  2771.         TinyFont z$, 8, i * 8 + 13, gray
  2772.         y = i * 8 + t + 8 + 1
  2773.         LINE (0, y)-(q3, y), red
  2774.     NEXT i
  2775.     LINE (0, 0)-(q3, 320), red, B
  2776.     _DISPLAY
  2777.     SLEEP
  2778. NEXT pass
  2779. ' -------------------------------------------------------------------------------------------------------x
  2780. SUB mHelp
  2781.     VIEW: CLS
  2782.     hp = 1
  2783.     DO
  2784.         CLS
  2785.         IF hp = 1 THEN GOSUB Help1
  2786.         IF hp = 2 THEN GOSUB Help2
  2787.         IF hp = 3 THEN GOSUB Help3
  2788.         IF hp = 4 THEN GOSUB credits
  2789.         timemachine
  2790.         DO: _LIMIT 30
  2791.             i$ = INKEY$
  2792.         LOOP UNTIL LEN(i$)
  2793.         IF LEN(i$) = 1 THEN k = ASC(i$) ELSE k = ASC(RIGHT$(i$, 1))
  2794.         hp = hp + (k = 75) - (k = 77)
  2795.         IF (k = 27) OR (hp < 1) OR (hp > 4) THEN EXIT DO
  2796.     LOOP
  2797.     CLS
  2798.     EXIT SUB
  2799.     ' --------------------------------------------------------------------------
  2800.     ReadAndReplace:
  2801.     READ z$
  2802.     z = INSTR(z$, "ground")
  2803.     p = INSTR(z$, "<"): IF (p > 0) AND (z = 0) THEN MID$(z$, p, 1) = CHR$(27)
  2804.     p = INSTR(z$, ">"): IF (p > 0) AND (z = 0) THEN MID$(z$, p, 1) = CHR$(26)
  2805.     RETURN
  2806.     ' --------------------------------------------------------------------------
  2807.     Help1:
  2808.     RESTORE d1
  2809.     REDIM gbuff2(8000)
  2810.     s& = VARSEG(gbuff2(0))
  2811.     o& = VARPTR(gbuff2(0))
  2812.     DEF SEG = s&
  2813.     BLOAD "PANEL.DAT", o&
  2814.     PUT (0, 0), gbuff2(0)
  2815.     REDIM gbuff2(0)
  2816.     LINE (85, 0)-(260, q4), gray, BF
  2817.     FOR i = 1 TO 13 '                                                 define the panel first
  2818.         READ ty, z$
  2819.         IF i < 5 THEN
  2820.             sprint2 z$, 90, ty, white, 0
  2821.         ELSE
  2822.             IF i = 9 THEN z$ = CHR$(24) + CHR$(25) + z$ '             up & down arrow keys
  2823.             IF i = 10 THEN z$ = CHR$(27) + CHR$(26) + z$ '            left & right arrow keys
  2824.             sprint z$, 90, ty, white, 0
  2825.             IF (i = 9) OR (i = 10) THEN sprint LEFT$(z$, 2), 90, ty, red, 0
  2826.             IF i > 10 THEN sprint LEFT$(z$, 1), 90, ty, red, 0
  2827.         END IF
  2828.     NEXT i
  2829.     LINE (261, 0)-(639, q4), blue2, BF '                              summary of program
  2830.     ty = 11: c = white
  2831.     FOR i = 1 TO 25
  2832.         GOSUB ReadAndReplace
  2833.         p = INSTR(z$, "*auto")
  2834.         IF p THEN qm$ = CHR$(34): MID$(z$, p, 6) = qm$ + "auto" + qm$
  2835.         sprint z$, 275, ty, c, 0
  2836.         ty = ty + 9 - (z$ <> "") * 5
  2837.     NEXT i
  2838.     RETURN
  2839.     ' --------------------------------------------------------------------------
  2840.     Help2:
  2841.     RESTORE d2
  2842.     c1 = gray
  2843.     c2 = black
  2844.     z$ = "KEYBOARD COMMANDS"
  2845.     GOSUB pageprep
  2846.     tx = 40: ty = 26
  2847.     FOR i = 1 TO 46
  2848.         GOSUB ReadAndReplace
  2849.         p = INSTR(z$, "ud")
  2850.         IF p THEN MID$(z$, p, 2) = CHR$(24) + CHR$(25)
  2851.         IF i = 3 THEN MID$(z$, 8, 1) = " "
  2852.         e = INSTR(z$, "main t") + INSTR(z$, "side t")
  2853.         IF e THEN c = green ELSE c = white
  2854.         IF INSTR("ahv", LEFT$(z$, 1)) THEN c = gasoline
  2855.         sprint2 z$, tx, ty, c, 0
  2856.         ty = ty + 11: IF ty > 276 THEN tx = 340: ty = 26
  2857.     NEXT i
  2858.     LINE (50, 300)-(585, 300), 0
  2859.     LINE (55, 302)-(590, 302), 0
  2860.     GOSUB ReadAndReplace
  2861.     sprint2 "When landed or paused, arrow keys move stars", 135, 282, white, 0
  2862.     ty = 310
  2863.     sprint z$, 350, ty, white, 0
  2864.     sprint "essential", 50, ty, green, 0
  2865.     sprint "other flight", 150, ty, gasoline, 0
  2866.     RETURN
  2867.  
  2868.     Help3:
  2869.     RESTORE d3
  2870.     c1 = gray
  2871.     c2 = black
  2872.     z$ = "MORE KEYBOARD COMMANDS"
  2873.     GOSUB pageprep
  2874.     tx = 200: ty = 36: c2 = blue
  2875.     FOR i = 1 TO 19
  2876.         GOSUB ReadAndReplace
  2877.         IF i = 19 THEN ty = 310: c2 = black
  2878.         sprint z$, tx, ty, white, c2
  2879.         ty = ty + 15
  2880.     NEXT i
  2881.  
  2882.     LINE (50, 300)-(585, 300), 0
  2883.     LINE (55, 302)-(590, 302), 0
  2884.     RETURN
  2885.     ' --------------------------------------------------------------------------
  2886.     credits:
  2887.     RESTORE d4
  2888.     c1 = dred
  2889.     c2 = white
  2890.     z$ = "AUTHOR & HUMOUR SUMMARY"
  2891.     GOSUB pageprep: x1 = 86: ty = 40
  2892.     FOR i = 1 TO 30
  2893.         GOSUB ReadAndReplace
  2894.         IF i = 30 THEN
  2895.             x1 = 320 - LEN(z$) * 4 - 8
  2896.             x2 = 320 + LEN(z$) * 4 + 8
  2897.             ty = 330
  2898.             LINE (x1, ty)-(x2, ty + 11), dred, BF
  2899.         END IF
  2900.         sprint2 z$, x1 + 8, ty, c2, 0
  2901.         ty = ty + t
  2902.     NEXT i
  2903.     RETURN
  2904.     ' --------------------------------------------------------------------------
  2905.     pageprep:
  2906.     CLS: PAINT (1, 1), c1
  2907.     x1 = 30: y1 = 5: x2 = 610: y2 = 345
  2908.     FOR q = 2 TO 20 STEP 4
  2909.         LINE (x1 - q, y1 + q)-(x2 + q, y2 - q), c1, B
  2910.         LINE (x1 - q + 1, y1 + q + 1)-(x2 + q + 1, y2 - q + 1), c2, B
  2911.     NEXT q
  2912.     z = LEN(z$) + 2: x1 = 320 - z * 4: x2 = 320 + z * 4
  2913.     LINE (x1, 9)-(x2, 22), c1, BF
  2914.     sprint z$, x1 + 8, t, white, -c2
  2915.     RETURN
  2916. ' -------------------------------------------------------------------------------------------------------x
  2917. SUB sprint (z$, tx, ty, c1, c2) '                                     VGA font
  2918.     FOR i = 1 TO LEN(z$)
  2919.         d = ASC(MID$(z$, i, 1))
  2920.         IF d = 248 THEN d = 0 '                                       degree symbol
  2921.         x = tx + (i - 1) * 8
  2922.         FOR byte = 0 TO 13
  2923.             y = ty + byte
  2924.             p& = (p(d, byte) AND 255) * 128
  2925.             IF c2 >= 0 THEN LINE (x + 1, y)-(x + 8, y), c2, , p&
  2926.             LINE (x, y)-(x + 7, y), c1, , p&
  2927.         NEXT byte
  2928.     NEXT i
  2929. ' -------------------------------------------------------------------------------------------------------x
  2930. SUB sprint2 (c$, tx, ty, c1, c2) '                                    CGA font
  2931.     FOR i = 1 TO LEN(c$)
  2932.         d = ASC(MID$(c$, i, 1))
  2933.         IF d = 248 THEN d = 0 '                                       degree symbol
  2934.         FOR k = 0 TO 7
  2935.             tx2 = tx + (i - 1) * 8 + k
  2936.             ty2 = ty + 2
  2937.             p& = p2(d, k)
  2938.             IF c2 >= 0 THEN
  2939.                 LINE (tx2 + 1, ty2 + 1)-(tx2 + 1, ty2 + 9), c2, , p&
  2940.             END IF
  2941.             LINE (tx2, ty2)-(tx2, ty2 + 8), c1, , p&
  2942.         NEXT k
  2943.     NEXT i
  2944. ' -------------------------------------------------------------------------------------------------------x
  2945. SUB AuHoVe (auto, hover, vert, lam)
  2946.     FOR i = 0 TO 2
  2947.         z$ = MID$(" AUTOHOVER VERT", i * 5 + 1, 5)
  2948.         IF i = 0 THEN k = auto
  2949.         IF i = 1 THEN k = hover
  2950.         IF i = 2 THEN k = vert
  2951.  
  2952.         ty = 307 + i * 15
  2953.         PrintCGA z$, 4, ty, gunmetal, black2, 0
  2954.  
  2955.         IF k THEN
  2956.             c1 = green
  2957.             c2 = black2
  2958.         ELSE
  2959.             c1 = black2
  2960.             c2 = red
  2961.         END IF
  2962.  
  2963.         IF crash THEN c1 = black2: c2 = black2
  2964.  
  2965.         IF lam AND k AND (i = 0) THEN c1 = gold '                     land at McD
  2966.  
  2967.         PrintCGA "ON ", 57, ty - 4, c1, -1, 0
  2968.  
  2969.         '                                                             blink OFF to indicate a keyboard command turned it off
  2970.         IF (i = 0) AND (APdisengage > 0) AND (c2 = red) THEN
  2971.             c2 = (APdisengage MOD 2) * red
  2972.             APdisengage = APdisengage - 1
  2973.         END IF
  2974.         PrintCGA "OFF", 57, ty + 3, c2, -1, 0
  2975.  
  2976.         tx1 = 48: ty1 = ty + 5 '                                      switches
  2977.         IF i = 1 THEN c = blue2 ELSE c = blue '                       background
  2978.         IF k THEN ta = 285 ELSE ta = 75 '                             up & down angles
  2979.         tx2 = tx1 + 5 * c!(ta)
  2980.         ty2 = ty1 + 5 * s!(ta)
  2981.         FOR k = 0 TO 1
  2982.             LINE (tx1 + 2, ty1)-(tx2 + k + 2, ty2), white '           plot switch
  2983.         NEXT k
  2984.         LINE (tx1 + 1, ty1)-(tx2 + 1, ty2), black2 '                  outline left
  2985.         LINE (tx1 + 3, ty1)-(tx2 + 4, ty2), black2 '                  outline right
  2986.     NEXT i
  2987. ' -------------------------------------------------------------------------------------------------------x
  2988. SUB Bar (xdat!, cl)
  2989.     xmax = gs - t '                                                   graphics start - ten
  2990.     xmin = xmax - 50
  2991.     ymax = 273 - osc * 39
  2992.     ymin = ymax - t
  2993.     'xcen = xmin + (xmax - xmin) / 2 '                                center line
  2994.     xbar = xmin + xdat! * (xmax - xmin) '                             data
  2995.     IF xbar < xmin THEN xbar = xmin '                                 limit min
  2996.     IF xbar > xmax THEN xbar = xmax '                                 limit max
  2997.  
  2998.     IF porb THEN '                                                    led bar
  2999.         IF LEDtri = 0 THEN c = LEDc
  3000.         IF cl THEN '                                                  center line
  3001.             LINE (xbar - 1, ymin + 4)-(xbar + 1, ymin + 7), c, BF
  3002.         ELSE
  3003.             LINE (xmin, ymin + 5)-(xbar, ymin + 7), c, BF
  3004.         END IF
  3005.     ELSE '                                                            mechanical pointer
  3006.         IF (osc = 4) AND (radarf = 0) THEN '                          altitude with radar off
  3007.             tc1 = gray
  3008.             tc2 = black
  3009.         ELSE '                                                        normal
  3010.             tc1 = white
  3011.             tc2 = white
  3012.         END IF
  3013.         LINE (xbar, ymin + 4)-(xbar - 4, ymin + 8), tc1
  3014.         LINE -(xbar + 4, ymin + 8), tc1
  3015.         LINE -(xbar, ymin + 4), tc1
  3016.         PAINT (xbar, ymin + 5), tc2, tc1
  3017.     END IF
  3018. ' -------------------------------------------------------------------------------------------------------x
  3019. SUB BlackHole (freeze) STATIC
  3020.     IF ei(3) = 0 THEN
  3021.         DIM tc(2)
  3022.         ei(3) = 1
  3023.         l! = aspect!
  3024.         tx = 30 + RND * 40
  3025.         IF RND > .7 THEN tx = tx + RND * h
  3026.         IF RND > .7 THEN tx = tx + RND * h '                          intentional repeat
  3027.         v! = tx / l!
  3028.         s1! = l! / t: r = RND * 90: ri = RND * 8 + 2
  3029.         bc = bc + 1 + (bc = 6) * 7
  3030.         z$ = "020105040906010613070603091301070605121404" '           colors
  3031.         FOR i = 0 TO 2
  3032.             tc(i) = VAL(MID$(z$, bc * 6 + i * 2 + 1, 2))
  3033.         NEXT i
  3034.         d1 = RND * 2 + 1
  3035.         d2 = RND * 2 + 1
  3036.     END IF
  3037.  
  3038.     x0 = localize(ex(3), 0, 0)
  3039.     y0 = ey(3)
  3040.  
  3041.     tri = ri
  3042.     IF freeze THEN tri = tri \ 2 '                                    rotation increment
  3043.     r = (r + tri) MOD tsix '                                           rotation
  3044.     dtlt! = -30 - 30 * ABS(c!((r * 3 + 50) MOD tsix)) '                tilt
  3045.     dtlti = (dtlt! + tsix) MOD tsix
  3046.     crot! = c!(r)
  3047.     srot! = s!(r)
  3048.     ctlt! = c!(dtlti) / d1
  3049.     stlt! = s!(dtlti) / d2
  3050.     co = (co + 1) MOD tsix
  3051.  
  3052.     bhx = 0: bhy = bhx
  3053.     FOR pass = 0 TO 1 '                                               90 degrees apart
  3054.         FOR za! = -l! TO l! STEP s1!
  3055.             pd = 0 '                                                  pen up
  3056.             FOR zb! = -l! TO l! STEP s1!
  3057.                 x1! = za!
  3058.                 y1! = zb!
  3059.                 IF pass THEN SWAP x1!, y1!
  3060.                 x! = x1! * crot! + y1! * srot!
  3061.                 y! = y1! * crot! - x1! * srot!
  3062.                 q! = -.8 / (x1! * x1! + y1! * y1!) + .8
  3063.                 z! = q! * ctlt! - y! * stlt!
  3064.                 y! = y! * ctlt! + q! * stlt!
  3065.                 s! = (l! * 2) / ((l! * 2) + y!)
  3066.                 xx = x0 + x! * v! * s!
  3067.                 yy = y0 - z! * v! * s!
  3068.                 x! = za! * 1.8: x! = x! * x!
  3069.                 y! = zb! * 1.8: y! = y! * y!
  3070.                 tc = tc((x! + y! + co) MOD 3)
  3071.                 IF pd THEN LINE -(xx, yy), tc ELSE PSET (xx, yy)
  3072.                 c1 = (xx > -120) AND (xx < 770)
  3073.                 c2 = (yy > -120) AND (yy < 470)
  3074.                 IF c1 AND c2 THEN '                                   on screen
  3075.                     bh = 1
  3076.                     IF (ABS(za!) < .1) AND (yy > bhy) THEN
  3077.                         bhx = xx
  3078.                         bhy = yy
  3079.                     END IF
  3080.                 END IF
  3081.                 pd = 1 '                                              pen down
  3082.             NEXT zb!
  3083.         NEXT za!
  3084.     NEXT pass
  3085. ' -------------------------------------------------------------------------------------------------------x
  3086. SUB BlackHoleDoom '                                                   fall in while shrinking
  3087.     fb$ = "" '                                                        silence feedback, if any
  3088.     sgs = gs '                                                        save graphics start (going to kill panel here)
  3089.     gs = 0 '                                                          kills panel
  3090.     VIEW
  3091.     DIM LMxi!(q2), LMyi!(q2)
  3092.     FOR i = 1 TO rp '                                                 rp=right pad (end of LM data)
  3093.         LMxi!(i) = (exl(3) - LMrx(i)) / 50
  3094.         LMyi!(i) = ((ey(3) + bhy) \ 2 - LMry(i)) / 50
  3095.     NEXT i
  3096.     FOR pass = 1 TO 50
  3097.         CLS
  3098.         mes$(0) = "Let's get SMALL! - Steve Martin"
  3099.         FOR i = 1 TO rp
  3100.             x = LMrx(i) + LMxi!(i) * pass
  3101.             y = LMry(i) + LMyi!(i) * pass
  3102.             c = LMc(i)
  3103.             IF (c = gasoline) AND (RND > pf!) THEN c = 0
  3104.             PSET (x, y), c
  3105.         NEXT i
  3106.         GOSUB ibd
  3107.         wu! = TIMER + .1
  3108.         DO: _LIMIT mdelay
  3109.             GOSUB ibd
  3110.             i$ = INKEY$
  3111.             IF (i$ = "q") OR (i$ = CHR$(27)) THEN Quit
  3112.         LOOP UNTIL TIMER > wu!
  3113.     NEXT pass
  3114.     mes$(0) = dead$
  3115.     mes$(1) = ""
  3116.     gs = sgs
  3117.     EXIT SUB
  3118.  
  3119.     ibd:
  3120.     Info
  3121.     BlackHole 1
  3122.     timemachine
  3123.     RETURN
  3124. ' -------------------------------------------------------------------------------------------------------x
  3125. SUB CMshadow (tx2, x1, x2)
  3126.     z = (TIMER MOD 17) + 1 '                                          rotation 1
  3127.     IF z < t THEN
  3128.         LINE (tx2 - 4, 17 + z)-(tx2 - 1, 17 + z), white
  3129.     END IF
  3130.     z = ((z + 8) MOD 17) + 1 '                                        rotation 2
  3131.     IF z < t THEN
  3132.         LINE (tx2 + 6, 17 + z)-(tx2 + 8, 17 + z), white
  3133.     END IF
  3134.     FOR tx = x1 TO x2 '                                               shadow
  3135.         FOR ty = 17 TO 26
  3136.             pp = POINT(tx, ty)
  3137.             zx = tx - x1 - (x2 - x1) \ 2
  3138.             zy = ty - 22
  3139.             IF (pp = white) AND (zy > (zx + 4)) THEN PSET (tx, ty), gray2
  3140.         NEXT ty
  3141.     NEXT tx
  3142. ' -------------------------------------------------------------------------------------------------------x
  3143. FUNCTION dcolor (v!, z1, z2, d) '                                     determine color for various displays
  3144.     dcolor = LEDc '                                                   normal
  3145.     IF liftoff = 0 THEN
  3146.         tv! = ABS(v!)
  3147.         IF d = 1 THEN '                                               problem higher
  3148.             IF tv! > z1 THEN dcolor = yellow '                        warning
  3149.             IF tv! > z2 THEN dcolor = red '                           serious warning
  3150.         ELSE '                                                        problem lower
  3151.             IF tv! < z1 THEN dcolor = yellow '                        warning
  3152.             IF tv! < z2 THEN dcolor = red '                           serious warning
  3153.         END IF
  3154.     END IF
  3155. ' -------------------------------------------------------------------------------------------------------x
  3156. SUB Evaluate (savea, z) '                                             landing analysis
  3157.     IF (ABS(z) > 4) AND (crash = 0) THEN
  3158.         IF ABS(savea) > 4 THEN
  3159.             z$ = "contact angle " + LTRIM$(STR$(-savea)) + CHR$(248)
  3160.             GOSUB tackon
  3161.         END IF
  3162.         IF ABS(z) > 4 THEN
  3163.             z$ = "ending angle " + LTRIM$(STR$(-(z))) + CHR$(248)
  3164.             GOSUB tackon
  3165.         END IF
  3166.     END IF
  3167.  
  3168.     IF ABS(vx!) > 3 THEN z$ = "horizontal velocity": GOSUB tackon
  3169.     IF ABS(vy!) > 3 THEN z$ = "vertical velocity": GOSUB tackon
  3170.     ok = -(LEN(fb$) = 0)
  3171.     z! = ABS(vx!)
  3172.     IF (z! <= 3) AND (vy! <= 3) THEN score = 5: z$ = "Poor"
  3173.     IF (z! <= 2) AND (vy! <= 2) THEN score = 4: z$ = "Fair"
  3174.     IF (z! <= 1) AND (vy! <= 1) THEN score = 3: z$ = "Good"
  3175.     IF (z! <= pf!) AND (vy! <= pf!) THEN score = 2: z$ = "Excellent"
  3176.     IF (z! < .1) AND (vy! < .1) THEN score = 1: z$ = "Fantastic"
  3177.     IF magic THEN z$ = "Magic"
  3178.     IF ok = 0 THEN z$ = "Bad"
  3179.     z$ = z$ + " landing"
  3180.     IF crash THEN fb$ = "": z$ = "CRASHED"
  3181.  
  3182.     IF lob THEN
  3183.         z$ = z$ + " on Borg": GOSUB tackon
  3184.         GOTO eother
  3185.     END IF
  3186.  
  3187.     v$ = "" '                                                         verb
  3188.     n$ = "" '                                                         noun
  3189.     ldis = q1 '                                                       last distance
  3190.  
  3191.     FOR i = 1 TO t '                                                  5wlemtsihg
  3192.         tx = sf(i, 2) - suri '                                        point of interest middle
  3193.         IF tx < 0 THEN tx = tx + q1
  3194.         poi$ = sf$(i) '                                               name of poi
  3195.         dis = ABS(px! - tx)
  3196.         IF (poi$ = "") OR (dis > ldis) THEN GOTO ni
  3197.         ldis = dis
  3198.         IF dis < h THEN
  3199.             n$ = poi$
  3200.             don = (sf(i, 2) - sf(i, 0)) + wi2 '                       distance to be "on"
  3201.             IF dis < don THEN
  3202.                 '        pad  349              LGM        Surveyor
  3203.                 IF (ABS(sy1 - q4) < 20) AND (i <> 3) AND (i <> 7) THEN
  3204.                     v$ = "in"
  3205.                 ELSE
  3206.                     v$ = "on"
  3207.                 END IF
  3208.             ELSE
  3209.                 v$ = "at"
  3210.             END IF
  3211.             IF ok THEN
  3212.                 IF (i = 1) THEN mes$(1) = "MIB will visit you shortly!"
  3213.                 IF (i = 3) AND (LGMc = gray) THEN n$ = "the ashes of " + n$
  3214.                 IF (i = 4) AND (v$ = "on") THEN mes$(1) = "On a volcano?  Are you crazy?"
  3215.                 IF (i = 5) THEN mes$(1) = "Buzz wants a Happy Meal!"
  3216.                 IF (i = t) AND (v$ = "on") THEN
  3217.                     mes$(1) = "Rude to land on a tombstone!"
  3218.                 END IF
  3219.             END IF
  3220.         END IF
  3221.         ni:
  3222.     NEXT i
  3223.  
  3224.     z$ = RTRIM$(z$ + " " + v$ + " " + n$): GOSUB tackon
  3225.  
  3226.     IF v$ = "in" THEN '                                               handle oddball cases
  3227.         IF n$ = sf$(6) THEN mes$(1) = "The aliens will not be pleased!"
  3228.         IF n$ = sf$(8) THEN mes$(1) = "Merged with the machine!"
  3229.         IF n$ = sf$(t) THEN mes$(1) = "Desecration of a grave!"
  3230.     END IF
  3231.  
  3232.     eother:
  3233.     IF fuel! = 0 THEN z$ = "ran out of fuel!": GOSUB tackon
  3234.     EXIT SUB
  3235.  
  3236.     tackon:
  3237.     IF LEN(fb$) THEN z$ = ", " + z$
  3238.     fb$ = fb$ + z$
  3239.     RETURN
  3240. ' -------------------------------------------------------------------------------------------------------x
  3241. SUB ExplodeLM
  3242.     DIM LMxi!(q2), LMyi!(q2)
  3243.     CountFuel = 0
  3244.     FOR i = 1 TO rp '                                                 for each pixel, a direction
  3245.         ta = RND * tsix '                                              pick an angle, any angle
  3246.         IF contact THEN ta = RND * 180 + 180 '                        upward only if on ground
  3247.         tf = RND * 20 + 2 '                                           force
  3248.         LMxi!(i) = tf * c!(ta) '                                      x increment
  3249.         LMyi!(i) = tf * s!(ta)
  3250.         IF LMc(i) = fuel THEN '                                       color
  3251.             CountFuel = CountFuel + 1
  3252.             IF CountFuel < ptk THEN LMc(i) = 0 '                      points to kill
  3253.         END IF
  3254.     NEXT i
  3255.     contact = 0
  3256.     fb$ = "" '                                                        eval feedback
  3257.     sgs = gs
  3258.     gs = 0 '                                                          full screen
  3259.     VIEW
  3260.     FOR pass = 1 TO 40 '                                              expanding debris
  3261.         CLS
  3262.         mes$(0) = dead$
  3263.         mes$(1) = ""
  3264.         Info '                                                        say why exploding
  3265.         FOR i = 1 TO rp
  3266.             LMrx(i) = LMrx(i) + LMxi!(i)
  3267.             LMry(i) = LMry(i) + LMyi!(i)
  3268.             LMyi!(i) = LMyi!(i) - grav! * (warp! = 0)
  3269.             x = (LMrx(i) - h) * aspect!
  3270.             y = LMry(i)
  3271.             s = i MOD 5 '                                             size
  3272.             LINE (x, y)-(x + s, y + s), LMc(i), BF
  3273.             z1 = ((RND * t) - 5) * 3
  3274.             z2 = ((RND * t) - 5) * 3
  3275.             LINE (x + z1, y + z2)-(x + z1 + s, y + z2 + s), LMc(i), BF
  3276.         NEXT i
  3277.         LINE (0, 0)-(q3, q4), 0, B '                                  erase ugly border
  3278.         timemachine
  3279.         w! = TIMER + .02: WHILE TIMER < w!: WEND
  3280.     NEXT pass
  3281.     gs = sgs
  3282. ' -------------------------------------------------------------------------------------------------------x
  3283. SUB ExplodeShell (s) '                                                not contact - when LM fires at them
  3284.     tx = shx(s) - suri
  3285.     ty = shy(s)
  3286.     LINE (tx - 5, ty - 5)-(tx + 5, ty + 5), black2, BF '              erase shell
  3287.  
  3288.     FOR d = t TO 30 STEP 2 '                                          distance
  3289.         FOR z = 0 TO 40 - d '                                         particles at above distance
  3290.             ang = RND * tsix '                                         angle
  3291.             tx2 = tx + d * c!(ang) * aspect!
  3292.             ty2 = ty + d * s!(ang)
  3293.             bit = bit XOR 1
  3294.             IF bit THEN c = red ELSE c = yellow
  3295.             PSET (tx2, ty2), c
  3296.         NEXT z
  3297.     NEXT d
  3298.     shx(s) = 0
  3299.     shd(s) = q1 '                                                     6400, any large number
  3300.     sia = sia - 1 '                                                   shells in air
  3301. ' -------------------------------------------------------------------------------------------------------x
  3302. SUB GetSurface (gh) '                                                 load surface array
  3303.     DIM lz(t) '                                                       landing zones
  3304.     f$ = "s" + LTRIM$(STR$(gh)) + ".dat" '                            0 - 10
  3305.     IF gh < 0 THEN f$ = "SL.DAT" '                                    l for level
  3306.     IF demo THEN f$ = "SD.DAT" '                                      d for demo
  3307.     CLOSE #6
  3308.     OPEN f$ FOR RANDOM AS #6 LEN = 2
  3309.     FOR i = 0 TO 6399
  3310.         GET #6, i + 1, gh(i)
  3311.     NEXT i
  3312.     FOR i = 1 TO t '                                                  create landing zones
  3313.         IF demo THEN '                                                compress onto 1 page
  3314.             lz(i) = 3050 + (i - 1) * 80
  3315.         ELSE
  3316.             lz(i) = 320 + (i - 1) * (q3 + 1) '                        1 per page
  3317.         END IF
  3318.     NEXT i
  3319.     IF demo THEN '                                                    all on one page
  3320.         SWAP lz(9), lz(t) '                                           move grave 1 page left
  3321.         SWAP lz(2), lz(4) '                                           move car wash 2 pages right
  3322.     END IF
  3323.     RESTORE features
  3324.     FOR i = 1 TO t
  3325.         READ sf$(i), x, y, lz '                                       sf = special feature
  3326.         sf(i, 0) = lz(i) - x \ 2 '                                    start
  3327.         IF demo AND (i = 9) THEN sf(i, 0) = 3750 '                    Hollywood
  3328.         sf(i, 1) = sf(i, 0) + x '                                     end
  3329.         sf(i, 2) = sf(i, 0) + x \ 2 '                                 middle
  3330.     NEXT i
  3331.     IF demo THEN '                                                    move LGM to top of grave
  3332.         sf(3, 0) = sf(t, 0) + 14 '                                    x left
  3333.         sf(3, 1) = sf(t, 1) + 14 '                                    x right
  3334.         sf(3, 2) = sf(t, 2) + 14 '                                    x middle
  3335.     END IF
  3336.     sspinit2 = 0
  3337. ' -------------------------------------------------------------------------------------------------------x
  3338. FUNCTION gety (x) '                                                   ground level for given x
  3339.     ax = ABS(x)
  3340.     xx = (suri + ax) MOD q1
  3341.     IF sy1 > 310 THEN
  3342.         c1 = (xx >= sf(2, 0)) '                                       car wash start
  3343.         c2 = (xx <= sf(2, 1)) '                                       car wash end
  3344.         IF c1 AND c2 THEN
  3345.             IF ASO THEN z = 320 ELSE z = 338 '                        safe zone start different with ascent stage only
  3346.             IF sy1 > z THEN
  3347.                 gety = q4 '                                           349, max y
  3348.                 EXIT FUNCTION
  3349.             END IF
  3350.         END IF
  3351.     END IF
  3352.     IF x < 0 THEN
  3353.         c1 = (ek(2) <> -1) AND (ek(2) < h)
  3354.         c2 = (skyoff = 0) AND (sy1 < borgt) AND (ax > borgl) AND (ax < borgr)
  3355.         IF c1 AND c2 THEN
  3356.             gety = borgt
  3357.             EXIT FUNCTION
  3358.         END IF
  3359.     END IF
  3360.     gety = gh(xx)
  3361. ' -------------------------------------------------------------------------------------------------------x
  3362. SUB Hollywood
  3363.     FOR i = 1 TO 9
  3364.         tx = x + i * 16
  3365.         ty = gety(tx) - 14
  3366.         PrintVGA MID$("HOLLYWOOD", i, 1), tx - 4, ty, white, black
  3367.         LINE (tx, ty + 9)-(tx, ty + 22), gray2
  3368.     NEXT i
  3369. ' -------------------------------------------------------------------------------------------------------x
  3370.     DIM a(1)
  3371.     x0 = x
  3372.     y0 = 304
  3373.     IF bolthitf THEN tc = white ELSE tc = gasoline '                  lightning bolt from deathstar
  3374.     LINE (x0, y0)-(x0 + 50, y0 + 45), tc, BF '                        entire area
  3375.     LINE (x0, y0)-(x0 + 50, y0 + 45), gray, B '                       outline
  3376.  
  3377.     LINE (x0, y0 - 1)-(x0, y0 - 30), gray2 '                          light towers
  3378.     LINE (x0 + 50, y0 - 1)-(x0 + 50, y0 - 30), gray2
  3379.  
  3380.     IF bbit THEN '                                                    global seconds toggle
  3381.         PSET (x0, y0 - 30), red '                                     lights on towers
  3382.         PSET (x0 + 50, y0 - 30), red
  3383.         ltoggle = ltoggle XOR 1
  3384.         IF ltoggle THEN
  3385.             PSET (x0, y0 - 31), red
  3386.             PSET (x0 + 50, y0 - 31), red
  3387.             LINE (x0 - 2, y0 - 30)-STEP(4, 0), red
  3388.             LINE (x0 + 48, y0 - 30)-STEP(4, 0), red
  3389.         END IF
  3390.     END IF
  3391.  
  3392.     IF a(0) = 0 THEN a(0) = 30: a(1) = 150 '                          initial marker positions
  3393.     IF RND > pf! THEN '                                               reel mark direction&speed
  3394.         tdir = SGN(RND - pf!) * INT(RND * 4 + 2)
  3395.         IF RND > .8 THEN tdir = 0 '                                   sometimes not moving
  3396.     END IF
  3397.     LINE (x0 + 6, y0 + 15)-(x0 + 19, y0 + 21), black2 '               tape
  3398.     LINE -(x0 + 33, y0 + 21), black2
  3399.     LINE -(x0 + 44, y0 + 15), black2
  3400.     LINE (x0 + 24, y0 + 19)-STEP(3, 1), dred, BF '                    head
  3401.     FOR i = 0 TO 1 '                                                  reels/rollers
  3402.         a(i) = (a(i) + t * tdir + tsix) MOD tsix '                      marker angle
  3403.         x = x0 + 13 + i * 24
  3404.         y = y0 + 11
  3405.         FOR d! = 5 TO 9
  3406.             CIRCLE (x, y), d!, white, , , .73 '                       reel
  3407.             CIRCLE (x, y), d!, white, , , .68
  3408.         NEXT d!
  3409.         x1 = x + 3 * s!(a(i)) * grav!
  3410.         y1 = y + 3 * c!(a(i))
  3411.         x2 = x + 6 * s!(a(i)) * grav!
  3412.         y2 = y + 6 * c!(a(i))
  3413.         LINE (x1, y1)-(x2, y2), black2 '                              rotation marker
  3414.         FOR d = 0 TO 4 '                                              hub
  3415.             CIRCLE (x, y), d, dred, , , .73
  3416.         NEXT d
  3417.     NEXT i
  3418.  
  3419.     IF sia > 0 THEN '                                                 shells in air = building gets MEAN title
  3420.         PrintLines "HAL", 0, 47, x0 + 1, y0 + 39, red, white, 1, 2
  3421.     ELSE
  3422.         PrintLines "IBM", 0, 47, x0, y0 + 39, blue, white, 1, 2
  3423.     END IF
  3424.  
  3425.     '                                                                 binary clock
  3426.     z$ = TIME$ '                                                      hh:mm:ss
  3427.     z$ = LEFT$(z$, 2) + MID$(z$, 4, 2) + RIGHT$(z$, 2) '              hhmmss
  3428.     FOR i = 1 TO 6
  3429.         v = VAL(MID$(z$, i, 1)) '                                     value
  3430.         x = x0 + i * 5 + 2 - (i > 2) * 5 - (i > 4) * 5 '              column
  3431.         z = VAL(MID$("132323", i, 1)) '                               rows for this column
  3432.         FOR j = 0 TO z
  3433.             IF v AND 1 THEN c = red ELSE c = black2 '                 red = on
  3434.             v = v \ 2
  3435.             y = glmax - 2 - j * 2
  3436.             LINE (x - 1, y)-(x + 1, y), c, B '                        show bit
  3437.         NEXT j
  3438.     NEXT i
  3439.  
  3440.     IF ttf! < -2 THEN fat! = TIMER + 10
  3441.     ttf! = fat! - TIMER '                                             time to fire
  3442.     IF fat! > 86400 THEN fat! = t: ttf! = 0
  3443.  
  3444.     IF (ttf! > 0) AND (ttf! < 1) THEN '                               optional radar
  3445.         sky = (sky + 1) MOD tsix
  3446.         x1 = x0 + 25
  3447.         FOR sky2 = 0 TO 180 STEP 5
  3448.             zz = (sky + sky2) MOD 180
  3449.             x2 = x1 + q2 * c!(zz)
  3450.             y2 = (y0 - 1) - q2 * s!(zz) - 1
  3451.             LINE (x1, y0 - 1)-(x2, y2), red, , &H1111
  3452.         NEXT sky2
  3453.     END IF
  3454.  
  3455.     IF pat1& = 0 THEN pat1& = &H5555: pat2& = &HAAAA
  3456.     SWAP pat1&, pat2& '                                               countdown to firing
  3457.     z! = ttf!: IF z! < 0 THEN z! = 0
  3458.     tx = x0 + z! / t * 48
  3459.     IF tx > (x0 + 48) THEN tx = xo + 48 '                             crude fix for a midnite crossing
  3460.     ty = y0 + 1
  3461.     LINE (x0 + 1, ty)-(tx, ty), black2, , pat1&
  3462.     LINE (x0 + 1, ty)-(tx, ty), red, , pat2&
  3463.  
  3464.     IF (sia < 20) AND (shoot OR (ttf! <= 0)) THEN '                   initialize shell
  3465.         shoot = 0
  3466.         FOR s = 1 TO 20
  3467.             IF shx(s) = 0 THEN
  3468.                 sia = sia + 1 '                                       shells in air
  3469.                 shx(s) = suri + x0 + 25
  3470.                 shy(s) = 320
  3471.                 shellv = (-32 + (RND - pf!) * t) * t '                velocity
  3472.                 ta = 0
  3473.                 IF RND > .1 THEN '                                    smart 10%
  3474.                     IF RND > pf! THEN
  3475.                         ta = -RND * 25
  3476.                     ELSE
  3477.                         ta = RND * 50 '                               above or below
  3478.                     END IF
  3479.                     ta = ta + (RND - pf!) * 4 '                       vary it a little
  3480.                 END IF
  3481.                 dx = px! - shx(s) + suri
  3482.                 dy = shy(s) - py!
  3483.                 IF dy = 0 THEN dy = 1
  3484.                 shella = _R2D(ATN(dx / dy)) + (90 - 5 * SGN(dx) + ta)
  3485.                 IF py! > 280 THEN
  3486.                     shella = 90 + (RND - pf!) * 40
  3487.                     shellv = shellv * .75
  3488.                 END IF
  3489.                 shella = (shella + tsix) MOD tsix
  3490.                 shvx(s) = (shellv / t) * c!(shella)
  3491.                 shvy(s) = (shellv / t) * s!(shella)
  3492.                 shd(s) = q1
  3493.                 EXIT FOR
  3494.             END IF
  3495.         NEXT s
  3496.     END IF
  3497. ' -------------------------------------------------------------------------------------------------------x
  3498. SUB Info STATIC '                                                     show messages
  3499.     DIM lenmes(1)
  3500.     IF LEN(fb$) THEN mes$(0) = UCASE$(fb$): sm!(0) = mTIMER
  3501.  
  3502.     FOR i = 0 TO 1
  3503.         IF mes$(i) <> omes$(i) THEN sm!(i) = 0
  3504.         lenmes(i) = LEN(mes$(i))
  3505.         IF lenmes(i) AND (sm!(i) = 0) THEN
  3506.             sm!(i) = TIMER
  3507.             omes$(i) = mes$(i)
  3508.         END IF
  3509.         el! = TIMER - sm!(i)
  3510.         IF el! > 5 THEN mes$(i) = "": sm!(i) = 0
  3511.     NEXT i
  3512.     tcenter = (q3 + gs) \ 2 '                                         center of "space" area
  3513.     IF lenmes(0) THEN
  3514.         c1 = white2: c2 = gray
  3515.         z$ = LTRIM$(mes$(0))
  3516.         l3$ = LEFT$(z$, 3)
  3517.         IF l3$ = "CM:" THEN c1 = red '                                rendesvous chatter
  3518.         IF l3$ = "DAN" THEN c1 = red '                                Danger, Will Robinson
  3519.         IF c1 = red THEN c2 = black2
  3520.         IF (convo > 0) OR (INSTR("EstWARRad", l3$) > 0) THEN
  3521.             PrintVGA z$, tcenter - lenmes(0) * 4, 5, c1, -1
  3522.         ELSE
  3523.             IF lenmes(0) > (34 - (gs = 0) * 5) THEN
  3524.                 tcol = (tcol + 4) MOD (lenmes(0) * t)
  3525.                 z$ = SPACE$(4) + z$
  3526.                 PrintLines z$, tcol, tcol + 40 * 16, gs, 20, c1, c2, 2, 2
  3527.             ELSE
  3528.                 tx = tcenter - LEN(z$) * 8
  3529.                 'LINE (gs, 6)-(q3, 17), 0, BF
  3530.                 PrintLines z$, 0, lenmes(0) * 16 - 1, tx, 20, c1, c2, 2, 2
  3531.             END IF
  3532.         END IF
  3533.     END IF
  3534.  
  3535.     IF lenmes(1) THEN '                                               subordinate msg
  3536.         IF lenmes(0) THEN ty = 30 ELSE ty = 5
  3537.         PrintVGA mes$(1), tcenter - lenmes(1) * 4, ty, red, dred
  3538.     END IF
  3539.  
  3540.     IF (invincible = 0) AND (rads >= h) AND (TIMER < rtl!(0)) THEN
  3541.         z = rads \ h
  3542.         IF z >= t THEN radiationdeath = 1: z = t '                    >= ten
  3543.         IF z <= t THEN '                                              <= ten
  3544.             RESTORE radcomments
  3545.             FOR i = 1 TO z
  3546.                 READ z$
  3547.             NEXT i
  3548.             IF VAL(LEFT$(z$, 1)) THEN '                               does it start with a #?
  3549.                 z$ = "ensures your death within " + z$ '              yes, tack on phrase
  3550.             END IF
  3551.             mes$(1) = "Radiation exposure " + z$ + "!"
  3552.         END IF
  3553.     END IF
  3554. ' -------------------------------------------------------------------------------------------------------x
  3555. SUB LEDdisplay (t$) STATIC
  3556.     IF LEDinit = 0 THEN
  3557.         DIM segment(6, 3), number$(11)
  3558.         RESTORE leds
  3559.         FOR i = 0 TO 6
  3560.             READ g$
  3561.             FOR j = 0 TO 3
  3562.                 READ segment(i, j)
  3563.             NEXT j
  3564.         NEXT i
  3565.         FOR i = 0 TO 11
  3566.             READ g$, number$(i)
  3567.         NEXT i
  3568.         LEDinit = 1
  3569.     END IF
  3570.  
  3571.     IF (osc < 6) OR (osc = t) THEN '                                  fuel,alt,h,v,thrust,angle
  3572.         tc = c: IF LEDtri = 0 THEN tc = LEDc
  3573.         IF osc = t THEN '                                             angle
  3574.             segx = 14: segy = 14 '                                    segment size
  3575.             tx = 92 - LEN(t$) * segx * 2
  3576.             ty = 298
  3577.         ELSE
  3578.             tl = (LEN(t$) - SGN(INSTR(t$, "."))) * 16
  3579.             tx = gs - tl
  3580.             ty = 296 - osc * 39
  3581.             segx = 8: segy = 8
  3582.         END IF
  3583.     ELSE '                                                            6clock 7dtm 8speed 9rads
  3584.         IF osc = 9 THEN tc = red ELSE tc = orange
  3585.         IF crash THEN tc = white2
  3586.         tx = 50
  3587.         ty = 35 + (osc - 6) * 9
  3588.         IF osc = 9 THEN ty = 62
  3589.         segx = 4: segy = 3
  3590.     END IF
  3591.  
  3592.     IF crash AND (osc <> 6) THEN EXIT SUB '                           allow clock
  3593.  
  3594.     dpp = 0 '                                                         decimal point
  3595.     FOR si = 1 TO LEN(t$)
  3596.         z$ = MID$(t$, si, 1)
  3597.         IF z$ = "." THEN '                                            plot sub can't handle decimal
  3598.             tx1 = tx + (si - 1) * 16 - 5
  3599.             LINE (tx1, ty - 1)-(tx1 + 1, ty), tc, BF
  3600.             dpp = 1
  3601.         ELSE
  3602.             z = VAL(z$)
  3603.             IF z$ = "-" THEN z = t
  3604.             IF z$ = "L" THEN z = 11 '                                 "L" for lock fuel and level ground
  3605.             IF z$ <> " " THEN GOSUB leddigit
  3606.         END IF
  3607.     NEXT si
  3608.  
  3609.     IF osc = 6 THEN '                                                 colon for clock
  3610.         IF crash THEN bbit = 1
  3611.         PSET (tx + 14, ty - 4), tc * bbit
  3612.         PSET (tx + 14, ty - 2), tc * bbit
  3613.     END IF
  3614.     EXIT SUB
  3615.  
  3616.     leddigit:
  3617.     FOR i = 1 TO LEN(number$(z))
  3618.         seg$ = MID$(number$(z), i, 1)
  3619.         IF INSTR("abcdefg", z$) THEN seg$ = z$ '                      for wave effect
  3620.         segn = ASC(seg$) - 97
  3621.         x0 = tx + (si - 1 - dpp) * (segx * 2)
  3622.         x1 = x0 + segment(segn, 0) * segx
  3623.         y1 = ty + segment(segn, 1) * segy
  3624.         x2 = x0 + segment(segn, 2) * segx
  3625.         y2 = ty + segment(segn, 3) * segy
  3626.         IF x1 < x2 THEN
  3627.             LINE (x1 + 1, y1)-(x2 - 1, y1), tc '                      horizontal
  3628.             IF osc = t THEN '                                         angle (very thick)
  3629.                 LINE (x1 + 2, y1 - 1)-(x2 - 2, y1 - 1), tc
  3630.                 LINE (x1 + 2, y1 + 1)-(x2 - 2, y1 + 1), tc
  3631.             END IF
  3632.         ELSE
  3633.             LINE (x1, y1 + 1)-(x1, y2 - 1), tc '                      vertical
  3634.             IF osc = t THEN '                                         angle (very thick)
  3635.                 LINE (x1 - 1, y1 + 2)-(x1 - 1, y2 - 2), tc
  3636.                 LINE (x1 + 1, y1 + 2)-(x1 + 1, y2 - 2), tc
  3637.             END IF
  3638.         END IF
  3639.     NEXT i
  3640.     RETURN
  3641. ' -------------------------------------------------------------------------------------------------------x
  3642. SUB LMbloads
  3643.     p = ASO * 3 + 4
  3644.  
  3645.     s& = VARSEG(LMx(0))
  3646.     o& = VARPTR(LMx(0))
  3647.     DEF SEG = s&
  3648.     BLOAD f$(p), o&
  3649.  
  3650.     s& = VARSEG(LMy(0))
  3651.     o& = VARPTR(LMy(0))
  3652.     DEF SEG = s&
  3653.     BLOAD f$(p + 1), o&
  3654.  
  3655.     s& = VARSEG(LMc(0))
  3656.     o& = VARPTR(LMc(0))
  3657.     DEF SEG = s&
  3658.     BLOAD f$(p + 2), o&
  3659. ' -------------------------------------------------------------------------------------------------------x
  3660. SUB LMdistort
  3661.     FOR i = 1 TO rp
  3662.         IF (LMc(i) = craft) AND (RND > .6) THEN
  3663.             LMx(i) = LMx(i) + RND * 3 - 1
  3664.             LMy(i) = LMy(i) + RND * 3 - 1
  3665.         END IF
  3666.     NEXT i
  3667. ' -------------------------------------------------------------------------------------------------------x
  3668. SUB LoadPanel STATIC
  3669.     IF pload = 0 THEN
  3670.         z = 12500
  3671.         REDIM pb(z)
  3672.         tf$ = "PANEL" + CHR$(48 + background) + ".DAT"
  3673.         s& = VARSEG(pb(0))
  3674.         o& = VARPTR(pb(0))
  3675.         DEF SEG = s&
  3676.         BLOAD tf$, o&
  3677.         pload = 1
  3678.     END IF
  3679.     PUT (0, 67), pb(), PSET
  3680. ' -------------------------------------------------------------------------------------------------------x
  3681. FUNCTION localize (tx, p, m)
  3682.     z0 = 9999 '                                                       assume out of range
  3683.     z1 = suri - m '                                                   surface index - minus
  3684.     z2 = suri + p + q3 '                                              surface index + plus
  3685.     FOR z = -1 TO 1 '                                                 page before, current, next
  3686.         zx = tx + z * q1
  3687.         IF (zx <= z2) AND (zx >= z1) THEN z0 = tx - suri + q1 * z
  3688.     NEXT z
  3689.     localize = z0 '                                                   return 9999 or calculated
  3690. ' -------------------------------------------------------------------------------------------------------x
  3691. SUB Map
  3692.     LINE (0, 0)-(gs - 1, 1), blue2, BF
  3693.     FOR i = 1 TO 17 + ufof
  3694.         IF i <= t THEN '                                              surface features
  3695.             tx = sf(i, 2)
  3696.             IF tx = -1 THEN GOTO skipf '                              destroyed
  3697.             tc = blue
  3698.             z$ = sf$(i) '                                             surface feature name
  3699.             IF i = 3 THEN z$ = "LGM" '                                shorten some names
  3700.             IF i = 5 THEN z$ = "McD"
  3701.             IF i = 7 THEN z$ = "SSC"
  3702.             GOTO wubba
  3703.         END IF
  3704.         IF i = (17 + ufof) THEN
  3705.             tc = white
  3706.             tx = (suri + px!) MOD (q1 + 1)
  3707.             z$ = "LM"
  3708.         ELSE '                                                        sky feature
  3709.             IF skyoff THEN GOTO skipf
  3710.             j = i - 11
  3711.             IF (ek(j) = -1) OR eou THEN GOTO skipf '                  destroyed or not present
  3712.             IF j THEN tc = red ELSE tc = green '                      CM green, rest red
  3713.             tx = ex(j)
  3714.             '                     1    2    3    4    5    6
  3715.             '                 12345123451234512345123451234512345
  3716.             z$ = RTRIM$(MID$("CM   EPCORBorg BH   Worm CometAlien", j * 5 + 1, 5))
  3717.             IF j = 0 THEN z$ = z$ + STR$(exv(0)) '                    CM + velocity
  3718.         END IF
  3719.  
  3720.         wubba:
  3721.         tx = tx \ t
  3722.         LINE (tx, 0)-(tx + 1, 1), tc, BF
  3723.         zz = LEN(mes$(0)) + LEN(mes$(1)) - (liftoff = 1) '            quash names when messages active and during liftoff
  3724.         IF (zz = 0) AND (tx > (gs + 6)) THEN PrintLines z$, 0, LEN(z$) * 8, tx - 6, 16, tc, -99, 0, 1
  3725.         skipf:
  3726.     NEXT i
  3727. ' -------------------------------------------------------------------------------------------------------x
  3728. SUB McD STATIC '                                                      37 * 16
  3729.     IF McDi = 0 THEN '                                                initialize
  3730.         z$ = "    Burger, fries & Coke only $1.99!"
  3731.         FOR i = 1 TO LEN(z$) '                                        Morse code
  3732.             c$ = MID$(z$, i, 1)
  3733.             RESTORE MorseData
  3734.             FOR j = 1 TO 39
  3735.                 READ d$, x$
  3736.                 IF d$ = LCASE$(c$) THEN m$ = m$ + x$ + " "
  3737.             NEXT j
  3738.         NEXT i
  3739.         McDi = 1
  3740.     END IF
  3741.  
  3742.     mp = (mp + 4) MOD 320 '                                           show ad in text
  3743.     x2 = x + 38
  3744.     IF bolthitf THEN tc = white ELSE tc = gold
  3745.     LINE (x, glmax)-(x2, glmax - 19), tc, BF '                        clear sign area
  3746.     PrintLines z$, mp, mp + 37, x, glmax - 1, red, black2, 1, 1
  3747.  
  3748.     FOR mx = x TO x2 - 1 '                                            arch & red neon
  3749.         my = gety(mx)
  3750.         arch = (arch + 1) MOD t
  3751.         IF arch < 2 THEN tc = red ELSE tc = gold
  3752.         IF bolthitf THEN tc = white
  3753.         IF mx > x THEN LINE (mx, my)-(mx, my + 2), tc
  3754.         tmx = x + x2 - mx - 2
  3755.         IF tmx > x THEN LINE (tmx, glmax - 19)-(tmx + 2, glmax - 18), tc, BF
  3756.     NEXT mx
  3757.  
  3758.     y = glmax - 1 '                                                   show ad in Morse
  3759.     i = 0
  3760.     z = (z MOD LEN(m$)) + 1
  3761.     DO
  3762.         j = ((z + i) MOD LEN(m$)) + 1
  3763.         i = i + 1
  3764.         p = INSTR(".- ", MID$(m$, j, 1)) - 1
  3765.         IF p < 2 THEN LINE (x, y)-(x + p * 2, y), black2
  3766.         x = x + (p + 1) * 2
  3767.     LOOP UNTIL (x + 2) > x2
  3768. ' -------------------------------------------------------------------------------------------------------x
  3769. FUNCTION OnOff$ (v)
  3770.     OnOff$ = MID$("OFFON ", v * 3 + 1, 3)
  3771. ' -------------------------------------------------------------------------------------------------------x
  3772. SUB PrepAndShowLED (t!, nd, dp) STATIC
  3773.     osc = osc + 1
  3774.     IF dp = t THEN dp = 0: osc = 9
  3775.  
  3776.     ti = FIX(t!)
  3777.     z! = ABS(t! - ti)
  3778.     s$ = SPACE$(6)
  3779.     IF (t! < 0) AND (ti = 0) THEN
  3780.         t1$ = RIGHT$(s$ + "-" + LTRIM$(STR$(ti)), nd)
  3781.     ELSE
  3782.         t1$ = RIGHT$(s$ + LTRIM$(STR$(ti)), nd)
  3783.     END IF
  3784.  
  3785.     t2a$ = LTRIM$(STR$(INT(z! * (t ^ dp))))
  3786.     IF LEN(t2a$) < dp THEN t2a$ = RIGHT$("000" + t2a$, dp)
  3787.     t2$ = LEFT$(LTRIM$(t2a$) + "0000", dp)
  3788.     IF dp = 0 THEN z$ = t1$ ELSE z$ = t1$ + "." + t2$
  3789.  
  3790.     IF z$ = " -0.00" THEN z$ = "  0.00"
  3791.  
  3792.     IF (osc = 9) AND (t! = 0) THEN '                                  usually count for rads, lightning
  3793.         cylon = (cylon + 1) MOD 6 '                                   when blank, cycle a "-"
  3794.         zz = VAL(MID$("123432", cylon + 1, 1))
  3795.         z$ = "    "
  3796.         MID$(z$, zz, 1) = "-"
  3797.     END IF
  3798.  
  3799.     IF osc = 4 THEN
  3800.         IF (liftoff = 0) AND level THEN MID$(z$, 1, 1) = "L" '        altitude
  3801.         IF radarf = 0 THEN z$ = " ----"
  3802.     END IF
  3803.  
  3804.     IF (osc = 5) AND lockfuel THEN MID$(z$, 1, 1) = "L" '             fuel
  3805.  
  3806.     IF warp! > 0 THEN
  3807.         IF osc = 4 THEN z$ = " ----" '                                suppress altitude
  3808.         IF osc = 7 THEN z$ = "----" '                                 distance to McDonalds
  3809.     END IF
  3810.  
  3811.     LEDdisplay z$
  3812. ' -------------------------------------------------------------------------------------------------------x
  3813. SUB PrintCGA (c$, x, y, tc1, tc2, compress) STATIC '                  CGA font, 8 * 8
  3814.     c1 = tc1
  3815.     c2 = tc2
  3816.     IF y = -1 THEN '                                                  single char panel stuff - F for Fuel, etc.
  3817.         c2 = -1
  3818.         y = 263 - osc * 39
  3819.         tx1 = x - 3
  3820.         tx2 = x + 11
  3821.         ty1 = y
  3822.         ty2 = y + t
  3823.         IF bbit AND (LEDc = green) AND (radarf > 0) AND (contact = 0) AND ((c1 = red) OR (c1 = yellow)) THEN
  3824.             LINE (tx1 + 1, ty1 + 1)-(tx2 - 1, ty2 - 1), c1, BF
  3825.             c1 = black2
  3826.         ELSE
  3827.             IF (osc = 4) AND (radarf = 0) THEN c1 = gray ELSE c1 = white
  3828.         END IF
  3829.     END IF
  3830.  
  3831.     IF y + 9 > glmax THEN EXIT SUB
  3832.     tx = x + 1
  3833.  
  3834.     FOR i = 1 TO LEN(c$)
  3835.         d = ASC(MID$(c$, i, 1))
  3836.         FOR k = 0 TO 7
  3837.             IF p2(d, k) OR (compress = 0) THEN
  3838.                 IF c2 >= 0 THEN
  3839.                     LINE (tx + 1, y + 2)-(tx + 1, y + t), c2, , p2(d, k)
  3840.                 END IF
  3841.                 LINE (tx, y + 1)-(tx, y + 9), c1, , p2(d, k)
  3842.                 tx = tx + 1
  3843.             END IF
  3844.         NEXT k
  3845.     NEXT i
  3846. ' -------------------------------------------------------------------------------------------------------x
  3847. SUB PrintLines (d$, i1, i2, x1, y1, c1, c2, sd, s) STATIC
  3848.     ' chars, index1, index2, x,y, color 1, color 2, shadow distance,size
  3849.     slant = -(c2 < -20)
  3850.     FOR i = i1 TO i2 - 1
  3851.         z = i \ (8 * s) + 1
  3852.         IF z > LEN(d$) THEN d = 32 ELSE d = ASC(MID$(d$, z, 1))
  3853.         IF d = 248 THEN d = 0 '                                       degree symbol
  3854.         m& = _SHL(1, (7 - (i \ s) MOD 8))
  3855.         p& = 0
  3856.         FOR j = 0 TO 13
  3857.             p& = p& * 2 + SGN((p(d, 13 - j) AND m&))
  3858.         NEXT j
  3859.         IF c2 = -99 THEN '                                            vertical
  3860.             ty1 = y1 + (i - i1)
  3861.             ty2 = ty1 - slant * 13
  3862.             LINE (x1, ty1)-(x1 + 13, ty2), c1, , p& * 2
  3863.         ELSE '                                                        horizontal
  3864.             tx1 = x1 + i - i1 + 1
  3865.             tx2 = tx1 + slant * 15
  3866.             ty2 = y1 - 15
  3867.             LINE (tx1, y1)-(tx2, ty2), c1, , p&
  3868.             IF c2 >= 0 THEN LINE (tx1 + sd, y1)-(tx2 + sd, ty2), c2, , p&
  3869.         END IF
  3870.     NEXT i
  3871. ' -------------------------------------------------------------------------------------------------------x
  3872. SUB PrintVGA (z$, tx, ty, c1, c2) '                                   VGA font, 8 * 14
  3873.     PrintLines z$, 0, LEN(z$) * 8 - 1, tx, ty + 13, c1, c2, 1, 1
  3874. ' -------------------------------------------------------------------------------------------------------x
  3875. SUB Setcolor
  3876.     '          b g g r g g w g d g b o b y w
  3877.     '          l r u e a y h y r o k r 2 e h
  3878.     '          1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  3879.     IF bw THEN '
  3880.         z$ = "070707075607070756070007565656" '                       black and white (because I can!)
  3881.     ELSE
  3882.         z$ = "010249042456075632380052085407" '                       color
  3883.         'z$ = "010249322456075632380052085407" '                       color
  3884.     END IF
  3885.     FOR i = 0 TO 14
  3886.         PALETTE i + 1, VAL(MID$(z$, i * 2 + 1, 2))
  3887.     NEXT i
  3888. ' -------------------------------------------------------------------------------------------------------x
  3889. SUB Shells STATIC
  3890.     FOR s = 0 TO 20 '                                                 0 element is bomb, others from IBM
  3891.         IF shx(s) = 0 THEN GOTO nextshell '                           never active or already exploded
  3892.         shvy(s) = shvy(s) + grav! '                                   gravity
  3893.         shx(s) = shx(s) + shvx(s)
  3894.         shy(s) = shy(s) + shvy(s)
  3895.         tsx = shx(s) - suri
  3896.         tsy = shy(s)
  3897.  
  3898.         IF (s > 0) AND (crash = 0) THEN
  3899.             dx! = tsx - px!
  3900.             dy! = (tsy - py!) * aspect!
  3901.             shd(s) = SQR(dx! * dx! + dy! * dy!)
  3902.             IF (invincible = 0) AND (shd(s) < 20) THEN
  3903.                 dead$ = "HAL KILLED YOU"
  3904.                 EXIT SUB
  3905.             END IF
  3906.         END IF
  3907.  
  3908.         IF (tsy > 0) AND (shvy(s) > 0) AND ((tsy + shvy(s)) > gety(tsx)) THEN
  3909.             tsy = gety(tsx)
  3910.             FOR a2 = 0 TO tsix STEP 30 '                               explode, make star
  3911.                 bit = bit XOR 1 '                                     toggle
  3912.                 d2 = bit * t + t / 2
  3913.                 x2 = tsx + d2 * c!(a2) * aspect!
  3914.                 y2 = tsy + d2 * s!(a2)
  3915.                 IF a2 THEN LINE -(x2, y2), gold ELSE PSET (x2, y2), gold
  3916.             NEXT a2
  3917.             PAINT (tsx, tsy), gold, gold
  3918.             shx(s) = 0
  3919.             sia = sia - 1
  3920.             IF s = 0 THEN GOSUB makecrater
  3921.         ELSE '                                                        show shell
  3922.             IF shvx(s) < 0 THEN ai = -30 ELSE ai = 30 '               spin
  3923.             sha(s) = (sha(s) + ai + tsix) MOD tsix
  3924.             ss = 3 + (s = 0) * 2
  3925.             FOR i = 0 TO 1
  3926.                 IF i THEN cc = red ELSE cc = gold
  3927.                 a1 = (sha(s) + i * 180) MOD tsix '                     angle 1
  3928.                 a2 = a1 + 150 '                                       angle 2
  3929.                 ex = tsx + ss * c!(a1) * aspect! '                    1 of the endpoints
  3930.                 ey = tsy + ss * s!(a1) '                              a line from an endpoint to
  3931.                 FOR j = a1 TO a2 STEP t '                             each point on the half circle
  3932.                     zk = j MOD tsix '                                  seemed easier than a paint
  3933.                     zx = tsx + ss * c!(zk) * aspect!
  3934.                     zy = tsy + ss * s!(zk)
  3935.                     LINE (zx, zy)-(ex, ey), cc
  3936.                 NEXT j
  3937.             NEXT i
  3938.         END IF
  3939.         nextshell:
  3940.     NEXT s
  3941.     EXIT SUB
  3942.  
  3943.     makecrater:
  3944.     dd = ABS(sf(sf, 2) - suri - tsx) '                                distance to current surface feature
  3945.     IF dd < t THEN sf(sf, 2) = -1 '                                   under ten from a surface feature, kill feature
  3946.  
  3947.     zz = 40 '                                                         distance +- impact
  3948.     r1 = RND * 40
  3949.     r2 = RND * 40 + 40
  3950.     FOR crx = -zz TO zz
  3951.         ta = (crx * 2 + 270) MOD tsix '                                angle
  3952.         tx = tsx + crx
  3953.         ty = gety(tc) - r1 - r2 * s!(ta)
  3954.         IF ty > glmax THEN ty = glmax
  3955.         ti = ((suri + tx + q1) MOD q1)
  3956.         gh(ti) = ty
  3957.         IF iscd = 0 THEN PUT #6, ti + 1, ty
  3958.     NEXT crx
  3959.  
  3960.     ti = (suri + tsx - zz - 1 + q1) MOD q1
  3961.     Smooth ti
  3962.     ti = (suri + tsx + zz) MOD q1
  3963.     Smooth ti
  3964.     RETURN
  3965. ' -------------------------------------------------------------------------------------------------------x
  3966. SUB ShowAngle (a)
  3967.     zc = dcolor(CSNG(a), 0, 4, 1)
  3968.     c = zc
  3969.     IF (bbit = 0) AND (contact = 0) THEN c = black '                  blink
  3970.     IF a = 0 THEN z$ = "  "
  3971.     IF a > 0 THEN z$ = CHR$(17) + " " '                               point left
  3972.     IF a < 0 THEN z$ = " " + CHR$(16) '                               point right
  3973.     PrintVGA z$, 7, 270, c, black2
  3974.     IF LEDtri THEN c = zc ELSE c = LEDc
  3975.     osc = t
  3976.     a$ = LTRIM$(STR$(-a))
  3977.     LEDdisplay a$
  3978. ' -------------------------------------------------------------------------------------------------------x
  3979. SUB Surveyor STATIC
  3980.     DIM SSp&(1, 26), x(1), y(1)
  3981.     IF sspinit1 = 0 THEN
  3982.         s& = VARSEG(SSp&(0, 0))
  3983.         o& = VARPTR(SSp&(0, 0))
  3984.         DEF SEG = s&
  3985.         BLOAD f$(17), o& '                                            surv2.dat
  3986.         sc = white
  3987.         sspinit1 = 1
  3988.     END IF
  3989.  
  3990.     x0 = x
  3991.     ti = suri + x0 - 1
  3992.     IF ti > q1 THEN ti = ti - q1
  3993.     y0 = gh(ti)
  3994.  
  3995.     FOR i = 0 TO 26
  3996.         tx = x0 + i
  3997.         LINE (tx, y0 - 21)-(tx, y0 - 5), sc, , SSp&(0, i)
  3998.         LINE (tx, y0 - 16)-(tx, y0 - 0), sc, , SSp&(1, i)
  3999.     NEXT i
  4000.  
  4001.     '                                                                 modify ground to include Surveyor
  4002.     IF (x0 >= gs) AND (x0 < 604) AND (sspinit2 = 0) THEN
  4003.         FOR tx = x0 TO x0 + 32
  4004.             FOR ty = y0 - 20 TO glmax
  4005.                 IF POINT(tx, ty) = sc THEN
  4006.                     z = (suri + tx) MOD q1
  4007.                     gh(z) = ty
  4008.                     EXIT FOR
  4009.                 END IF
  4010.             NEXT ty
  4011.         NEXT tx
  4012.         sspinit2 = 1
  4013.     END IF
  4014.  
  4015.     FOR tx = x0 TO x0 + 26 '                                          optional shadow
  4016.         FOR ty = y0 - 21 TO y0
  4017.             p = POINT(tx, ty)
  4018.             IF p = sc THEN
  4019.                 zx = tx - (x0 + 13)
  4020.                 zy = ty - (y0 - t)
  4021.                 IF zy > (zx + 4) THEN PSET (tx, ty), gray
  4022.             END IF
  4023.         NEXT ty
  4024.     NEXT tx
  4025.  
  4026.     attack = 0
  4027.     sdd = q1
  4028.     FOR i = 180 TO 355 STEP 5 '                                       rays
  4029.         ra = i + RND * 5
  4030.         z = 25 + RND * t
  4031.         FOR j = 0 TO 1
  4032.             x(j) = (x + t) + z * c!(ra) * aspect!
  4033.             y(j) = y0 + z * s!(ra) - 1
  4034.             z = z + RND * 30 + t
  4035.         NEXT j
  4036.         xs! = (x(1) - x(0)) / 20
  4037.         ys! = (y(1) - y(0)) / 20
  4038.         FOR j = 0 TO 19
  4039.             tx = x(0) + j * xs!
  4040.             ty = y(0) + j * ys!
  4041.             x! = px! - tx
  4042.             y! = (py! - ty) * aspect!
  4043.             dd = SQR(x! * x! + y! * y!)
  4044.             IF dd < sdd THEN sdd = dd
  4045.             IF (shield = 0) OR (dd > 70) OR (j = 0) THEN PSET (tx, ty), gunmetal
  4046.             IF shield AND ((dd = 70) OR ((j = 0) AND (dd < 70))) THEN
  4047.                 LINE (sx0 + xoff, sy0 + vy!)-(tx, ty), lmsl
  4048.                 IF RND < .7 THEN
  4049.                     PSET STEP(0, 0), red
  4050.                 ELSE
  4051.                     LINE (tx - 1, ty)-(tx + 1, ty), red
  4052.                     LINE (tx, ty - 1)-(tx, ty + 1), red
  4053.                 END IF
  4054.                 EXIT FOR
  4055.             END IF
  4056.         NEXT j
  4057.         IF sdd < 20 THEN attack = 1
  4058.     NEXT i
  4059.     IF attack AND (crash = 0) AND (shield = 0) THEN
  4060.         oldr = rads
  4061.         rads = rads + RND * t + 1
  4062.         IF rads > 9999 THEN rads = 9999
  4063.         IF rads > oldr THEN
  4064.             rtl!(0) = TIMER + 5
  4065.             rtlc(0) = rads
  4066.             panelinit = 0
  4067.         END IF
  4068.     END IF
  4069. ' -------------------------------------------------------------------------------------------------------x
  4070. SUB Tile STATIC
  4071.     IF tinit = 0 THEN
  4072.         s = 7
  4073.         DIM t(1, s, s)
  4074.         FOR i = 0 TO 1
  4075.             FOR j = 0 TO 1
  4076.                 FOR k = 0 TO 90 STEP t
  4077.                     ta = k + j * 180
  4078.                     tx = j * s + (s \ 2) * c!(ta)
  4079.                     ty = j * s + (s \ 2) * s!(ta)
  4080.                     IF i THEN ty = s - ty
  4081.                     t(i, tx, ty) = 1
  4082.                 NEXT k
  4083.             NEXT j
  4084.         NEXT i
  4085.         tinit = 1
  4086.     END IF
  4087.  
  4088.     IF gstyle = 4 THEN tc = gray ELSE tc = black2
  4089.     FOR xo = gs TO q3 STEP s
  4090.         FOR yo = glmax TO (glmin - 50) STEP -s
  4091.             SELECT CASE tilef
  4092.                 CASE IS = 0
  4093.                     bp = gety(xo) + yo
  4094.                     z1 = bp MOD 128
  4095.                     z2 = (bp MOD 12) + 1
  4096.                     td = p(z1, z2)
  4097.                     kk = SGN(td AND _SHL(1, (bp MOD 8)))
  4098.                 CASE IS = 1
  4099.                     bp = SQR(xo * yo)
  4100.                     z1 = bp MOD 128
  4101.                     z2 = (bp MOD 12) + 1
  4102.                     td = p(z1, z2)
  4103.                     kk = SGN(td AND _SHL(1, (bp MOD 8)))
  4104.                 CASE IS = 2
  4105.                     kk = RND '
  4106.             END SELECT
  4107.             FOR i = 0 TO s
  4108.                 tx = xo + i
  4109.                 yy = gety(tx) + 1
  4110.                 FOR j = 0 TO s
  4111.                     ty = yo - j
  4112.                     IF ty <= yy THEN EXIT FOR
  4113.                     IF t(kk, i, j) THEN
  4114.                         zz = tx + suri
  4115.                         c1 = (sf(5, 2) = -1) OR (zz < sf(5, 0)) OR (zz > sf(5, 1)) '     McD
  4116.                         c2 = (sf(7, 2) = -1) OR (zz < sf(7, 0)) OR (zz > sf(7, 1)) '     Surv
  4117.                         IF c1 AND c2 THEN PSET (tx, ty), tc
  4118.                     END IF
  4119.                 NEXT j
  4120.             NEXT i
  4121.         NEXT yo
  4122.     NEXT xo
  4123. ' -------------------------------------------------------------------------------------------------------x
  4124.     DIM tmaa!(10), tmab!(10), tmac(10)
  4125.     IF ok AND (INSTR(fb$, "on TMA") > 0) THEN '                       landed, do Mandelbrot instead of moire
  4126.         Mandel
  4127.         GOTO tmaother
  4128.     END IF
  4129.     IF zdc = 0 THEN '                                                 then initialize
  4130.         nc = RND * 2 + 1 '                                            use 2-3 colors
  4131.         lc = -1 '                                                     last color, prevent repeats
  4132.         FOR z = 0 TO nc
  4133.             tmaa!(z) = RND + 4
  4134.             tmab!(z) = (RND - pf!) / 8
  4135.             DO
  4136.                 c = RND * 14 + 1
  4137.                 IF c = gray2 THEN c = gray '                          stars use gray2
  4138.                 IF c = white2 THEN c = white '                        stars use white2
  4139.                 IF c <> lc THEN lc = c: EXIT DO
  4140.             LOOP
  4141.             tmac(z) = c
  4142.         NEXT z
  4143.     END IF
  4144.  
  4145.     zdc = (zdc + 1) MOD 50
  4146.     FOR z = 0 TO 2
  4147.         tmaa!(z) = tmaa!(z) + tmab!(z)
  4148.     NEXT z
  4149.     y0 = glmax - 72
  4150.     y1 = y0 + 1
  4151.     y2 = glmax - 1
  4152.     LINE (x, glmax)-(x + 46, glmax), gray
  4153.  
  4154.     FOR gx = x TO x + 45
  4155.         x2! = gx / tmaa!(0)
  4156.         x2! = x2! * x2!
  4157.         FOR gy = y1 TO y2
  4158.             y2! = gy / tmaa!(0)
  4159.             y2! = y2! * y2!
  4160.             tcc = ABS((x2! + y2!) / tmaa!(1)) MOD (nc + 1)
  4161.             PSET (gx, gy), tmac(tcc)
  4162.         NEXT gy
  4163.     NEXT gx
  4164.  
  4165.     IF TIMER < cybilltime! THEN CybillPix f$(16) ELSE gotpix = 0
  4166.  
  4167.     tmaother:
  4168.     IF bolthitf THEN LINE (x, y0)-(x + 45, glmax), white, BF
  4169.  
  4170.     FOR s = 0 TO 20 '                                                 shells
  4171.         IF (shx(s) > 0) AND (shd(s) < 80) THEN
  4172.             tarx = shx(s) - suri
  4173.             tary = shy(s)
  4174.             IF (s > 0) OR (shy(s) > 200) THEN
  4175.                 GOSUB tmafl
  4176.                 ExplodeShell s '                                      show it exploded
  4177.             END IF
  4178.         END IF
  4179.     NEXT s
  4180.  
  4181.     FOR i = 2 TO 6 '                                                  not DS!
  4182.         IF (ek(i) > 0) AND (ek(i) < 30) THEN
  4183.             tarx = exl(i) '                                           where to shoot
  4184.             tary = ey(i)
  4185.             GOSUB tmafl '                                             fire laser
  4186.             ek(i) = 0
  4187.             ex(i) = 0 '                                               mark destroyed
  4188.             exv(i) = 0
  4189.         END IF
  4190.     NEXT i
  4191.     EXIT SUB
  4192.  
  4193.     tmafl: '                                                          fire laser
  4194.     FOR gx = x TO x + 45 STEP 2 '                                     along top of TMA1
  4195.         LINE (gx, y1 - 1)-(tarx, tary), blue '                        nice blue
  4196.     NEXT gx
  4197.     IF gotpix = 0 THEN '                                              not showing Cybill
  4198.         cybilltime! = TIMER + 2 '                                     keep on screen for 2 sec
  4199.         gotpix = 1 '                                                  flag onscreen
  4200.     END IF
  4201.     RETURN
  4202. ' -------------------------------------------------------------------------------------------------------x
  4203. SUB Wave STATIC '                                                     funny effect for warp speeds
  4204.     tdg = (tdg MOD 4) + 1
  4205.     FOR i = 1 TO 22
  4206.         '               1234567890123456789012
  4207.         '               TTTTHHHHHVVVVVAAAAFFFF
  4208.         osc = VAL(MID$("1111222223333344445555", i, 1))
  4209.         wll = VAL(MID$("45555", osc, 1))
  4210.         adg = (tdg + wll) MOD 4 + 1 - (wll = 4)
  4211.         z$ = MID$("agdgagdg", adg, wll)
  4212.         LEDdisplay z$
  4213.     NEXT i
  4214. ' -------------------------------------------------------------------------------------------------------x
  4215. SUB WormHole STATIC
  4216.     IF eou THEN EXIT SUB '                                            end of universe
  4217.  
  4218.     IF ei(4) = 0 THEN
  4219.         nc:
  4220.         c1 = RND * 14 + 1
  4221.         c2 = RND * 14 + 1
  4222.         IF c1 = c2 THEN GOTO nc
  4223.         IF (c1 = black2) OR (c1 = gray) THEN GOTO nc
  4224.         IF (c2 = black2) OR (c2 = gray) THEN GOTO nc
  4225.         ei(4) = 1
  4226.     END IF
  4227.  
  4228.     tx = localize(ex(4), 0, 0)
  4229.     wy = ey(4)
  4230.     ba = (ba + 30) MOD tsix
  4231.     FOR ta = 0 TO 720 STEP 2
  4232.         FOR d = 0 TO 3
  4233.             baa = (ta + ba + d * 90) MOD tsix
  4234.             tx1 = tx + ta / 8 * c!(baa)
  4235.             ty1 = wy + ta / 40 * s!(baa)
  4236.             IF d MOD 2 THEN c = c1 ELSE c = c2
  4237.             PSET (tx1, ty1), c
  4238.         NEXT d
  4239.     NEXT ta
  4240. ' -------------------------------------------------------------------------------------------------------x
  4241. SUB LGM (fc) STATIC '                                                 little green man
  4242.  
  4243.     x = x - 5
  4244.     IF LGMc = gray THEN '                                             LGM toasted - show pile of ashes
  4245.         y1 = gety(x + t) - 1
  4246.         FOR y = 0 TO 5
  4247.             LINE (x + y, y1 - y)-(x + 15 - y, y1 - y), gray
  4248.             p = VAL(MID$("162341", y + 1, 1))
  4249.             PSET (x + y + p, y1 - y), black2
  4250.             PSET (x + y + p + 3, y1 - y), black2
  4251.         NEXT y
  4252.         EXIT SUB
  4253.     END IF
  4254.  
  4255.     IF sema$ = "" THEN '                                              initialize
  4256.         DIM a(28, 1) '                                                angles
  4257.         RESTORE semadata
  4258.         FOR i = 1 TO 28 '                                             read angles
  4259.             READ z$, a(i, 0), a(i, 1)
  4260.         NEXT i
  4261.         DO
  4262.             READ z$
  4263.             IF z$ = "end" THEN EXIT DO
  4264.             sema$ = sema$ + " " + z$ + " "
  4265.         LOOP
  4266.         lc$ = CHR$(255): i = 0 '                                      lc = last character, i = index
  4267.     END IF
  4268.  
  4269.     IF crash THEN LGMc = dred '                                       white2 as many other colors g1
  4270.     IF TIMER < sema! THEN sema! = TIMER '                             midnite crossing fix
  4271.     IF (TIMER - sema!) > semat! THEN '                                signal next letter
  4272.         sema! = TIMER
  4273.         IF fc = 0 THEN '                                              flame count
  4274.             semat! = .3
  4275.             tsema$ = sema$
  4276.             IF si > 0 THEN i = si - 1: si = 0
  4277.         ELSE
  4278.             semat! = .2 '                                             0.2 seconds between letters
  4279.             IF fc < 5 THEN '                                          flame count
  4280.                 IF tsema$ <> "help  " THEN tsema$ = "!"
  4281.                 toast = 0
  4282.             ELSE
  4283.                 tsema$ = "help  "
  4284.                 toast = toast + 1
  4285.                 IF toast > 2 THEN toast = 0: LGMc = LGMc + 1
  4286.             END IF
  4287.         END IF
  4288.         i = (i MOD LEN(tsema$)) + 1
  4289.         p = INSTR(tsema$, "time is")
  4290.         IF p THEN
  4291.             z$ = MID$(TIME$, 1, 2) + MID$(TIME$, 4, 2)
  4292.             MID$(tsema$, p + 8, 4) = z$
  4293.         END IF
  4294.         y1 = gety(x) - 14
  4295.         IF demo THEN y1 = 286
  4296.         c$ = MID$(tsema$, i, 1)
  4297.         d = ASC(LCASE$(c$)) - 96
  4298.         IF d < 1 THEN d = 27
  4299.         IF c$ = "!" THEN d = 28
  4300.         p = INSTR("1234567890", c$): IF p THEN d = p - (c$ = "0")
  4301.         IF oscar THEN
  4302.             c1 = red
  4303.             c2 = gold
  4304.         ELSE
  4305.             c1 = blue
  4306.             c2 = white
  4307.         END IF
  4308.         IF (c$ <> " ") AND (c$ = lc$) THEN SWAP c1, c2
  4309.         lc$ = c$
  4310.     END IF
  4311.  
  4312.     c = VAL(MID$("021412040906110015", (LGMc - 1) * 2 + 1, 2))
  4313.     IF bolthitf THEN c = white
  4314.     IF c = black2 THEN co = gray2 ELSE co = black2
  4315.     CIRCLE (x + t, y1 - 6), 4, c '                                    head
  4316.     PAINT (x + t, y1 - 6), c, c '                                     fill in head
  4317.     PSET (x + 8, y1 - 7), co '                                        left eye
  4318.     PSET (x + 12, y1 - 7), co '                                       right eye
  4319.     LINE (x + 9, y1 - 5)-(x + 11, y1 - 5), co '                       mouth
  4320.     LINE (x + 5, y1)-(x + 15, y1 + 12), c, BF '                       body
  4321.     IF c = black2 THEN
  4322.         CIRCLE (x + t, y1 - 6), 5, co '                               eye
  4323.         LINE (x + 5, y1)-(x + 15, y1 + 12), co, B '                   body
  4324.     END IF
  4325.  
  4326.     IF (d = 27) AND (c <> black2) AND (fc = 0) THEN '                 wiggle ears
  4327.         x2 = x + 5 - bbit
  4328.         x3 = x + 14 + bbit
  4329.         y2 = y1 - 8 + bbit
  4330.         LINE (x2, y2)-(x2 + 1, y2 + 1), c, BF
  4331.         LINE (x3, y2)-(x3 + 1, y2 + 1), c, BF
  4332.     END IF
  4333.  
  4334.     IF fc THEN '                                                      optional flame effect
  4335.         IF fc > t THEN di = 4 ELSE di = t '                           flame count
  4336.         FOR tx = x + 5 TO x + 15
  4337.             FOR ty = y1 - 9 TO y1 + 12
  4338.                 p = POINT(tx, ty)
  4339.                 z = (z + 1) MOD q1
  4340.                 IF p = c THEN
  4341.                     tc = (ty + tx + z) MOD di
  4342.                     IF tc = 0 THEN PSET (tx, ty), gold
  4343.                     IF tc = 1 THEN PSET (tx, ty), black2
  4344.                 END IF
  4345.             NEXT ty
  4346.         NEXT tx
  4347.     END IF
  4348.  
  4349.     IF c = black2 THEN c = gray2
  4350.     FOR j = 0 TO 1 '                                                  arms & flags
  4351.         a1 = a(d, j) - 90
  4352.         x2 = x + j * 20
  4353.         x3 = x2 + 26 * COS(_D2R(a1))
  4354.         y2 = y1 + 25 * SIN(_D2R(a1))
  4355.         LINE (x2, y1)-(x3, y2), c '                                   arm
  4356.         IF j = 0 THEN s = 1: IF INSTR("wxz", c$) THEN s = -s
  4357.         IF j = 1 THEN s = -1: IF INSTR("hio89", c$) THEN s = -s
  4358.         FOR q = 0 TO 3
  4359.             a1 = a1 - 90 * s
  4360.             x4 = x3 + t * COS(_D2R(a1))
  4361.             y4 = y2 + t * SIN(_D2R(a1))
  4362.             LINE -(x4, y4), gunmetal
  4363.             IF q = 1 THEN
  4364.                 sx = x4: sy = y4
  4365.                 r! = _D2R(a1 - 45 * s)
  4366.                 rx = x3 + 5 * COS(r!)
  4367.                 ry = y2 + 5 * SIN(r!)
  4368.             END IF
  4369.             IF q = 3 THEN
  4370.                 r! = _D2R(a1 - 45 * s)
  4371.                 yx = x3 + 5 * COS(r!)
  4372.                 yy = y2 + 5 * SIN(r!)
  4373.             END IF
  4374.             x3 = x4: y2 = y4
  4375.         NEXT q
  4376.         LINE -(sx, sy), gunmetal
  4377.         PAINT (rx, ry), c1, gunmetal
  4378.         PAINT (yx, yy), c2, gunmetal
  4379.     NEXT j
  4380.  
  4381.     IF c$ = UCASE$(c$) THEN
  4382.         x2 = x + 5 + SGN(INSTR("ACDHJMNOPSUV0123456789", c$)) '       letter centering
  4383.         y2 = y1 + 2
  4384.     ELSE
  4385.         x2 = x + 6 - SGN(INSTR("ijlnv", c$)) '                        as above
  4386.         y2 = y1 - SGN(INSTR("gjpqy", c$)) + 2
  4387.     END IF
  4388.  
  4389.     IF LGMc = 4 THEN tc = gold ELSE tc = red
  4390.     CALL PrintVGA(c$, x2, y2, tc, black2)
  4391. ' -------------------------------------------------------------------------------------------------------x
  4392. SUB Stars STATIC
  4393.  
  4394.     ' - starstatus  0 off, 1 on, 2+names, 3+RA & Dec & grid, 4+Mag
  4395.     ' - encodes magnitude into xy array by making negative
  4396.     ' - stars1 1797, stars2 16571, stars3 87470
  4397.  
  4398.     IF sinit = 0 THEN
  4399.         sinit = 1
  4400.         qq = 18000
  4401.         DIM starx(qq), stary(qq), starn(30), star$(2, 50)
  4402.         starmax = qq: namemax = 100
  4403.         gc = blue '                                                   grid color
  4404.         sc = gray2 '                                                  star info color
  4405.     END IF
  4406.     nh = 12 / (zoom + 1) '                                            hours (RA)
  4407.     nd = 90 / (zoom + 1) '                                            degrees (Dec)
  4408.  
  4409.     IF eou <> 0 THEN '                                                End of Universe
  4410.         alldown = 1
  4411.         FOR star = 1 TO nstars
  4412.             sy = stary(star)
  4413.             ay = ABS(sy)
  4414.             IF ay < q4 THEN '                                         less than screen bottom
  4415.                 stary(star) = stary(star) + SGN(stary(star))
  4416.                 alldown = 0 '                                         not done
  4417.             END IF
  4418.         NEXT star
  4419.         IF alldown THEN CLS: EXIT SUB
  4420.     END IF
  4421.  
  4422.     IF regen = 0 THEN CLS
  4423.     tss = starstatus
  4424.     IF starinit = 0 THEN
  4425.         starinit = 1
  4426.         eou = 0 '                                                     End of Universe
  4427.         alldown = 0
  4428.         nstars = 0
  4429.         named = 0
  4430.         rmax! = rmin + nh '                                           hours
  4431.         dmax! = dmin + nd '                                           degrees
  4432.         n1& = 0
  4433.         isred1 = 0: isred2 = 0
  4434.         rmin$ = RIGHT$("00" + LTRIM$(STR$(rmin)), 2) '                0 - 24
  4435.         dmin$ = RIGHT$("000" + LTRIM$(STR$(dmin)), 3) '               -90 to 90
  4436.         zz$ = LTRIM$(STR$(starfiles)) + rmin$ + dmin$ + ".dat"
  4437.         IF (warp! >= 1) AND (starfiles = 2) THEN tfs = 1 ELSE tfs = starfiles
  4438.         SELECT CASE tfs
  4439.             CASE IS = 0
  4440.                 th! = 5.07 + zoom: tf$ = "stars1.dat": d$ = ".\dat1\": nl& = 1797
  4441.             CASE IS = 1
  4442.                 th! = 7.07 + zoom: tf$ = "stars2.dat": d$ = ".\dat2\": nl& = 16571
  4443.             CASE IS = 2
  4444.                 th! = 8.07 + zoom: tf$ = "stars3.dat": d$ = ".\dat3\": nl& = 87470
  4445.         END SELECT
  4446.         IF okrick = 0 THEN d$ = "" '                                 ugh, all star files in same directory
  4447.         tf1$ = d$ + "si" + zz$: f1$ = tf1$: f1$ = FileCheck$(f1$)
  4448.         tf2$ = d$ + "sx" + zz$: f2$ = tf2$: f1$ = FileCheck$(f2$)
  4449.         tf3$ = d$ + "sy" + zz$: f3$ = tf3$: f1$ = FileCheck$(f3$)
  4450.         isstari = (f1$ <> "") AND (f2$ <> "") AND (f3$ <> "")
  4451.         IF regen THEN isstari = 0
  4452.         IF isstari THEN
  4453.             GOSUB readstar
  4454.             GOTO plot
  4455.         END IF
  4456.         regen = 0
  4457.         FOR i = 0 TO qq
  4458.             starx(i) = 0
  4459.             stary(i) = 0
  4460.         NEXT i
  4461.         tf = FREEFILE
  4462.         OPEN tf$ FOR INPUT AS #tf
  4463.         DO
  4464.             INPUT #tf, r!, d!, m!, dis$, n$
  4465.             n1& = n1& + 1
  4466.             IF (starfiles > -1) AND ((n1& MOD h) = 1) THEN
  4467.                 zz1 = h + t '                                         hundred + 10 = 110
  4468.                 zz2 = zz1 + n1& / nl& * 500
  4469.                 LINE (gs, 0)-(639, 40), black, BF
  4470.                 LINE (zz1, t)-(zz1 + 500, 13), red, B
  4471.                 LINE (zz1, t)-(zz2, 13), red, BF
  4472.                 PrintCGA "Loading stars...", 300, 14, red, black, 0
  4473.                 PrintCGA tf1$, 110, 14, red, black, 0
  4474.                 IF mstar > 0 THEN '                                   regenerating all starfiles, show progress
  4475.                     zz2 = zz1 + mstar / 1368 * 500
  4476.                     LINE (zz1, 27)-(zz1 + 500, 30), red, B
  4477.                     LINE (zz1, 27)-(zz2, 30), red, BF
  4478.                 END IF
  4479.                 timemachine
  4480.             END IF
  4481.  
  4482.             sa = (LEFT$(n$, 1) = "*") '                               show always (low mag)
  4483.             tt! = th! '                                               temp threshold
  4484.             IF ABS(d!) > 70 THEN tt! = tt! + 2
  4485.             IF ABS(d!) > 80 THEN tt! = tt! + 2
  4486.             abd = ABS(d!): tt! = tt! - (abd > 70) - (abd > 80)
  4487.             IF sa OR (m! <= tt!) THEN '                               show always or bright
  4488.                 FOR z1 = 0 TO 1 '                                     why why why?
  4489.                     FOR z2 = 0 TO 1
  4490.                         tr! = r! + z1 * 24
  4491.                         td! = d! + z2 * 180
  4492.                         IF (tr! > rmin) AND (tr! < rmax!) AND (td! > dmin) AND (td! < dmax!) THEN sr = z1: sd = z2
  4493.                     NEXT z2
  4494.                 NEXT z1
  4495.                 tx = q3 - (r! - rmin + sr * 24) / nh * q3
  4496.                 ty = q4 - (d! - dmin + sd * 180) / nd * q4
  4497.                 IF (tx > 0) AND (tx < q3) AND (ty > 0) AND (ty < q4) THEN
  4498.                     IF m! <= 3 THEN tx = -tx
  4499.                     IF m! <= 2 THEN ty = -ty
  4500.                     nstars = nstars + 1
  4501.                     starx(nstars) = tx
  4502.                     stary(nstars) = ty
  4503.                     IF sa THEN n$ = RIGHT$(n$, LEN(n$) - 1) '         show always, remove asterisk
  4504.                     IF LEN(n$) AND (sa OR (m! < 2)) AND (named < namemax) THEN
  4505.                         named = named + 1
  4506.                         starn(named) = nstars
  4507.                         star$(0, named) = n$
  4508.                         IF n$ = "Antares" THEN isred1 = nstars
  4509.                         IF n$ = "Mira" THEN isred2 = nstars
  4510.                         star$(1, named) = LTRIM$(STR$(m!)) + " " + dis$ ' + "P " + y$ + "L"
  4511.                         star$(2, named) = LTRIM$(STR$(r!)) + " " + LTRIM$(STR$(d!))
  4512.                     END IF
  4513.                 END IF
  4514.             END IF
  4515.         LOOP UNTIL EOF(tf) OR (nstars = starmax)
  4516.         CLOSE #tf
  4517.     END IF
  4518.  
  4519.     IF isstari = 0 THEN GOSUB writestar
  4520.     plot:
  4521.     CLS
  4522.     tss = starstatus
  4523.     IF auto AND (gstyle = 0) THEN tss = 4
  4524.  
  4525.     IF tss > 2 THEN '                                                 optional grids
  4526.         FOR i = 0 TO nh '                                             vertical lines
  4527.             tx = (i / nh * q3) MOD (q3 + 1)
  4528.             LINE (tx, 0)-(tx, q4), gc, , &H1111
  4529.             z = rmax! - i: z = z + (z > 23) * 24 '                    optional labeling
  4530.             TinyFont STR$(z), tx - 2, 0, -gc
  4531.         NEXT i
  4532.         z! = nd / t
  4533.         FOR de! = 0 TO z! '                                           horizontal lines
  4534.             ty = q4 - ((de! / z! * q4) MOD (q4 + 1))
  4535.             LINE (gs, ty)-(q3, ty), gc, , &H1111
  4536.             z = dmin + de! * t '                                      optional lableling
  4537.             z = z + ((z > 90) - (z < -90)) * 180
  4538.             z$ = STR$(z)
  4539.             TinyFont z$, q3 - LEN(z$) * 4 - 2, ty + 2, -gc
  4540.         NEXT de!
  4541.     END IF
  4542.  
  4543.     FOR star = 1 TO nstars
  4544.         stx = starx(star): ax = ABS(stx)
  4545.         sty = stary(star): ay = ABS(sty)
  4546.         IF warp! THEN
  4547.             tx = ax + SGN(-vx!) * warp! * 2
  4548.             IF ay < glmax THEN LINE (ax, ay)-(tx, ay), gray2
  4549.             IF tx < 1 THEN tx = tx + (q3 + 1)
  4550.             IF tx > q3 THEN tx = tx - (q3 + 1)
  4551.             starx(star) = tx * SGN(stx + .01)
  4552.         ELSE
  4553.             m = 3 + (stx < 0) + (sty < 0) '                           magnitude
  4554.             IF m < 3 THEN tc = white2 ELSE tc = gray2 '               slightly different brightness
  4555.             IF twinkle AND (RND > .9) AND (tc = white2) THEN tc = gray2
  4556.             IF star = isred1 THEN tc = red '                          Mira and Antares
  4557.             IF star = isred2 THEN tc = red
  4558.             IF m = 1 THEN '                                           small cross if < 2
  4559.                 LINE (ax - 1, ay)-(ax + 1, ay), tc
  4560.                 LINE (ax, ay - 1)-(ax, ay + 1), tc
  4561.             ELSE '                                                    bright or dim point
  4562.                 PSET (ax, ay), tc
  4563.             END IF
  4564.             ' IF (star MOD 37) = 0 THEN TinyFont STR$(star), ax, ay, sc ' diagnostic
  4565.             FOR i = 1 TO named '                                      show names & info
  4566.                 IF star = starn(i) THEN
  4567.                     FOR j = 0 TO tss - 2
  4568.                         IF j THEN
  4569.                             ty = ay + j * 9 + (j = 2) * 3 + 1
  4570.                             TinyFont star$(j, i), ax, ty, sc
  4571.                         ELSE
  4572.                             PrintCGA star$(j, i), ax, ay + j * 9, sc, -1, 1
  4573.                         END IF
  4574.                     NEXT j
  4575.                 END IF
  4576.             NEXT i
  4577.         END IF
  4578.     NEXT star
  4579.     IF rick THEN '                                                    show counts
  4580.         z$ = LTRIM$(STR$(starfiles)) + STR$(nstars) + STR$(starmax) + STR$(named) + STR$(th!)
  4581.         TinyFont z$, 86, 20, red
  4582.     END IF
  4583.     EXIT SUB
  4584.  
  4585.     readstar:
  4586.     tf = FREEFILE
  4587.     OPEN tf1$ FOR INPUT AS #tf
  4588.     INPUT #tf, nstars, named, isred1, isred2
  4589.     n1 = nstars
  4590.     FOR i = 1 TO named
  4591.         INPUT #tf, starn(i)
  4592.         FOR j = 0 TO 2
  4593.             INPUT #tf, star$(j, i)
  4594.         NEXT j
  4595.     NEXT i
  4596.     CLOSE #tf
  4597.     OPEN tf2$ FOR BINARY AS #tf
  4598.     GET #tf, , starx()
  4599.     CLOSE #tf
  4600.     OPEN tf3$ FOR BINARY AS #tf
  4601.     GET #tf, , stary()
  4602.     CLOSE #tf
  4603.     RETURN
  4604.     ' -----------------------------------------------------------------------------------
  4605.     writestar:
  4606.     tf = FREEFILE
  4607.     OPEN tf1$ FOR OUTPUT AS #tf
  4608.     PRINT #tf, nstars; ","; named; ","; isred1; ","; isred2
  4609.     FOR i = 1 TO named
  4610.         PRINT #tf, starn(i);
  4611.         FOR j = 0 TO 2
  4612.             PRINT #tf, ","; star$(j, i);
  4613.         NEXT j
  4614.         PRINT #tf, CHR$(13);
  4615.     NEXT i
  4616.     CLOSE #tf
  4617.  
  4618.     OPEN tf2$ FOR BINARY AS #tf
  4619.     PUT #tf, , starx()
  4620.     CLOSE #tf
  4621.  
  4622.     OPEN tf3$ FOR BINARY AS #tf
  4623.     PUT #tf, , stary()
  4624.     CLOSE #tf
  4625.     RETURN
  4626. ' -------------------------------------------------------------------------------------------------------x
  4627. SUB Borg (lbx, bmy) STATIC
  4628.     IF borginit = 0 THEN
  4629.         z$ = SPACE$(t) + "WE ARE THE BORG - RESISTANCE IS FUTILE" + SPACE$(50)
  4630.         moire = 0: moired = 1: xn = 19: yn = 8: zz = 13: p0 = &HAAAA
  4631.         DIM mat$(yn)
  4632.         FOR i = 1 TO yn
  4633.             mat$(i) = STRING$(xn, ASC("0"))
  4634.         NEXT i
  4635.         borginit = 1 '                                                      direction for guts
  4636.     END IF
  4637.     p1 = &H5555: p2 = &HAAAA
  4638.  
  4639.     borgt = bmy - 40 '                                                top
  4640.     borgl = lbx - 40 '                                                left side
  4641.     borgr = lbx + 52 '                                                right side
  4642.  
  4643.     x1 = lbx - 46: y1 = bmy - 34: x2 = lbx + 46: y2 = bmy + 34
  4644.  
  4645.     FOR i = 0 TO zz
  4646.         tx1 = x1 + i: tx2 = x2 + i: ty1 = y1 - i: ty2 = y2 - i
  4647.         IF (tx1 + 2) < gs THEN SWAP p1, p2
  4648.         LINE (tx1, ty1)-(tx1, ty2), black2 '                          left
  4649.         LINE (tx1, ty1)-(tx1, ty2), dred, , p0
  4650.         LINE (tx1 + 2, ty2)-(tx2, ty2), black2 '                      bottom
  4651.         LINE (tx1 + 2, ty2)-(tx2, ty2), dred, , p1
  4652.     NEXT i
  4653.     FOR i = 0 TO zz
  4654.         tx2 = x2 + i: ty1 = y1 - i + 2: ty2 = y2 - i
  4655.         LINE (tx2, ty1)-(tx2, ty2), red '                             right
  4656.         tx1 = x1 + i: tx2 = x2 + i: ty1 = y1 - i
  4657.         LINE (tx1, ty1)-(tx2, ty1), red '                             top
  4658.     NEXT i
  4659.     LINE (x2 + 1, y1)-(x2 + zz, y1 - zz + 1), black2 '                top right diag
  4660.     LINE (x1 + 1, y2)-(x1 + zz, y2 - zz + 1), black2 '                bottom left diag
  4661.  
  4662.     x1 = x1 + 8: y1 = y1 + 1: y2 = y2 - 8 '                           inside of craft
  4663.  
  4664.     LINE (x1 + 4, y1)-(x2 - 1, y2 - 4), black2, BF '                  blank interior
  4665.     SELECT CASE bstyle1
  4666.         CASE IS = 0 '                                                 ala Matrix
  4667.             '                                                         84 60
  4668.             FOR y = 0 TO yn - 1
  4669.                 mat$(y) = mat$(y + 1)
  4670.             NEXT y
  4671.             FOR x = 1 TO xn
  4672.                 MID$(mat$(yn), x, 1) = CHR$(48 + RND)
  4673.             NEXT x
  4674.             FOR y = 0 TO yn
  4675.                 ty = y1 + y * 6
  4676.                 TinyFont mat$(y), x1 + 5, ty + 1, blue
  4677.             NEXT y
  4678.         CASE IS = 1 '                                                 Moire
  4679.             moire = moire + moired
  4680.             IF ABS(moire) > t THEN moired = -moired
  4681.             FOR ty = y1 TO y2
  4682.                 FOR tx = x1 TO x2 - 1
  4683.                     z1! = tx / (moire + 40): z1! = z1! * z1!
  4684.                     z2! = ty / (moire + 40): z2! = z2! * z1!
  4685.                     IF ((z1! + z2!) MOD 4) THEN
  4686.                         IF ((z1! + z2!) MOD 2) THEN tc = blue ELSE tc = dred
  4687.                         PSET (tx, ty), tc
  4688.                     END IF
  4689.                 NEXT tx
  4690.             NEXT ty
  4691.         CASE IS = 2 '                                                 boxes
  4692.             x2 = x2 - 3: xs = x2 - x1: ys = y2 - y1
  4693.             FOR z = 1 TO h
  4694.                 bx1 = x1 + RND * xs + 2
  4695.                 by1 = y1 + RND * ys + 2
  4696.                 bx2 = bx1 + (RND - pf!) * xs / z * t + 2
  4697.                 by2 = by1 + (RND - pf!) * ys / z * t + 2
  4698.                 IF bx2 < x1 THEN bx2 = x1
  4699.                 IF bx2 > x2 THEN bx2 = x2
  4700.                 IF by2 < y1 THEN by2 = y1
  4701.                 IF by2 > y2 THEN by2 = y2
  4702.                 c = 1 + SGN(z MOD 2) * 12
  4703.                 IF RND > .95 THEN c = gunmetal
  4704.                 LINE (bx1, by1)-(bx2, by2), c, B
  4705.             NEXT z
  4706.     END SELECT
  4707.  
  4708.     FOR k = -30 TO 30 STEP 15 '                                   exhaust, 5 flames
  4709.         bit = bit XOR 1 '                                         alternate
  4710.         FOR i = 0 TO 20
  4711.             ba1 = (ba1 + i) MOD tsix
  4712.             zzz = ((20 - i) / 4) * SIN(_D2R(ba1))
  4713.             ty0 = y2 + i + 8 + bit + 1
  4714.             tx1 = lbx - zzz + k
  4715.             tx2 = lbx + zzz + k
  4716.             LINE (tx1, ty0)-(tx2, ty0), blue, , RND * &H7FFF
  4717.         NEXT i
  4718.     NEXT k
  4719.     '                                                                 scroll Borg message along top and right side of craft
  4720.     ti = (ti MOD (50 * 16)) + 8 '                                     index into text, speed 1-??
  4721.     tx1 = lbx - 46 - 3
  4722.     ty1 = bmy - 31
  4723.  
  4724.     PrintLines z$, ti, ti + 90, tx1, ty1 - 1, black2, -88, 2, 2 '     top
  4725.     PrintLines z$, ti, ti + 90, tx1, ty1 - 0, white2, -88, 2, 2
  4726.  
  4727.     tx1 = lbx + 46 - 2: ty1 = bmy - 32 '                              right
  4728.     PrintLines z$, ti + 91, ti + 91 + 67, tx1, ty1, black2, -99, 2, 2
  4729.  
  4730. ' -------------------------------------------------------------------------------------------------------x
  4731. SUB Volcano STATIC
  4732.  
  4733.     IF vinit = 0 THEN
  4734.         q = q3 * 2 '                                                  640*2=1280
  4735.         DIM vox!(q), voy!(q), vxi!(q), vyi!(q)
  4736.         vinit = 1
  4737.     END IF
  4738.  
  4739.     vx = sf(4, 2)
  4740.     IF ABS((TIMER MOD t) - (RND * t)) > 5 THEN
  4741.         FOR i = 0 TO q
  4742.             IF vyi!(i) < -3 THEN k! = .6 ELSE k! = .8 '               kill some
  4743.             IF (vox!(i) = 0) OR (RND > k!) THEN '                     dead or kill
  4744.                 vox!(i) = vx + RND * t - 5 '                          initial x
  4745.                 voy!(i) = gety(INT(vox!(i) - suri)) - 1 '             initial y
  4746.                 ta = RND * 40 + 70 '                                  angle
  4747.                 r! = _D2R(ta)
  4748.                 vxi!(i) = (RND * t + 1) * COS(r!) '                   x velocity
  4749.                 vyi!(i) = (RND * t + 2) * SIN(r!) '                   y velocity
  4750.             END IF
  4751.         NEXT i
  4752.     END IF
  4753.  
  4754.     FOR i = 0 TO q
  4755.         tx = vox!(i) - suri '                                         local x
  4756.         ty = voy!(i) '                                                local y
  4757.         IF shield THEN z = 0: GOSUB protect
  4758.         IF ty > q4 THEN '                                             off screen
  4759.             vox!(i) = 0 '                                             flag for init
  4760.         ELSE
  4761.             IF (tx >= gs) AND (tx <= q3) THEN
  4762.                 IF vyi!(i) < -(RND * 4) THEN
  4763.                     c = gunmetal
  4764.                     IF (ty > gety(tx)) AND (gstyle = 0) THEN c = black ' black on white
  4765.                 ELSE
  4766.                     c = orange
  4767.                 END IF
  4768.                 PSET (tx, ty), c
  4769.                 IF i MOD 2 THEN LINE -STEP(RND * 2 - 1, RND * 2 - 1), c
  4770.             END IF
  4771.         END IF
  4772.         vyi!(i) = vyi!(i) - .25 '                                     decelerate
  4773.         vox!(i) = vox!(i) - vxi!(i) '                                 new x
  4774.         voy!(i) = voy!(i) - vyi!(i) '                                 new y
  4775.     NEXT i
  4776.     EXIT SUB
  4777.  
  4778.     protect:
  4779.     dx! = px! - tx '                                                  distance x
  4780.     dy! = (py! - ty) * aspect! '                                      distance y
  4781.     dd = SQR(dx! * dx! + dy! * dy!) '                                 distance
  4782.     IF dd < 70 THEN '                                                 at shield
  4783.         z = 1
  4784.         vyi!(i) = 0
  4785.         ty = ty - SGN(dy!)
  4786.         GOTO protect
  4787.     END IF
  4788.     IF z THEN '                                                       laser
  4789.         vxi!(i) = SGN(dx!) * (5 + RND * 5)
  4790.         LINE (sx0 + xoff, sy0 + vy!)-(tx, ty), lmsl
  4791.     END IF
  4792.     RETURN
  4793. ' -------------------------------------------------------------------------------------------------------x
  4794. SUB Mandel '                                                          appears in TMA-1 when landed on
  4795.     xd! = .044
  4796.     yd! = .036
  4797.     zz! = TIMER * 4
  4798.     LINE (x, glmax - 1)-(x + 45, glmax - 71), black2, BF
  4799.     FOR xx = 0 TO 23
  4800.         FOR yy = 0 TO 70
  4801.             MandelX! = -2 + yy * yd!
  4802.             MandelY! = -1 + xx * xd!
  4803.             Real# = 0
  4804.             Imag# = 0
  4805.             Itera = 20
  4806.             DO
  4807.                 Itera = Itera - 1
  4808.                 hold# = Imag#
  4809.                 Imag# = (Real# * Imag#) * 2 + MandelY!
  4810.                 Real# = Real# * Real# - hold# * hold# + MandelX!
  4811.                 Size# = (Real# * Real# + Imag# * Imag#) - 4
  4812.             LOOP UNTIL (Itera = 0) OR (Size# > 0)
  4813.             IF Size# > 0 THEN
  4814.                 tc = (Itera + zz!) MOD 15 + 1
  4815.                 ty = glmax - 71 + yy
  4816.                 PSET (x + xx, ty), tc '                               left half
  4817.                 PSET (x + 45 - xx, ty), tc '                          right half
  4818.             END IF
  4819.         NEXT yy
  4820.     NEXT xx
  4821. ' -------------------------------------------------------------------------------------------------------x
  4822. SUB CarWash
  4823.     DIM cwpat&(7)
  4824.     cwpat&(0) = &HFFFF
  4825.     cwpat&(1) = &H1111
  4826.     cwpat&(2) = &H2222
  4827.     cwpat&(3) = &H4444
  4828.     cwpat&(4) = &H8888
  4829.     cwpat&(5) = cwpat&(3)
  4830.     cwpat&(6) = cwpat&(2)
  4831.     cwpat&(7) = cwpat&(1)
  4832.  
  4833.     x1 = x + 1
  4834.     x2 = x1 + 99
  4835.     y0 = 305
  4836.     IF bolthitf THEN tc = white ELSE tc = gunmetal
  4837.     LINE (x, y0 - 19)-(x2, y0 - 1), tc, BF '                          sign background
  4838.     PrintCGA "MONTEZUMA", x + 14, 286, orange, black2, 0
  4839.  
  4840.     IF bbit THEN
  4841.         c1 = green
  4842.         c2 = blue
  4843.         c3 = green
  4844.     ELSE
  4845.         c1 = black2
  4846.         c2 = -1
  4847.         c3 = gunmetal
  4848.     END IF
  4849.     PrintCGA "Car Wash", x + 17, 294, c1, c2, 0
  4850.     LINE (x, y0 - 19)-(x2, y0 - 1), c3, B
  4851.  
  4852.     IF bolthitf THEN tc = white ELSE tc = blue2
  4853.     LINE (x, y0)-(x2, q4), tc, BF '                                   spray zone
  4854.     LINE (x1, y0)-(x1, q4), white, , cwpat&(1) '                      left side &H1111
  4855.     LINE (x2, y0)-(x2, q4), white, , cwpat&(1) '                      right side
  4856.  
  4857.     IF cwsi = 0 THEN cwsi = 1 '                                       spray angle increment
  4858.     cwsd = cwsd + cwsi '                                              spray direction
  4859.     IF (cwsd = 0) OR (cwsd = t) THEN cwsi = -cwsi '                   hit limits, reverse
  4860.     FOR z = 1 TO 5
  4861.         x1 = x + z * t + 24
  4862.         FOR i = -4 TO 4 STEP 2
  4863.             td = cwsd - 5 + i
  4864.             IF z MOD 2 = 0 THEN
  4865.                 td = -td
  4866.                 up = 0 '                                              use pattern
  4867.             ELSE
  4868.                 iz = (iz + 1) MOD th
  4869.                 up = iz MOD 7 + 1
  4870.             END IF
  4871.             ra = (90 + td * 3) MOD tsix
  4872.             tx = 64 * c!(ra) * 1.1
  4873.             ty = y0 + 64 * s!(ra)
  4874.             LINE (x1, y0)-(x1 + tx, ty), gunmetal, , cwpat&(up) '     along top
  4875.             LINE (x + 0, y0)-(x1 + tx \ 2, ty), gunmetal, , cwpat&(up) ' tl
  4876.             LINE (x + h, y0)-(x1 + tx \ 2, ty), gunmetal, , cwpat&(up) ' tr
  4877.             tx = x1 + 20 * c!(ra) * 1.2
  4878.             ty = q4 - 20 * s!(ra) \ 2
  4879.             LINE (x1, q4)-(tx, ty), white '                           bottom
  4880.         NEXT i
  4881.         iz = iz + 1
  4882.     NEXT z
  4883. ' -------------------------------------------------------------------------------------------------------x
  4884. SUB DeathStar (dtx, tf$) STATIC
  4885.     IF dsinit = 0 THEN
  4886.         DIM tc(1)
  4887.         xc = 320: yc = 175: dty = 170
  4888.         IF INSTR(tf$, "rs") THEN
  4889.             xs = 100: ys = 73: bs = ys + 6: rs = 4020 '               small
  4890.         ELSE
  4891.             xs = 130: ys = 110: bs = ys - t: rs = 8000 '              large
  4892.         END IF
  4893.         wx1 = xc - xs: wx2 = xc + xs
  4894.         wy1 = yc - ys: wy2 = yc + ys
  4895.         CLOSE #8
  4896.         REDIM buff&(rs)
  4897.         OPEN tf$ FOR BINARY AS #8
  4898.         dsinit = 1
  4899.     END IF
  4900.  
  4901.     IF darkstarc = 0 THEN c1 = black2: c2 = blue: c3 = blue2
  4902.     IF darkstarc = 1 THEN c1 = gunmetal: c2 = red: c3 = dred
  4903.     tc(0) = c2: tc(1) = c3
  4904.  
  4905.     CIRCLE (dtx, dty + 6), xs, black2 '                               define area
  4906.     FOR z = -1 TO 1 STEP 2 '                                          circle may be barely on screen
  4907.         PAINT (dtx + z * (xs - 1), dty), c1, black2 '                 far left & far right
  4908.     NEXT z
  4909.  
  4910.     xx = dtx - xc
  4911.     yy = dty - yc
  4912.     zz = (zz + darkstars) MOD 49 '                                   0-48 images
  4913.     rn& = zz * rs * 4 + 1
  4914.     GET #8, rn&, buff&()
  4915.     n = -1
  4916.     FOR i = wx1 TO wx2
  4917.         tx = xx + i
  4918.         IF tx > q3 THEN GOTO bork
  4919.         FOR j = wy1 TO wy2 STEP 15
  4920.             FOR k = 0 TO 1
  4921.                 n = n + 1
  4922.                 IF (buff&(n) > 0) AND (tx >= gs) THEN
  4923.                     LINE (tx, j)-(tx, j + 15), tc(k), , buff&(n)
  4924.                     IF darkstart THEN LINE (tx, j + 1)-(tx, j + 16), tc(k), , buff&(n)
  4925.                 END IF
  4926.             NEXT k
  4927.         NEXT j
  4928.     NEXT i
  4929.     bork:
  4930.     GOSUB Title
  4931.  
  4932.     boltx = q1 '                                                      handy large value
  4933.  
  4934.     IF RND > .7 THEN '                                                lightning bolt
  4935.         a! = 90 + (RND * 20) - t '                                    starting angle
  4936.         r! = bs '                                                     starting radius
  4937.         bolty = q1 '                                                  handy large value
  4938.         FOR i = -h TO h '                                             -100 to 100
  4939.             tx = dtx + i
  4940.             ty = gety(tx)
  4941.             IF ty <= bolty THEN
  4942.                 IF (bolty = q1) OR (RND > .8) THEN boltx = tx
  4943.                 bolty = ty
  4944.             END IF
  4945.         NEXT i
  4946.         DO
  4947.             xx = dtx + r! * COS(_D2R(a!)) * aspect!
  4948.             yy = dty + r! * SIN(_D2R(a!))
  4949.             IF yy > q4 THEN EXIT DO '                                 q4 = 349
  4950.             a! = a! + RND * 2 - 1 + SGN(xx - boltx) * .05
  4951.             r! = r! + RND * 2.18 - 1
  4952.             IF r! < bs THEN r! = bs
  4953.             GOSUB dot
  4954.         LOOP
  4955.     END IF
  4956.  
  4957.     nc = RND * 3 '                                                    "internal" lightning
  4958.     FOR s = 0 TO nc
  4959.         DO
  4960.             a! = RND * tsix
  4961.         LOOP UNTIL ABS(a! - 90) > 20
  4962.         td = bs \ 2 + RND * bs \ 2
  4963.         IF RND > .8 THEN td = RND * bs
  4964.         r! = td
  4965.         qq = 6
  4966.         DO
  4967.             xx = dtx + r! * COS(_D2R(a!)) * aspect!
  4968.             yy = dty + r! * SIN(_D2R(a!))
  4969.             GOSUB dot
  4970.             a! = a! + RND * 2.15 - 1
  4971.             r! = r! - RND * 2.18 + qq
  4972.             qq = qq - 1 - (qq = 1)
  4973.         LOOP UNTIL r! < td
  4974.     NEXT s
  4975.     EXIT SUB
  4976.  
  4977.     dot:
  4978.     dx! = px! - xx
  4979.     dy! = py! - yy
  4980.     dd! = SQR(dx! * dx! + dy! * dy!)
  4981.     tcc = 1 - (RND > pf!) * 14
  4982.     IF (shield = 0) AND (dd! < 15) THEN bolthit = 1
  4983.     IF shield AND (dd! <= 70) THEN
  4984.         tcc = green
  4985.         IF RND > .95 THEN LINE (sx0 + xoff, sy0 + vy!)-(xx, yy), red
  4986.     END IF
  4987.     PSET (xx, yy), tcc
  4988.     RETURN
  4989.  
  4990.     Title:
  4991.     IF atu = 0 THEN atu = t: ati = 1
  4992.     atu = atu + ati
  4993.     IF (atu = t) OR (atu = 25) THEN ati = -ati
  4994.     t$ = "EPCOR"
  4995.     FOR i = 1 TO LEN(t$)
  4996.         z$ = MID$(t$, i, 1)
  4997.         aa = -90 + (i - 3) * atu
  4998.         tx = dtx + bs * COS(_D2R(aa)) * aspect! - 5
  4999.         ty = dty + bs * SIN(_D2R(aa))
  5000.         PrintVGA z$, tx, ty, c3, white
  5001.     NEXT i
  5002.     RETURN
  5003. ' -------------------------------------------------------------------------------------------------------x
  5004. SUB Parachute STATIC
  5005.     IF contact THEN
  5006.         cy! = cy! + 5
  5007.         IF cy! > 500 THEN cy! = 500: chs = 1: paraf = 0
  5008.         chs = chs - 1
  5009.     ELSE
  5010.         cy! = py! - h
  5011.         IF (py! > 120) AND (chs < 40) THEN chs = chs + 2
  5012.     END IF
  5013.     FOR ta = 0 TO tsix
  5014.         r! = _D2R(ta) / 2
  5015.         tx = px! + chs * COS(r!) * 2
  5016.         ty = cy! - chs * SIN(r!)
  5017.         PSET (tx, ty), gray2
  5018.         IF (ta / 20) MOD 2 THEN tc = red ELSE tc = white2
  5019.         LINE -(tx, cy!), tc
  5020.         IF (ta MOD 40) = 0 THEN LINE -(px! - ASO, cy! + 82 + ASO * t), gray2
  5021.     NEXT ta
  5022. ' -------------------------------------------------------------------------------------------------------x
  5023. SUB Comet (comx, comy)
  5024.     IF crash THEN tc = white ELSE tc = green
  5025.     FOR i = 0 TO 1
  5026.         CIRCLE (comx, comy), i + 1, tc, , , .78
  5027.         c$ = MID$("HalleBerry", i * 5 + 1, 5)
  5028.         tx = comx + t
  5029.         ty = comy + i * 8
  5030.         IF (tx > gs) AND (tx < 590) AND (ty > 0) AND (ty < 330) THEN PrintCGA c$, tx, ty, white2, gunmetal, 0
  5031.     NEXT i
  5032.     FOR ta = -t TO t STEP 5 '                                         tail, -10 to 10
  5033.         zz = 50 + RND * tw '                                          vary tail length
  5034.         r! = _D2R(140 + ta * 4)
  5035.         x1 = comx + 3 * COS(r!) '                                     tail start
  5036.         y1 = comy + 3 * SIN(r!)
  5037.         r! = _D2R(140 + ta \ 2)
  5038.         x2 = comx + zz * COS(r!) '                                    tail end
  5039.         y2 = comy + zz * SIN(r!)
  5040.         LINE (x1, y1)-(x2, y2), white2, , RND * &H7FFF
  5041.     NEXT ta
  5042. ' -------------------------------------------------------------------------------------------------------x
  5043. SUB CybillPix (pfile$) STATIC
  5044.     IF cpinit = 0 THEN
  5045.         z = 1225
  5046.         DIM cbuff(z)
  5047.         s& = VARSEG(cbuff(0))
  5048.         o& = VARPTR(cbuff(0))
  5049.         DEF SEG = s&
  5050.         BLOAD pfile$, o&
  5051.         cpinit = 1
  5052.     END IF
  5053.     IF ((x + 5) >= gs) AND (x < 600) THEN PUT (x + 5, 289), cbuff(), PSET
  5054. ' -------------------------------------------------------------------------------------------------------x
  5055. SUB Quit
  5056.     SCREEN 0, 0, 0, 0
  5057.     CLS
  5058.     CLOSE
  5059.     IF iscd THEN SYSTEM
  5060.  
  5061.     OPEN settings$ FOR OUTPUT AS #1
  5062.     z = auto: d$ = "auto": GOSUB pconfig '                            1 full autopilot
  5063.     z = background: d$ = "panel": GOSUB pconfig '                     2 instrument panel
  5064.     z = cbh: d$ = "cbh": GOSUB pconfig '                              3 constant black holes
  5065.     z = demo: d$ = "skyf": GOSUB pconfig '                            4 0 off 1 all features
  5066.     z = doclock: d$ = "clock": GOSUB pconfig '                        5 clock display on DS
  5067.     z = invincible: d$ = "invincible": GOSUB pconfig '                6 invincible
  5068.     z = jitter: d$ = "thrust": GOSUB pconfig '                        7 thrust calculation
  5069.     z = LEDc: d$ = "ledc": GOSUB pconfig '                            8 LED color
  5070.     z = LEDtri: d$ = "ledtri": GOSUB pconfig '                        9 LED tri-color
  5071.     z = radarf: d$ = "radar": GOSUB pconfig '                         10 radar visible
  5072.     z = shield: d$ = "shield": GOSUB pconfig '                        11 Star Trek!
  5073.     z = showmap: d$ = "map": GOSUB pconfig '                          12 feature locations at screen top
  5074.     z = starstatus: d$ = "stari": GOSUB pconfig '                     13 0off 1names 2info 3info 4grid
  5075.     z = zoom: d$ = "starz": GOSUB pconfig '                           14 starfield
  5076.     z = skyoff: d$ = "skys": GOSUB pconfig '                          15 sky objects
  5077.     z = gstyle: d$ = "gstyle": GOSUB pconfig '                        16 ground type
  5078.     z = mouseswap: d$ = "mouse": GOSUB pconfig '                      17 mouse buttons
  5079.     z = porb: d$ = "porb": GOSUB pconfig '                            18 pointers or bars for instruments
  5080.     z = starfiles: d$ = "stars": GOSUB pconfig '                      19 star quantity
  5081.     z = mdelay: d$ = "speed": GOSUB pconfig '                         20 system speed
  5082.     z = SGN(_FULLSCREEN): d$ = "fullscreen": GOSUB pconfig '          21 fullscreen
  5083.  
  5084.     CLOSE
  5085.     SYSTEM
  5086.  
  5087.     pconfig:
  5088.     PRINT #1, d$; ","; z
  5089.     RETURN
  5090. ' -------------------------------------------------------------------------------------------------------x
  5091. SUB Henonp (f) STATIC
  5092.  
  5093.     IF henoni = 0 THEN
  5094.         z = 20000
  5095.         DIM tb(z)
  5096.         henoni = 1
  5097.     END IF
  5098.  
  5099.     s& = VARSEG(tb(0)) '                                              for BLOADING images
  5100.     o& = VARPTR(tb(0))
  5101.     DEF SEG = s&
  5102.  
  5103.     IF crash THEN GOTO nosp
  5104.     wts = (wts + 1) MOD 3 '                                           what to show
  5105.     FOR pass = 1 TO 2
  5106.         FOR i = 0 TO 2
  5107.             IF ((i = wts) OR (pass = 2)) AND (TIMER < rtl!(i)) THEN
  5108.                 SELECT CASE i
  5109.                     CASE IS = 0 '                                     radiation
  5110.                         BLOAD f$(19), o& '                            rad.dat
  5111.                         PUT (0, 0), tb(0), PSET
  5112.                         gotblank = 0
  5113.                     CASE IS = 1 '                                     thermometer
  5114.                         GOSUB loadblank
  5115.                         LINE (20, 28)-(26, 56), 0, BF '               shadow
  5116.                         LINE (20, 26)-(24, 56), 0, BF '               erase old
  5117.                         LINE (20, 26)-(24, 56), red, B '              outline
  5118.                         CIRCLE (23, 60), 5, 0 '                       bulb shadow
  5119.                         CIRCLE (24, 60), 5, 0 '                       bulb shadow
  5120.                         CIRCLE (22, 59), 5, red '                     bulb
  5121.                         PAINT (22, 59), red, red '                    bulb fill
  5122.                         ty = 56 - rtlc(1) / 100 * 30 '                reading
  5123.                         LINE (20, ty)-(24, 56), red, BF
  5124.                     CASE IS = 2 '                                     lightning
  5125.                         GOSUB loadblank
  5126.                         uc = uc XOR 1
  5127.                         IF uc THEN tc = yellow ELSE tc = gold
  5128.                         PSET (17, 27)
  5129.                         LINE -(33, 27), tc
  5130.                         LINE -(24, 43), tc
  5131.                         LINE -(29, 43), tc
  5132.                         LINE -(16, 63), tc
  5133.                         LINE -(21, 47), tc
  5134.                         LINE -(13, 47), tc
  5135.                         LINE -(17, 27), tc
  5136.                         PAINT (22, 47), tc, tc
  5137.                 END SELECT
  5138.                 z = rtlc(i) '                                         0rads 1temperature 2bolts
  5139.                 lf = -1
  5140.                 PrepAndShowLED CSNG(z), 4, 10
  5141.                 EXIT SUB
  5142.             END IF
  5143.         NEXT i
  5144.     NEXT pass
  5145.  
  5146.     nosp: '                                                           no special = Henon plots
  5147.     IF f <> lf THEN
  5148.         tf$ = f$(f)
  5149.         BLOAD tf$, o&
  5150.         gotblank = 0
  5151.         lf = f
  5152.     END IF
  5153.     hc = (hc + 1) MOD 13 '                                            h1-h5 contain 13 images each
  5154.     IF crash THEN hc = 0 '                                            h6.dat only has one page
  5155.     PUT (0, 0), tb(hc * 1500), PSET '                                 includes
  5156.     PrepAndShowLED 0, 4, 0
  5157.     EXIT SUB
  5158.  
  5159.     loadblank: '                                                      not really blank - has program name
  5160.     IF gotblank = 0 THEN '                                               and clock/McD/speed/count box
  5161.         BLOAD f$(39), o& '                                            is lanblank.dat
  5162.         gotblank = 1
  5163.     END IF
  5164.     PUT (0, 0), tb(0), PSET
  5165.     RETURN
  5166. ' -------------------------------------------------------------------------------------------------------x
  5167. SUB Grave (x, fb$) STATIC
  5168.     tx1 = x: IF tx1 < gs THEN tx1 = gs
  5169.     tx2 = x + 68: IF tx2 > q3 THEN tx2 = q3
  5170.     IF tx1 >= tx2 THEN EXIT SUB
  5171.     VIEW SCREEN(tx1, 300)-(tx2, q4)
  5172.     IF bolthitf THEN
  5173.         tc = white: tc2 = white
  5174.     ELSE
  5175.         tc = gray: tc2 = gasoline
  5176.     END IF
  5177.     LINE (x, 300)-(x + 68, q4), tc, BF
  5178.     LINE (x + 2, 302)-(x + 66, 347), black2, B
  5179.     FOR x1 = 0 TO 1
  5180.         FOR y1 = 0 TO 1
  5181.             x2 = x + x1 * 68 - 4
  5182.             y2 = 300 + y1 * 42 - 1
  5183.             LINE (x2, y2)-(x2 + 9, y2 + 9), tc2, BF
  5184.             LINE (x2, y2)-(x2 + 9, y2 + 9), black2, B
  5185.         NEXT y1
  5186.     NEXT x1
  5187.  
  5188.     FOR z = 0 TO 1
  5189.         LINE (x + z, 300 + z)-(x + 68 - z, q4 - z), tc2, B
  5190.     NEXT z
  5191.  
  5192.     IF INSTR(fb$, "g on a ") = 0 THEN
  5193.         z$ = "  JFK      R.I.P. 1917 1963"
  5194.     ELSE
  5195.         IF (TIMER MOD 10) < 5 THEN
  5196.             z$ = "B FROST    R.I.P. 1952 2006"
  5197.         ELSE
  5198.             z$ = "R FROST    R.I.P. 1957 2019"
  5199.         END IF
  5200.     END IF
  5201.  
  5202.     PrintVGA LEFT$(z$, 7), x + 5, 317, black2, white2
  5203.  
  5204.     FOR i = 0 TO 1
  5205.         d$ = MID$(z$, i * 9 + 10, 9)
  5206.         c1 = black2: c2 = gasoline
  5207.         FOR j = 1 TO 9
  5208.             c$ = MID$(d$, j, 1)
  5209.             ta = (ta + 23) MOD tsix
  5210.             zz = (3 + 3 * SIN(ta * ATN(1) / 45)) * i
  5211.             tx = x + (j - 2) * 6 + 12
  5212.             ty = 304 + i * 24 + zz
  5213.             PrintCGA c$, tx, ty, c1, c2, 0
  5214.         NEXT j
  5215.     NEXT i
  5216.     VIEW SCREEN(gs, 0)-(q3, q4)
  5217. ' -------------------------------------------------------------------------------------------------------x
  5218. SUB FlagandFireworks STATIC
  5219.     IF fmax = 0 THEN
  5220.         fs = 60: fq = 600: fmax = fs
  5221.         DIM flagb(fq)
  5222.         DIM ve!(fs), ho!(fs), pe(fs), x!(fs), y!(fs), c(fs)
  5223.     END IF
  5224.  
  5225.     IF flx = 0 THEN '                                                 initialize
  5226.         z = SGN(sf(sf, 2) - (px! + suri)) '                           to plant flag opposite feature
  5227.         IF z = 0 THEN z = -1 '                                        optional, prevent middle
  5228.         FOR i = -1 TO 1 STEP 2 '                                      check sides
  5229.             tx = px! + i * z * 22
  5230.             ty = gety(-tx)
  5231.             '                                                         prevent PUT beyond 580 for grave in demo mode
  5232.             IF (tx < 580) AND (ABS(ty - sy1) < t) THEN
  5233.                 flx = tx
  5234.                 fly = ty
  5235.                 rev = 0
  5236.                 IF nation = 1 THEN nation = 2 ELSE nation = 1
  5237.                 initfw = 0
  5238.                 EXIT SUB
  5239.             END IF
  5240.         NEXT i
  5241.         EXIT SUB
  5242.     END IF
  5243.  
  5244.     IF liftoff THEN GOTO pflag
  5245.  
  5246.     IF initfw = 0 THEN '                                              fireworks launch & init
  5247.         ve! = RND * 5 + 16 - lob * 8 '                                vertical velocity
  5248.         ho! = RND * 5 + 2 '                                           horizontal velocity
  5249.         x!(0) = px! '                                                 initial x, middle of craft
  5250.         y!(0) = py! - 15 + ASO * 7 '                                  initial y, top of craft
  5251.         ea = -(RND * t) '                                             explode at 0-10
  5252.         IF lho! > 0 THEN ho! = -ho! '                                 reverse direction half the time
  5253.         lho! = ho!
  5254.         DO '                                                          launch
  5255.             x!(0) = x!(0) + ho! / t '                                 t = 10
  5256.             y!(0) = y!(0) - ve! / t
  5257.             ve! = ve! - .1 '                                          slow down
  5258.             PSET (x!(0), y!(0)), yellow '                             launch track
  5259.         LOOP UNTIL ve! < ea '                                         explode
  5260.         FOR i = 1 TO fmax
  5261.             z = nation - 1
  5262.             z = z * 6 + (i MOD (3 - z)) * 2 + 1 '                     color index
  5263.             '                rewhblreye
  5264.             c(i) = VAL(MID$("0415010414", z, 2)) '                    color
  5265.             z! = RND * 5 + 1 '                                        velocity
  5266.             ta = (i * 6) MOD tsix '                                    angle
  5267.             ve!(i) = z! * c!(ta) '                                    vertical velocity
  5268.             ho!(i) = z! * s!(ta) * 1.8 '                              horizontal velocity
  5269.             x!(i) = x!(0) + ho!(i) * 2 + xe! '                        start of arm
  5270.             y!(i) = y!(0) + ve!(i) * 2 + ye!
  5271.             pe(i) = RND * 5 + t '                                     persistance of arm
  5272.         NEXT i
  5273.         initfw = 1 '                                                  mark initialized
  5274.     END IF
  5275.  
  5276.     f = 1 '                                                           assume done
  5277.     FOR q = 0 TO 1 '                                                  show shell exploding
  5278.         FOR i = 1 TO fmax '                                           arms
  5279.             IF pe(i) THEN '                                           persistance of arm
  5280.                 f = 0 '                                               not done
  5281.                 pe(i) = pe(i) - 1 '                                   persistance
  5282.                 x!(i) = x!(i) + ho!(i)
  5283.                 y!(i) = y!(i) + ve!(i)
  5284.                 ve!(i) = ve!(i) + .4 '                                gravity modifies vertical
  5285.                 IF RND > .1 THEN
  5286.                     LINE (x!(i), y!(i))-(x!(i) + RND, y!(i) + RND), c(i), B
  5287.                 END IF
  5288.             END IF
  5289.         NEXT i
  5290.     NEXT q
  5291.     IF f THEN initfw = 0 '                                            end of this one, start another
  5292.  
  5293.     pflag:
  5294.     IF sn <> nation THEN '                                            new, or user changed it
  5295.         sn = nation '                                                 save current nation
  5296.         s& = VARSEG(flagb(0)) '                                       segment
  5297.         o& = VARPTR(flagb(0)) '                                       offset
  5298.         DEF SEG = s& '                                                set segment
  5299.         BLOAD f$(19 + nation), o& '                                   load array 20=USA 21=USSR
  5300.         sx = 0
  5301.         rev = 0
  5302.     END IF
  5303.  
  5304.     REDIM f2(600) '                                                   FLAG
  5305.     ty = fly - 80
  5306.     LINE (flx - 1, fly)-(flx - 1, ty), white '                        pole
  5307.     zx = flx - rev * 71
  5308.     GET (zx, ty)-(zx + 70, ty + 32), f2() '                           was flx
  5309.     PUT (zx, ty), flagb(), PSET '                                     flag
  5310.  
  5311.     '                                                                 optional move flag to left of pole
  5312.     IF (flx < px!) AND (rev = 0) AND (liftoff = 0) THEN
  5313.         FOR rx = 0 TO 69
  5314.             FOR ry = 0 TO 32
  5315.                 p = POINT(flx + rx, ty + ry)
  5316.                 PSET (flx - rx - 2, ty + ry), p
  5317.             NEXT ry
  5318.         NEXT rx
  5319.         PUT (flx, ty), f2(), PSET '                                   restore original area
  5320.         GET (flx - 71, ty)-(flx - 2, ty + 32), flagb() '              get new
  5321.         rev = 1
  5322.         zx = flx - 71
  5323.     END IF
  5324.     REDIM f2(0)
  5325.  
  5326.     sx = sx + t '                                                     optional unfurl flag
  5327.     IF sx > 70 THEN sx = 70
  5328.     IF sx < 70 THEN
  5329.         IF rev THEN
  5330.             LINE (zx, ty)-(zx + 71 - sx, ty + 32), 0, BF
  5331.         ELSE
  5332.             LINE (zx + sx, ty)-(zx + 71, ty + 32), 0, BF
  5333.         END IF
  5334.     END IF
  5335. ' -------------------------------------------------------------------------------------------------------x
  5336. SUB MakeSur
  5337.     IF iscd THEN EXIT SUB
  5338.     DIM z!(t), a1(t), v1(t), lz(t)
  5339.     msflag = 1
  5340.     VIEW
  5341.     CLS
  5342.     FOR gh = -2 TO 9 '                                                -2 demo, -1 flat, 0-9 rocks
  5343.         z$ = "Creating surfaces" + STR$(gh + 3) + " of 12"
  5344.         LINE (s, 0)-(q3, 20), 0, BF
  5345.         PrintVGA z$, 320 - LEN(z$) * 4, 2, white, black
  5346.         timemachine
  5347.  
  5348.         IF INKEY$ = CHR$(27) THEN Quit
  5349.         f$ = "S" + LTRIM$(STR$(gh))
  5350.         IF gh = -2 THEN f$ = "sd"
  5351.         IF gh = -1 THEN f$ = "sl"
  5352.         f$ = f$ + ".DAT"
  5353.         CLOSE #6
  5354.         OPEN f$ FOR RANDOM AS #6 LEN = 2
  5355.         FOR i = 1 TO q1 '                                             6400, 10 pages
  5356.             PUT #6, i, glmax
  5357.         NEXT i
  5358.         IF gh < 0 THEN GOTO keepflat
  5359.         FOR i = 1 TO 4 '                                              make sine waves
  5360.             z!(i) = RND * 36 / 550
  5361.             a1(i) = RND * tsix
  5362.             v1(i) = RND * gh * 2
  5363.         NEXT i
  5364.         FOR i = 0 TO q1
  5365.             z! = 0
  5366.             FOR j = 1 TO 4
  5367.                 y! = v1(j) * SIN((i - a1(j)) * z!(j))
  5368.                 z! = z! + y! * 4
  5369.             NEXT j
  5370.             IF (i > 5320) AND (i < 5560) THEN z! = z! / 4 - 40 '      make Hollywood higher
  5371.             z = glmax - ABS(z!)
  5372.             IF z < glmin THEN z = glmin
  5373.             PUT #6, i + 1, z
  5374.         NEXT i
  5375.         Smooth 5319
  5376.         Smooth 5559
  5377.         keepflat:
  5378.         IF gh = -2 THEN tz = 3130 ELSE tz = 2240
  5379.         FOR i = -51 TO 51 '                                           volcano
  5380.             z = glmax - (51 - ABS(i))
  5381.             PUT #6, tz + i, z
  5382.         NEXT i
  5383.         Smooth 2240 - 50
  5384.         Smooth 2240 + 50
  5385.         z = 302
  5386.         FOR i = -5 TO 5 '                                             volcano top
  5387.             PUT #6, tz + i, z
  5388.         NEXT i
  5389.         IF gh > -1 THEN '                                             ground height not flat, add rocks/small craters
  5390.             FOR i = -1 TO 1 STEP 2 '                                  up or down
  5391.                 rocks = RND * h + h '                                 rocks & indentations
  5392.                 FOR j = 1 TO rocks
  5393.                     rx = RND * 6380 + t
  5394.                     zz = RND * 4 + 1
  5395.                     FOR k = -zz TO zz
  5396.                         GET #6, rx + k, z
  5397.                         z = z - zz * i + ABS(k) * i
  5398.                         IF z < glmin THEN z = glmin
  5399.                         IF z > glmax THEN z = glmax
  5400.                         PUT #6, rx + k, z
  5401.                     NEXT k
  5402.                 NEXT j
  5403.             NEXT i
  5404.         END IF
  5405.         Smooth q1 - 1 '                                               6399 - 0 transition
  5406.  
  5407.         FOR i = 1 TO t '                                              create landing zones
  5408.             IF gh = -2 THEN '                                         compress onto 1 page
  5409.                 lz(i) = 3050 + (i - 1) * 80
  5410.             ELSE
  5411.                 lz(i) = 320 + (i - 1) * (q3 + 1) '                    1 per page
  5412.             END IF
  5413.         NEXT i
  5414.         IF gh = -2 THEN '                                             demo terrain
  5415.             SWAP lz(9), lz(t) '                                       move grave 1 page left
  5416.             SWAP lz(2), lz(4) '                                       move car wash 2 pages right
  5417.         END IF
  5418.  
  5419.         hs = 0
  5420.         RESTORE features
  5421.         FOR i = 1 TO t '                                              10 features, create landing zones beside each
  5422.             READ z$, x, y, lz
  5423.             sf(i, 0) = lz(i) - x \ 2 '                                start
  5424.             sf(i, 1) = sf(i, 0) + x '                                 end
  5425.             sf(i, 2) = (sf(i, 0) + sf(i, 1)) \ 2 '                    middle
  5426.             IF i = 4 THEN GOTO isvolcano
  5427.             FOR x2 = -lz TO lz
  5428.                 z = hs * (y = 0) * (i <> 5)
  5429.                 IF i = 3 THEN z = 40 '                                LGM
  5430.                 IF i = 4 THEN z = 50 - ABS(x2) / 2
  5431.                 IF gh <> -2 THEN
  5432.                     z = glmax - z
  5433.                     PUT #6, sf(i, 2) + x2, z
  5434.                 END IF
  5435.             NEXT x2
  5436.             FOR x2 = sf(i, 0) TO sf(i, 1) '                           target
  5437.                 GET #6, x2 + 1, z
  5438.                 z = z + y * (y <> 0)
  5439.                 PUT #6, x2 + 1, z
  5440.             NEXT x2
  5441.             IF gh <> -2 THEN
  5442.                 Smooth sf(i, 2) - lz
  5443.                 Smooth sf(i, 2) + lz
  5444.             END IF
  5445.             isvolcano:
  5446.         NEXT i
  5447.  
  5448.         Smooth sf(1, 0) '                                             Area 51
  5449.         Smooth sf(1, 1)
  5450.  
  5451.         RESTORE BigM '                                                McDonalds
  5452.         y = 0
  5453.         DO
  5454.             READ z$
  5455.             IF z$ = "x" THEN EXIT DO
  5456.             y = y + 1
  5457.             FOR x = 1 TO LEN(z$)
  5458.                 IF MID$(z$, x, 1) = "X" THEN
  5459.                     z = glmax + y - 38
  5460.                     PUT #6, sf(5, 0) + x + 1, z
  5461.                 END IF
  5462.             NEXT x
  5463.         LOOP
  5464.  
  5465.         suri = 0
  5466.         FOR i = 1 TO q1 '                                             optional, show progress
  5467.             GET #6, i + 1, y
  5468.             y = gh * 25 + y / 6 + 20
  5469.             PSET (i \ t, y), 1
  5470.         NEXT i
  5471.     NEXT gh
  5472.     msflag = 0
  5473. ' -------------------------------------------------------------------------------------------------------x
  5474. SUB Area51 (tf$) STATIC
  5475.     IF a51i = 0 THEN
  5476.         pi! = _D2R(180)
  5477.         zz! = ATN(1) / 45 * 3
  5478.         ac1 = red
  5479.         ac2 = white2
  5480.         fc$ = "0105030709101412"
  5481.         a51i = 1
  5482.     END IF
  5483.  
  5484.     IF bolthitf THEN GOTO aother
  5485.  
  5486.     tx = x + 33
  5487.     FOR i = 20 TO h STEP 5
  5488.         z = (z + 2) MOD 45
  5489.         FOR j = 0 TO 1
  5490.             SWAP ac1, ac2
  5491.             FOR k = 0 TO 3
  5492.                 aa = k * 45 + z
  5493.                 a1! = _D2R(aa) - zz!
  5494.                 a2! = _D2R(aa) + zz!
  5495.                 IF j THEN
  5496.                     a1! = pi! - a1!
  5497.                     a2! = pi! - a2!
  5498.                 END IF
  5499.                 IF a1! < 0 THEN a1! = 0
  5500.                 IF a2! < 0 THEN a2! = 0
  5501.                 IF a2! < a1! THEN SWAP a1!, a2!
  5502.                 CIRCLE (tx, 308), i, ac1, a1!, a2!
  5503.             NEXT k
  5504.         NEXT j
  5505.     NEXT i
  5506.  
  5507.     IF invincible THEN GOTO aother
  5508.     dx! = px! - tx
  5509.     dy! = 280 - py!
  5510.     IF (ABS(dx!) < 81) AND (ABS(dy!) < 61) AND (liftoff = 0) THEN
  5511.         IF contact = 0 THEN mes$(1) = "AREA 51 ELEVATOR ACTIVATED"
  5512.         _DELAY .1
  5513.         FOR tx2 = sx1 TO sx2 STEP 1
  5514.             LINE (tx2, sy1 + 2)-(tx, 309), gray
  5515.         NEXT tx2
  5516.         IF sy1 > 310 THEN
  5517.             LINE (sx1 - 1, sy1 + 2)-(tx, 309), black
  5518.             LINE (sx2 + 1, sy1 + 2)-(tx, 309), black
  5519.         END IF
  5520.         px! = px! - SGN(dx!)
  5521.         IF ABS(dx!) < 2 THEN
  5522.             IF py! > 280 THEN j = 0 ELSE j = 2
  5523.         ELSE
  5524.             IF py! > 280 THEN j = -2 ELSE j = 1
  5525.         END IF
  5526.         py! = py! + j
  5527.         a = 0
  5528.         thrust! = 0
  5529.         vx! = 0
  5530.         vy! = 0
  5531.         b2b = 1
  5532.         GOTO bingo
  5533.     END IF
  5534.  
  5535.     aother:
  5536.     IF bb2! = 0 THEN bb2! = TIMER + 2
  5537.     IF TIMER > bb2! THEN
  5538.         bb2! = TIMER + 2
  5539.         b2b = 1 - b2b
  5540.     END IF
  5541.  
  5542.     bingo:
  5543.     IF contact THEN b2b = 1
  5544.     IF b2b THEN
  5545.         IF bolthitf THEN tc = white ELSE tc = dred
  5546.         FOR i = 1 TO 4
  5547.             tx = x + i * t + 3
  5548.             PrintVGA MID$("AREA", i, 1), tx, 313, white2, tc
  5549.         NEXT i
  5550.         FOR nu = 0 TO 1
  5551.             FOR ty = 0 TO 4
  5552.                 bp = VAL("&H" + MID$("26227E8E2E", nu * 5 + ty + 1, 1))
  5553.                 sp = 1
  5554.                 FOR tx = 1 TO 4
  5555.                     IF bp AND 1 THEN
  5556.                         tx2 = x + 52 - tx * 4 - nu * 16
  5557.                         ty2 = 309 + ty * 5 + 15
  5558.                         LINE (tx2, ty2)-STEP(3, 4), tc, BF
  5559.                         IF sp THEN sp = 0: LINE (tx2 + 4, ty2)-STEP(0, 4), white2
  5560.                     END IF
  5561.                     bp = bp \ 2
  5562.                 NEXT tx
  5563.             NEXT ty
  5564.         NEXT nu
  5565.     ELSE
  5566.         OPEN tf$ FOR INPUT AS #5 '                                    alien.dat (head)
  5567.         zc = (zc + 1) MOD 8 '                                         color
  5568.         FOR i = 1 TO 32
  5569.             LINE INPUT #5, z$
  5570.             FOR j = 1 TO LEN(z$)
  5571.                 c$ = MID$(z$, j, 1)
  5572.                 IF c$ <> "." THEN '                                   . = transparent
  5573.                     IF c$ = " " THEN
  5574.                         tc = VAL(MID$(fc$, zc * 2 + 1, 2))
  5575.                         IF bolthitf THEN tc = white
  5576.                     ELSEIF c$ = "r" THEN '                            spooky eyes
  5577.                         tc = red
  5578.                     ELSE
  5579.                         tc = black2 '                                 eyes/nose/mouth
  5580.                     END IF
  5581.                     x2 = x + j + t
  5582.                     y2 = 312 + i
  5583.                     PSET (x2, y2), tc
  5584.                 END IF
  5585.             NEXT j
  5586.         NEXT i
  5587.         CLOSE #5
  5588.     END IF
  5589. ' -------------------------------------------------------------------------------------------------------x
  5590. SUB UFO (tx0, ty0, txi) STATIC '                                      so pathetic a graphic that it's funny, maybe
  5591.     aa = (aa + 5) MOD tsix
  5592.     tx = tx0 + t * COS(_D2R(aa))
  5593.     ty = ty0 + t * SIN(_D2R(aa))
  5594.     FOR i = 0 TO 55
  5595.         CIRCLE (tx, ty), i, gunmetal, , , .15
  5596.     NEXT i
  5597.     FOR i = 8 TO 15
  5598.         IF i MOD 2 THEN tc = orange ELSE tc = black2
  5599.         CIRCLE (tx, ty - 12), i, tc, , , .35
  5600.     NEXT i
  5601.     tc = VAL(MID$("020414", (ty MOD 3) * 2 + 1, 2))
  5602.     p = (p + 1) MOD 5
  5603.     IF txi < 0 THEN tp = 4 - p ELSE tp = p
  5604.     FOR z = -2 TO 2
  5605.         tx2 = tx + z * 16
  5606.         CIRCLE (tx2, ty), 5 - ABS(z), black2, , , .7
  5607.         IF tp = (z + 2) THEN tc2 = tc ELSE tc2 = black2
  5608.         PAINT (tx2, ty), tc2, black2
  5609.         CIRCLE (tx2, ty), 5 - ABS(z), tc2, , , .7
  5610.     NEXT z
  5611.     LINE (tx - 30, ty + 8)-(tx - 35, ty + 20), orange '               legs
  5612.     LINE (tx - 37, ty + 20)-(tx - 31, ty + 20), orange
  5613.     LINE (tx + 30, ty + 8)-(tx + 35, ty + 20), orange '               pads
  5614.     LINE (tx + 32, ty + 20)-(tx + 38, ty + 20), orange
  5615. ' -------------------------------------------------------------------------------------------------------x
  5616. SUB TinyFont (d$, tx, ty, tc) STATIC '                                3*5
  5617.     IF fontinit = 0 THEN '                                            initialize
  5618.         DIM sp(13, 4)
  5619.         RESTORE tinyfontd
  5620.         FOR n = 0 TO 13
  5621.             READ g$
  5622.             FOR i = 0 TO 4
  5623.                 READ z
  5624.                 sp(n, i) = z * 4096
  5625.             NEXT i
  5626.         NEXT n
  5627.         fontinit = 1
  5628.     END IF
  5629.  
  5630.     FOR z = 1 TO LEN(d$)
  5631.         z$ = MID$(d$, z, 1)
  5632.         zz = INSTR(".-: ", z$)
  5633.         IF zz THEN d = zz + 9 ELSE d = VAL(z$)
  5634.         IF (tc = 1) AND (RND > .9) THEN ttc = 3 ELSE ttc = tc '       Borg effect (some bright)
  5635.         FOR i = 0 TO 4
  5636.             x2 = tx + z * 4 + j - 4
  5637.             LINE (x2, ty + i)-(x2 + 4, ty + i), ABS(ttc), , sp(d, i)
  5638.         NEXT i
  5639.     NEXT z
  5640. ' -------------------------------------------------------------------------------------------------------x
  5641. SUB GraphSpeed STATIC
  5642.     IF speedi = 0 THEN
  5643.         spq = t: psp = 500
  5644.         DIM spt!(spq)
  5645.         DIM pspeed(psp)
  5646.         DIM m(3) AS _MEM
  5647.         m(0) = _MEM(spt!(0))
  5648.         m(1) = _MEM(spt!(1))
  5649.         m(2) = _MEM(pspeed(0))
  5650.         m(3) = _MEM(pspeed(1))
  5651.         speedi = 1
  5652.     END IF
  5653.  
  5654.     IF spt! = 0 THEN
  5655.         spt! = TIMER
  5656.         zmin! = h
  5657.         zran! = 2
  5658.         sphac = psp + 1
  5659.     ELSE
  5660.         _MEMCOPY m(1), m(1).OFFSET, 4 * spq TO m(0), m(0).OFFSET
  5661.         _MEMCOPY m(3), m(3).OFFSET, 2 * psp TO m(2), m(2).OFFSET
  5662.  
  5663.         IF spt! > TIMER THEN spt! = TIMER
  5664.         spt!(spq) = (TIMER - spt!) * h * t
  5665.         spt! = TIMER
  5666.         z! = 0
  5667.         FOR i = 1 TO spq
  5668.             z! = z! + spt!(i)
  5669.         NEXT i
  5670.         pspeed(psp) = z! / spq
  5671.         spmin = q1: spmax = -spmin
  5672.         sphac = sphac - 1 - (sphac = 0)
  5673.  
  5674.         IF rick = 0 THEN EXIT SUB
  5675.  
  5676.         FOR i = sphac TO psp
  5677.             spx = 113 + i
  5678.             spy = zmin! + (pspeed(i) - zmin!) / zran!
  5679.             IF i = sphac THEN
  5680.                 PSET (spx, spy), orange
  5681.             ELSE
  5682.                 LINE -(spx, spy), orange
  5683.             END IF
  5684.             IF pspeed(i) <= spmin THEN spmin = pspeed(i): spminx = spx: spminy = spy
  5685.             IF pspeed(i) >= spmax THEN spmax = pspeed(i): spmaxx = spx: spmaxy = spy
  5686.         NEXT i
  5687.  
  5688.         spsta = FIX(spmin / h) * h
  5689.         spend = INT(spmax / h + pf!) * h
  5690.         spend = spend - (spend = spsta) * h
  5691.         FOR i = spsta TO spend STEP h
  5692.             spy = zmin! + (i - zmin!) / zran!
  5693.             LINE (110, spy)-(614, spy), green, , &H1111
  5694.             z$ = RIGHT$("  " + STR$(i), 4)
  5695.             TinyFont z$, 87, spy - 2, orange
  5696.             TinyFont z$, 620, spy - 2, orange
  5697.         NEXT i
  5698.  
  5699.         z$ = LTRIM$(STR$(spmin))
  5700.         ty = spminy - 15
  5701.         TinyFont z$, spminx + 5, ty, orange
  5702.         LINE (spminx, ty + 5)-(spminx, ty - 5), orange
  5703.  
  5704.         z$ = LTRIM$(STR$(spmax))
  5705.         ty = spmaxy + 15
  5706.         IF ty > q4 THEN ty = q4 - 20
  5707.         TinyFont z$, spmaxx + 5, ty, orange
  5708.         LINE (spmaxx, ty)-(spmaxx, ty + t), orange
  5709.     END IF
  5710. ' -------------------------------------------------------------------------------------------------------x
  5711. SUB Smooth (p1)
  5712.     p2 = p1 + 1
  5713.     zz = t
  5714.     i1 = (p1 - zz + q1) MOD q1
  5715.     i2 = (p2 + zz + q1) MOD q1
  5716.     IF msflag THEN '                                                  making surfaces, array not valid
  5717.         GET #6, i1 + 1, y1
  5718.         GET #6, i2 + 1, y2
  5719.     ELSE
  5720.         y1 = gh(i1)
  5721.         y2 = gh(i2)
  5722.     END IF
  5723.     m! = (y1 + y2) / 2
  5724.     d! = (y1 - y2) / zz / 2
  5725.     FOR x = 1 TO zz
  5726.         s! = d! * (zz - x)
  5727.         i1 = (p2 + zz - x + q1) MOD q1
  5728.         i2 = (p1 - zz + x + q1) MOD q1
  5729.         gh(i1) = m! - s!
  5730.         gh(i2) = m! + s!
  5731.         IF iscd = 0 THEN
  5732.             PUT #6, i1 + 1, gh(i1)
  5733.             PUT #6, i2 + 1, gh(i2)
  5734.         END IF
  5735.     NEXT x
  5736. ' -------------------------------------------------------------------------------------------------------x
  5737. SUB SaveImage (f$) '                                                  this sub from qb64.org website (modified)
  5738.     IF iscd THEN EXIT SUB
  5739.     VIEW SCREEN(0, 0)-(q3, q4)
  5740.     bpp& = 8
  5741.     tx& = 640
  5742.     ty& = 350
  5743.     '       XXXX   1XXXX
  5744.     '     12345678901234
  5745.     b$ = "BM????_RGF????" + MKL$(40) + MKL$(tx&) + MKL$(ty&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
  5746.     FOR c& = 0 TO 255 '                                               read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
  5747.         cv& = _PALETTECOLOR(c&, 0) '                                  color attribute to read
  5748.         b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
  5749.     NEXT
  5750.     MID$(b$, 11, 4) = MKL$(LEN(b$)) '                                 image pixel data offset (BMP header)
  5751.     IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
  5752.     FOR py& = ty& - 1 TO 0 STEP -1
  5753.         z$ = ""
  5754.         FOR px& = 0 TO tx& - 1
  5755.             c& = POINT(px&, py&) '                                    2 bit values are large LONG values
  5756.             z$ = z$ + CHR$(ABS(c&) MOD 256)
  5757.         NEXT px&
  5758.         d$ = d$ + z$ + padder$
  5759.     NEXT py&
  5760.     MID$(b$, 35, 4) = MKL$(LEN(d$)) '                                 image size (BMP header)
  5761.     b$ = b$ + d$ '                                                    total file data bytes to create file
  5762.     MID$(b$, 3, 4) = MKL$(LEN(b$)) '                                  size of data file (BMP header)
  5763.     f& = FREEFILE
  5764.     OPEN f$ FOR OUTPUT AS #f&: CLOSE #f& '                            erases an existing file
  5765.     OPEN f$ FOR BINARY AS #f&
  5766.     PUT #f&, , b$
  5767.     CLOSE #f&
  5768.     VIEW SCREEN(gs, 0)-(q3, q4)
  5769. ' -------------------------------------------------------------------------------------------------------x
  5770. SUB MakeStarFiles '                                                   takes a LONG time
  5771.     IF iscd THEN EXIT SUB
  5772.     savestarfiles = starfiles
  5773.     ts$ = TIME$
  5774.     mstar = 0
  5775.     FOR starfiles = 0 TO 2
  5776.         FOR rmin = 0 TO 23
  5777.             FOR dmin = -90 TO 90 STEP 10
  5778.                 mstar = mstar + 1 '                                   for progress bar
  5779.                 starinit = 0
  5780.                 regen = 1
  5781.                 Stars
  5782.                 IF INKEY$ = CHR$(27) THEN SYSTEM '                    Esc aborts
  5783.             NEXT dmin
  5784.         NEXT rmin
  5785.     NEXT starfiles
  5786.     mstar = 0
  5787.     sprint ts$, 200, 100, red, black
  5788.     sprint TIME$, 200, 120, red, black
  5789.     timemachine
  5790.     SLEEP '                                                           lets user see how LONG it took
  5791.     starfiles = savestarfiles: starinit = 0: rmin = 0: dmin = 0
  5792. ' -------------------------------------------------------------------------------------------------------x
  5793. SUB dissolve STATIC '                                                 called with }
  5794.     DIM Buffer AS _MEM
  5795.     Buffer = _MEMIMAGE(0)
  5796.     np = 0
  5797.     DO
  5798.         FOR y = _HEIGHT - 8 TO 0 STEP -1
  5799.             FOR x = 0 TO _WIDTH
  5800.                 f& = y * _WIDTH + x
  5801.                 t& = f& + INT(RND * 2 + 4) * _WIDTH
  5802.                 d = _MEMGET(Buffer, Buffer.OFFSET + f&, _UNSIGNED _BYTE)
  5803.                 _MEMPUT Buffer, Buffer.OFFSET + t&, d AS _UNSIGNED _BYTE
  5804.             NEXT x
  5805.         NEXT y
  5806.         IF np = 0 THEN
  5807.             FOR x = 0 TO _WIDTH * 4
  5808.                 _MEMPUT Buffer, Buffer.OFFSET + x, 0 AS _UNSIGNED _BYTE
  5809.                 o2& = _WIDTH * _HEIGHT - 1 - x
  5810.                 _MEMPUT Buffer, Buffer.OFFSET + o2&, 0 AS _UNSIGNED _BYTE
  5811.             NEXT x
  5812.         END IF
  5813.         timemachine
  5814.         np = np + 1
  5815.         IF INKEY$ = CHR$(27) THEN SYSTEM
  5816.     LOOP UNTIL np > 120
  5817.     _MEMFREE Buffer
  5818. ' -------------------------------------------------------------------------------------------------------x
  5819. SUB timemachine '                                                     xlate to 32 bit color for green screen, warp effects
  5820.     DIM oc&(15)
  5821.     FOR i = 0 TO 15
  5822.         OUT &H3C7, i
  5823.         tred = INP(&H3C9) * 4: tgrn = INP(&H3C9) * 4: tblu = INP(&H3C9) * 4
  5824.         coav = (tred + tgrn + tblu) \ 3
  5825.         IF cpal = 0 THEN
  5826.             oc&(i) = _RGB32(tred, tgrn, tblu) '                       regular color
  5827.         ELSEIF cpal = 1 THEN
  5828.             oc&(i) = _RGB32(0, coav, 0) '                             shades of green
  5829.         ELSEIF cpal = 2 THEN
  5830.             oc&(i) = _RGB32(coav, coav \ 2, 0) '                      shades of orange
  5831.         ELSE
  5832.             oc&(i) = _RGB32(coav, coav, coav) '                       black and white
  5833.         END IF
  5834.     NEXT i
  5835.  
  5836.     DIM m AS _MEM
  5837.     m = _MEMIMAGE(canvas&)
  5838.     DO: _LIMIT q4 '                                                   349 (h/100 too little, slows down program!)
  5839.         tempimage& = _NEWIMAGE(640, 350, 32)
  5840.     LOOP UNTIL tempimage& < -1 '                                      try until valid (can fail to make screen)
  5841.     SCREEN tempimage&
  5842.     FOR y = 0 TO q4 '                                                 replot each pixel of old to new screen
  5843.         FOR x = 0 TO q3
  5844.             a& = y * 640 + x
  5845.             dd = _MEMGET(m, m.OFFSET + a&, _UNSIGNED _BYTE)
  5846.             PSET (x, y), oc&(dd)
  5847.         NEXT x
  5848.     NEXT y
  5849.     IF (LEN(dead$) = 0) AND (warp! >= 1) THEN
  5850.         VIEW SCREEN(gs, SGN(LEN(mes$(0))) * 20)-(q3, q4) '            protect instrument panel, top line if message active
  5851.         IF warp! >= 9 THEN contour ELSE warpx
  5852.         VIEW SCREEN(gs, 0)-(q3, q4) '                                 back to normal, only instrument panel protected
  5853.     END IF
  5854.  
  5855.     IF (rdtime! > 0) AND (TIMER < rdtime!) AND _FILEEXISTS("rick.jpg") THEN
  5856.         i& = _LOADIMAGE("rick.jpg") '                                 87 * 93 pix of author
  5857.         IF i& < -1 THEN
  5858.             tx = _WIDTH - 87
  5859.             _PUTIMAGE (tx, 0)-(tx + 87, 93), i&, 0
  5860.             _FREEIMAGE i&
  5861.             _PRINTSTRING (tx + 24, 100), "What?"
  5862.         END IF
  5863.     END IF
  5864.  
  5865.     IF starship AND _FILEEXISTS("starship.jpg") THEN
  5866.         IF shipi& = 0 THEN shipi& = _LOADIMAGE("starship.jpg") '      296 * 91
  5867.         shipx = shipx + 4
  5868.         ty1 = py! - 50: ty2 = ty1 + 91
  5869.         shipo = shipx - 100
  5870.         q = 2
  5871.         gs = 0
  5872.         IF shipi& < -1 THEN _PUTIMAGE (shipo, ty1 \ q)-(shipo + 296 \ q, ty2 \ q), shipi&, 0
  5873.         IF shipx > 750 THEN shipx = 0: starship = 0
  5874.     END IF
  5875.  
  5876.     _DISPLAY '                                                        show new image
  5877.     SCREEN canvas& '                                                  back to old mode so the rest of the program can run
  5878.     _MEMFREE m '                                                      would run out of memory otherwise
  5879.     _FREEIMAGE tempimage&
  5880.  
  5881. ' -------------------------------------------------------------------------------------------------------x
  5882. SUB warpx STATIC
  5883.     wa1 = (wa1 + 5) MOD tsix
  5884.     wa2 = wa1
  5885.     wx! = 320 + 70 * s!(wa1)
  5886.     wy! = 175 + 70 * c!(wa1)
  5887.     wc1 = 200
  5888.     FOR wd1 = 64 TO 600 STEP 8
  5889.         wa2 = wa2 + 2
  5890.         wc1 = (wc1 + 27) MOD 512
  5891.         wc2 = ABS(wc1 - 256)
  5892.         wc& = _RGB32(wc2, 1, 1)
  5893.         wd2 = 20 * s!((ABS(wa1 - 256) * 5) MOD tsix)
  5894.         wd3 = wd1 + wd2
  5895.         FOR z = 0 TO 4
  5896.             wde = (wa2 + 90 * z) MOD tsix
  5897.             wtx = wx! + wd3 * s!(wde)
  5898.             wty = wy! + wd3 * c!(wde)
  5899.             IF z = 0 THEN PSET (wtx, wty), wc& ELSE LINE -(wtx, wty), wc&
  5900.         NEXT z
  5901.     NEXT wd1
  5902. ' -------------------------------------------------------------------------------------------------------x
  5903. SUB contour STATIC
  5904.     wa1 = (wa1 + 5) MOD tsix
  5905.     wx! = 320 + 70 * s!(wa1)
  5906.     wy! = 175 + 70 * c!(wa1)
  5907.     DIM distance(360), elevation(360), active(10), angle(10)
  5908.     e0 = 320
  5909.     n = 6: GOSUB genang
  5910.     FOR i = 1 TO n
  5911.         angle = angle(i)
  5912.         angle = (angle + tsix) MOD tsix
  5913.         active(i) = angle
  5914.         distance(angle) = 50 + RND * 150
  5915.         elevation(angle) = 100 + RND * 150
  5916.     NEXT i
  5917.     n = n + 1
  5918.     active(n) = active(1)
  5919.     distance(active(n)) = distance(active(1))
  5920.     elevation(active(n)) = elevation(active(1))
  5921.     FOR i = 1 TO n
  5922.         angle1 = active(i - 1)
  5923.         angle2 = active(i)
  5924.         ddif! = distance(angle2) - distance(angle1)
  5925.         edif! = elevation(angle2) - elevation(angle1)
  5926.         IF i = n THEN angle2 = angle2 + tsix
  5927.         a! = 0: ai! = 90 / (angle2 - angle1)
  5928.         FOR z = INT(angle1) TO angle2
  5929.             na = z MOD tsix
  5930.             a! = a! + ai!
  5931.             z! = s!(a!) * s!(a!)
  5932.             distance(na) = distance(angle1) + ddif! * z!
  5933.             elevation(na) = elevation(angle1) + edif! * z!
  5934.         NEXT z
  5935.     NEXT i
  5936.     FOR el = -200 TO 220
  5937.         zz = 155 * s!((ABS(el) * 3) MOD tsix) + 100
  5938.         bb = bb XOR 1
  5939.         IF bb THEN c& = _RGB32(0, 0, zz) ELSE c& = _RGB32(zz, 0, 0)
  5940.         FOR mangle = 0 TO tsix
  5941.             angle = mangle MOD tsix
  5942.             distance = distance(angle)
  5943.             elevation = elevation(angle)
  5944.             epf! = distance / (e0 - elevation)
  5945.             d! = distance - ((el - elevation) * epf!)
  5946.             tx = px! + d! * c!(angle)
  5947.             ty = py! - d! * s!(angle)
  5948.             IF mangle THEN LINE -(tx, ty), c& ELSE PSET (tx, ty), c&
  5949.         NEXT mangle
  5950.     NEXT el
  5951.     EXIT SUB
  5952.  
  5953.     genang:
  5954.     zz = 420 / n
  5955.     FOR i = 2 TO n
  5956.         ta = (i - 2) * zz + INT(RND * 10) - 5 + 30
  5957.         angle(i) = INT(ta MOD tsix)
  5958.     NEXT i
  5959.     sort:
  5960.     sorted = 1
  5961.     FOR i = 1 TO n - 1
  5962.         a1 = angle(i)
  5963.         a2 = angle(i + 1)
  5964.         IF a1 > a2 THEN sorted = 0: SWAP angle(i), angle(i + 1)
  5965.     NEXT i
  5966.     IF sorted = 0 THEN GOTO sort
  5967.     FOR i = 1 TO n - 1
  5968.         a1 = angle(i)
  5969.         a2 = angle(i + 1)
  5970.         IF (a2 - a1) < 20 THEN GOTO genang
  5971.     NEXT i
  5972.     RETURN
  5973. ' -------------------------------------------------------------------------------------------------------x
  5974. FUNCTION FileCheck$ (f$)
  5975.     i = 0
  5976.     IF _FILEEXISTS(LCASE$(f$)) THEN f$ = LCASE$(f$): i = 1
  5977.     IF _FILEEXISTS(UCASE$(f$)) THEN f$ = UCASE$(f$): i = 1
  5978.     IF i = 0 THEN f$ = ""
  5979.     FileCheck$ = f$
  5980. ' -------------------------------------------------------------------------------------------------------x
  5981.  

 
Moon Lander Screenshot.png




                                                                                                                                          (98 downloads previously)
* L64 2020-11-29.ZIP (Filesize: 1.52 MB, Downloads: 125)
« Last Edit: August 17, 2021, 05:23:35 am by Junior Librarian »