[comp.sys.handhelds] AstroNUT V1.1

akcs.kevin@hpcvbbs.UUCP (Kevin Jessup) (05/16/91)

%%HP: T(3)A(R)F(.);
@
@ AstroNUT V1.1
@ by Kevin Jessup
@ 16-May-1991
@
@ Version 1.1
@ -----------
@ This version adds a bit of audio and corrects a minor bug:
@ flag -19, the COMPLEX MODE flag, is now cleared to insure
@ that 2-d vectors are produced when required.  Also, all
@ temporary global variables are cleared from the directory
@ at the end of play.  (Please allow time for cleanup when
@ the game ends: wait for the HP48SX busy indicator to shut
@ off.)  Otherwise, the game is the same.
@
@ Introduction
@ ------------
@ AstroNUT is a lunar lander simulation for the 48SX.
@ It supports 2-d travel (up, down, left, right) and a
@ random terraine that is generated for each new game.
@ All routines are in RPL so the screen updates are somewhat
@ slow.  I still find play acceptable however.
@
@ The object of the game is to land on a more or less flat
@ portion of the lunar surface with a horizontal velocity of
@ zero and a vertical velocity of less than 5 feet per second.
@ (Somewhat fast! Change it if you like.)  You have a limited
@ amount of fuel available to do this.
@
@ Initial parameters
@ ------------------
@ Altitude:            170 feet
@
@ Vertical velocity:   -20 feet per second.  A "second" is
@                      not the usual unit of time that you
@                      are familiar with but how long it takes
@                      this game to execute it's main loop!
@                      You will have to hit the thrust key
@                      quite often to slow down.  Read on...
@
@ Horizontal velocity: 5 feet per second.  The direction
@                      (left or right) is random.  The initial
@                      horizontal position is also random.
@
@ Fuel:                100 units.  In gallons, liters, cubic
@                      light-years or whatever you'd like to
@                      call it :-)
@
@ Control keys
@ ------------
@ 8: Apply upward thrust (One push equals thrust of 1/2 g)
@
@ 4: Apply left thrust (Changes horizontal vel. by 1 ft/sec)
@
@ 6: Apply right thrust (Changes horizontal vel. by 1 ft/sec)
@
@ With each screen update, your downward velocity will
@ increase due to the acceleration of gravity at a rate of
@ 4 ft/s^2.  It will require 2 hits of the vertical thrust
@ (key 8) to exactly compensate for the acceleration due to
@ gravity.
@
@ Screen positioning
@ ------------------
@ As you move to the left and right edges of the display, you
@ will wrap around to the opposite side.  There are "unlimited"
@ vertical screens.  You will wrap around at the top and bottom.
@ When you reach the lowest screen, there will be a slight pause
@ as the lunar surface is drawn.  If you move above the lowest
@ screen, the surface will be erased.  The current "flight
@ parameters" are displayed at the top right of the LCD.
@
@ Loading
@ -------
@ For the neophytes, those funny litle characters at the start
@ of these lines are HP48SX comment delimiters.  You can transfer
@ this entire file AS IS to your 48.  The 48 will remove all the
@ comments and load only the code.
@
@ After transferring this file to your 48, recall the directory
@ to the stack.  Execute the BYTES command.  You should get the
@ following...
@
@              Level 2:    #5AB1h
@              Level 1:    2707.5
@
@ Once you have successfully transferred the directory to your 48,
@ just hit PLAY to start.
@
@ Be patient...after a little practice, you should be able to
@ land using only 100 units of fuel.  You can modify the amount
@ of fuel, thrust and acceleration due to gravity if you like.
@ Study the code below to find out how.  Have fun!
@
@ This is "freeware" but if you'd like to send a few bucks, don't
@ let that stop you!
@
@ Kevin Jessup
@ 9118 N 85th
@ Milwaukee, WI 53224
@ (414)355-9752
@
@ Milwaukee HP48SX BBS
@ 2400/1200/300 baud
@ (414)362-2020
@ 6PM to 7AM or all day Sunday
@

DIR                   @ AstroNUT directory

  PLAY                @ push PLAY to start
    \<< RCLF 3 FIX    @ save flags
-19 CF # 83h # 40h    @ create a blank PICT
BLANK PICT STO 1 CF   @ clear the crash flag
170 'ht' STO          @ set height to 170 feet
-20 'v' STO 5         @ set vertical v to -20
      IF RAND .5 <    @ set horiz v to 5 or -5
      THEN NEG
      END 'hv' STO
RAND 80 * IP 'x'      @ random horiz position
STO 100 'fuel' STO    @ 100 unit of fuel
2 CF                  @ clear the bottom flag
MAKBOTTOM { # 0h      @ random terrain coordinates
# 0h } PVIEW MAIN     @ display and loop on main
CRASHht 'ht' STO      @ display landing parameters
CRASHx 'x' STO
CRASHv 'v' STO
STATUS PICT NEWC      @ display landing position
SHIP GXOR PICT {      @ display AstroNUT or CRASH
# 5h # 5h }
      IF CRASHv -4    @ test slope, vv and hv
< CRASHsl ABS .084
> OR hv OR
      THEN
"*CRASH*" LOOSE
      ELSE PICT 7
'ht' STO+ 1 'x'
STO+ NEWC aflag REPL
"AstroNUT" WIN
      END 3 \->GROB
REPL 7 FREEZE         @ freeze the display
globals PURGE         @ purge temporary globals
      WHILE KEY       @ flush any excess keys
      REPEAT DROP
      END STOF        @ restore flags and quit
    \>>

  WIN                 @ Play the WIN tune.
    \<< 125           @ "I am not a musician!"
      DO DUP .02
BEEP 2 *
      UNTIL DUP
4000 >
      END DROP
    \>>

  LOOSE               @ Play the LOOSE tune
    \<< 4000
      DO DUP .02
BEEP 2 /
      UNTIL DUP 125
<
      END DROP
    \>>

  MAIN                @ main processing loop
    \<<
      DO              @ draw or erase the terraine
        IF ht 56 >
        THEN
          IF 2 FS?
          THEN
ERASE 2 CF
          END
        ELSE
          IF 2 FC?
          THEN
DRAWBOTTOM 2 SF
          END
        END STATUS    @ display flight parameters
NEWC PICT OVER SHIP   @ display the lander
GXOR ht 20 * .01      @ beep based on altitude
BEEP v 'ht' STO+ hv   @ calculate new position
'x' STO+               
        IF x 124 >    @ wrap horizontal
x 0 < OR
        THEN x 125
MOD ABS 'x' STO
        END
CHKBOTTOM GETKEY ag   @ see if we crashed, process keys
'v' STO+ PICT SWAP    @ acceleration increases v
SHIP GXOR             @ erase old position
      UNTIL 1 FS?     @ quit if we landed or crashed
      END
    \>>

@ CHKBOTTOM is the routine that eats all the CPU time.
@ If anyone knows how to speed it up, please do so.
@ It works by calculating linear regressions and then
@ comparing the line slopes.

  CHKBOTTOM           @ set flag 1 if we crashed
    \<< 1 botCOORDS   @ get terraine coordinates list size
SIZE 1 -
      FOR i           @ test each line segment
botCOORDS i GETI 3    @ get line endpoints
ROLLD GET DUP2 1      @ duplicate them
GET SWAP 1 GET        @ get the x coordinates and
        IF x 3 + \<=  @ see if lander is between them
SWAP x 3 + > AND
        THEN OVER     @ if so, compare line slopes
C\->V2 CL\GS \GS+ C\->V2 \GS+ @ calculate line slope
LR x DUP 'CRASHx'     @ calculate and save possible
STO 3 + PREDY         @ crash x and y positions
'CRASHht' STO SWAP
DROP DUP 'CRASHsl'    @ save crash slope
STO SWAP C\->V2 CL\GS @ calculate slope of line to
\GS+ x 3.001 + ht \->V2 @ the landers coordinates
\GS+ LR SWAP DROP
          IF \>=      @ if line segment slope >= the
          THEN 1 SF   @ slope of line to lander,
 v                    @ we crahed.  Set crash flag.
'CRASHv' STO 99 'i'   @ save crash velocity
STO
          END
        ELSE DROP2    @ not within this line segment
        END
      NEXT            @ check next line
    \>>

  MAKBOTTOM           @ generates a list of coordinates
    \<< { } 0 120     @ get an empty list
      FOR a a RAND    @ generate a random y coordinate
25 * IP 6 + 2 \->LIST
1 \->LIST + 12        @ save xy in list, do next
      STEP 130 OVER   @ line up the end points so
1 GET OBJ\-> DROP     @ we don't impact on wrap
SWAP DROP 2 \->LIST 1
\->LIST + 9 RAND * IP @ insure at least one flat line
2 + GETI 2 GET 3
ROLLD GETI 2 5 ROLL
PUT SWAP 1 - SWAP
PUT 'botCOORDS' STO   @ save the list
    \>>

  DRAWBOTTOM          @ maps terraine coordinates to
    \<< 1 botCOORDS   @ screen and display the lines
SIZE 1 -
      FOR i
botCOORDS i GETI
OBJ\-> ROT R\->B ROT 63
SWAP - R\->B ROT
\->LIST 3 ROLLD GET
OBJ\-> ROT R\->B ROT 63
SWAP - R\->B ROT
\->LIST LINE
      NEXT
    \>>

  STATUS              @ displays the flight parameters
    \<<
      \<< + 1 \->GROB
PICT 3 ROLLD REPL
      \>> \-> s
      \<< { # 54h
# 0h } "Height: "
ht s EVAL { # 54h
# 6h } "VertV:  " v
s EVAL { # 54h # Ch
} "HorizV: " hv s
EVAL { # 54h # 12h
} "Fuel:   " fuel s
EVAL
      \>>
    \>>

  GETKEY              @ processes keys
    \<<
      WHILE KEY
      REPEAT
        IF fuel 0 >   @ but only if we got fuel!
        THEN
          CASE DUP
72 ==
            THEN -1
'hv' STO+ -1 'fuel'
STO+
            END DUP
74 ==
            THEN 1
'hv' STO+ -1 'fuel'
STO+
            END DUP
63 ==
            THEN
thrust DUP NEG
'fuel' STO+ 'v'
STO+
            END
          END
        END DROP
      END
    \>>

  NEWC         @ get current screen coordiantes
    \<< x R\->B 57 1 ht
57 MOD 57 / - * R\->B
2 \->LIST
    \>>

  C\->V2       @ convert 2-element list to vector
    \<< OBJ\-> DROP \->V2
    \>>

  SHIP         @ GROB of the lander
GROB 6 6 E13333E11212

  aflag        @ GROB of a flag
GROB 7 7 F7747414F71010

  thrust 2     @ vertical thrust = -1/2 ag

  ag -4        @ acceleration due to gravity

  globals { \GSDAT     @ these are PURGEd
CRASHv CRASHsl
CRASHht CRASHx \GSPAR
botCOORDS fuel x hv
v ht }

END

@ END OF ASCII FILE