


FORTH

: WHERE ." REACHED HERE " ;

0 SPEED !
FLOAD" BRKMISC"
FLOAD" HIGHTABLE"
FLOAD" SPRWORDS"
FLOAD" BRKSTRUCTS"

HEX 1000 CONSTANT SPRITE-AREA-SIZE DECIMAL
SPRITE-AREA-SIZE DEF-SPRITE-AREA SPRITE-AREA

FLOAD" WALLDEFS"
FLOAD" NUMWORDS"

FORTH

HEX
: FIND-BLOCK-BRICKS ( BLOCK -> NUM-BRICKS )
   0 SWAP
   DUP DUP BLOCK-HEIGHT @ 0 DO
      BLOCK-WIDTH @ 0 DO
         DUP DUP
         BLOCK-BRICKS SWAP BLOCK-WIDTH @
           ( NUM-BRKS / BLOCK / FIRST-BRK-ADDR / WIDTH )
         2 << J * I 2 << + + ( NUM-BRKS / BLOCK / BRK-ADDR )
         @ DUP
         80000000 AND 0= IF
            0F AND BLANK <> IF
               SWAP 1+ SWAP
            THEN
         ELSE
            DROP
         THEN
      LOOP
      DUP
   LOOP
   2DROP
   ;
DECIMAL

: FIND-WALL-BRICKS ( WALL -> NUM-BRICKS )
   0 SWAP
   >R> WALL-BLOCK-LIST @
   BEGIN
      DUP
      @ -1 = IF ( END OF LIST )
         DROP 1
      ELSE
         >R> @ FIND-BLOCK-BRICKS +
         R> BLOCK-LIST-SIZE +
         0
      THEN
   UNTIL
   R> WALL-NO-BRICKS !
   ;

HEX
: INIT-WALL-BLOCK ( BLOCK -> )
   >R> BLOCK-HEIGHT @
   R BLOCK-WIDTH @ *
   R> BLOCK-BRICKS
   SWAP 0 DO
      >R> @
      7FFFFFFF AND R FORTH !
      R> 4 +
   LOOP
   DROP
   ;
DECIMAL

: FIND-BRICK ( LIST / ELT-NO / BRICKPOSX / BRICKPOSY ->
               BOTLEFTX / BOTLEFTY / TOPRIGHTX / TOPRIGHTY / COL / FLAG )
   DUP 0 < IF
      2DROP 2DROP -1 EXIT
   THEN
   SWAP DUP 0 < IF
      2DROP 2DROP -1 EXIT
   THEN
   SWAP
   2SWAP
   BLOCK-LIST-SIZE * + ( ADDR OF ELEMENT )
   >R>
   WALL-BLOCK @ >R
   DUP
   R BLOCK-HEIGHT @
   >= IF ( BRICKPOSY >= BLOCK-HEIGHT )
      R> R> 2DROP 2DROP -1 EXIT
   THEN
   OVER
   R> BLOCK-WIDTH @
   >= IF ( BRICKPOSX >= BLOCK-WIDTH )
      R> DROP 2DROP -1 EXIT
   THEN
   R BLOCK-BOT-LEFTX @ R
   BLOCK-BOT-LEFTY @ R>
   WALL-BLOCK @ ( BRKPOSX / BRKPOSY / BLK-BLX / BLK-BLY / BLOCK ADDRESS )
   >R R
   BLOCK-XSIZE @ 5 PICK * 3 PICK + ( LOWER LEFT X OF BRICK )
   R BLOCK-YSIZE @ 5 PICK * 3 PICK + ( LOWER LEFT Y OF BRICK )
   ( BRKPOSX / BRKPOSY / BLK-BLX / BLK-BLY / BRK-BLX / BRK-BLY )
   2SWAP 2DROP
   R BLOCK-XSIZE @ 2 - 3 PICK + ( TOP RIGHT X OF BRICK )
   R BLOCK-YSIZE @ 4 - 3 PICK + ( TOP RIGHT Y OF BRICK )
   >R >R 2SWAP R> R> 2SWAP
   ( BRK-BLX / BRK-BLY / BRK-TRX / BRK-TRY / BRKPOSX / BRKPOSY )

   R BLOCK-WIDTH @ 2 << * SWAP 2 << + ( INDEX INTO BRICKS )
   R> BLOCK-BRICKS + @ 1 ( BRICK COLOUR / FLAG )
   ;

CODE RECTANGLE
   R1 [ SP 12 # ] LDR,
   R2 [ SP 8 # ] LDR,
   R0 4 # MOV,
   69 SWI,
   R0 101 # MOV,
   R1 [ SP 4 # ] LDR,
   R2 [ SP ] 16 # LDR,
   69 SWI,
   PC R14 MOV,
END-CODE
   

: DRAW-BRICK ( BRK-BLX / BRK-BLY / BRK-TRX / BRK-TRY / COL )
   11 SWAP GCOL2
   RECTANGLE
   ;

: DISPLAY-WALL ( WALL -> )
   WALL-BLOCK-LIST @ DUP
   0 SWAP
   BEGIN
      DUP ( LIST ADDR / LISTELTNO / ELT ADDR / ELT ADDR )
      WALL-BLOCK @ DUP
      -1 = IF
         DROP 1 ( FLAG SIGNIFYING END OF LOOP )
      ELSE
         DUP BLOCK-HEIGHT @ 0 DO
            DUP BLOCK-WIDTH @ 0 DO
               ( LIST ADDR / LISTELTNO / ELT ADDR / BLK ADDR)
               4 PICK
               4 PICK
               I J
               FIND-BRICK DROP
               DRAW-BRICK
            LOOP
         LOOP
         DROP ( DISPOSE OF BLOCK ADDR )
         BLOCK-LIST-SIZE + ( STEP ON TO NEXT ELEMENT )
         >R 1+ R>
         0
      THEN
   UNTIL
   2DROP DROP
   ;

: MOVE-BALL ( BALL -> FLAG )
   >R>
   BALLX @
   R BALL-INCX @
   +
   DUP
   R BALL-MAXX @ < IF
      DUP
      R BALL-MINX @ >= IF
         R BALLX !
      ELSE
         DROP
         R BALL-INCX @ NEGATE R BALL-INCX !
      THEN
   ELSE
      DROP
      R BALL-INCX @ NEGATE R BALL-INCX !
   THEN
   R BALLY @
   R BALL-INCY @
   +
   DUP
   R BALL-MAXY @ < IF
      DUP
      R BALL-MINY @ >= IF
         R BALLY !
      ELSE
         DROP
         R BALL-INCY @ NEGATE R BALL-INCY !
         R> DROP 1 EXIT
      THEN
   ELSE
      DROP
      R BALL-INCY @ NEGATE R BALL-INCY !
   THEN
   R> DROP 0
   ;

HEX
CODE WAIT-SYNC
   R0 13 # MOV,
   06 SWI,
   PC R14 MOV,
END-CODE

CODE DEFAULT-COLS
   114 SWI,
   PC R14 MOV,
END-CODE
DECIMAL


SPRITE-AREA MERGE-SPRITE' BALL

SPRITE-AREA 0 0 0 1260 1024 205 150 12 12 DEF-BALL BALL1
1 DEF-BALL-LIST BALL-LIST1
BALL1 BALL-LIST1 0 ATTACH-BALL

SPRITE-AREA MERGE-SPRITE' SMALLBAT
SPRITE-AREA 1 24 0 1279 480 100 DEF-BAT BAT2

SPRITE-AREA MERGE-SPRITE' LARGEBAT
SPRITE-AREA 2 24 0 1279 480 100 DEF-BAT BAT1

SPRITE-AREA MERGE-SPRITE' NUMBERS

HEX
CODE KEY-SCAN
   R1 POP,
   R0 81 # MOV,
   R2 FF # MOV,
   06 SWI,
   R1 R1 R2 AND,
   R1 PUSH,
   PC R14 MOV,
END-CODE
DECIMAL
FORTH

: PLOT-BAT ( BAT / GCOL -> )
   >R
   SPRITE-AREA SWAP
   >R> BAT-SPRITE-CTRL @
   R BATX @
   R> BATY @
   R>
   PUT-SPRITE
   ;

: MOVE-BAT ( BAT -> )
   >R> BATX @ R BAT-XINC @ + DUP
   R BAT-MINX @ < IF
      R> 2DROP EXIT
   ELSE
      DUP R BAT-MAXX @ > IF
         R> 2DROP EXIT
      THEN
   THEN
   R 11 PLOT-BAT ( DELETE OLD BAT )
   R BATX !
   R> 11 PLOT-BAT
   ;

: MOVE-BAT-LEFT ( BAT -> )
   >R> BAT-XINC @
   ABS NEGATE R BAT-XINC ! R>
   MOVE-BAT
   ;

: MOVE-BAT-RIGHT ( BAT -> )
   >R> BAT-XINC @
   ABS R BAT-XINC ! R>
   MOVE-BAT
   ;

-98 CONSTANT LEFT-KEY ( Z )
-67 CONSTANT RIGHT-KEY ( X )
-114 CONSTANT PAUSE-KEY ( F1 )
-99 CONSTANT RESTART-KEY ( SPACE-BAR )
-17 CONSTANT QUIT-KEY ( Q )

HEX
: CHECK-QUIT
   QUIT-KEY KEY-SCAN
   FF =
   ;

: CHECK-RESTART
   RESTART-KEY KEY-SCAN
   FF =
   ;

: CHECK-PAUSE
   PAUSE-KEY KEY-SCAN
   FF = IF
      BEGIN
         PAUSE-KEY KEY-SCAN
         FF <>
      UNTIL ( KEY RISES )
      BEGIN
         PAUSE-KEY KEY-SCAN
         FF =
      UNTIL ( KEY IS DEPRESSED )
      BEGIN
         PAUSE-KEY KEY-SCAN
         FF <>
      UNTIL ( KEY RISES )
    THEN
    ;
DECIMAL

: AUTO-MOVE-BAT ( BAT / BALL -> )
   2DUP BALLX @ SWAP BATX @ <
   IF
      DROP MOVE-BAT-LEFT
   ELSE
      >R> BALLX @ R> BALL-WIDTH @ + ( RIGHT BALL X )
      SWAP >R> BATX @ R BAT-WIDTH @ + > IF
         R> MOVE-BAT-RIGHT
      ELSE
         R> DROP ( NO MOVE )
      THEN
   THEN
   ;

HEX
: CHECK-MOVE-BAT ( BAT -> )
   LEFT-KEY KEY-SCAN
   FF = IF
      MOVE-BAT-LEFT
   ELSE
      RIGHT-KEY KEY-SCAN
      FF = IF
         MOVE-BAT-RIGHT
      ELSE
         DROP
      THEN
   THEN
   ;
DECIMAL

: PLOT-BALL ( BALL / GCOL -> )
   >R
   SPRITE-AREA SWAP
   >R> BALL-SPRITE-CTRL @
   R BALLX @
   R> BALLY @
   R> ( RETRIEVE GCOL )
   PUT-SPRITE
   ;

HEX
CODE READ-POINT
   R1 POP,
   R0 POP,
   32 SWI,
   R2 PUSH,
   PC R14 MOV,
END-CODE
DECIMAL
FORTH

: ERASE-BRICK ( BRK-POSX / BRK-POSY / LIST / ELT-NO -> BRICK-INFO )
   BLOCK-SIZE * +
   WALL-BLOCK @ >R>
   BLOCK-WIDTH @ 2 << *
   R> BLOCK-BRICKS +
   SWAP 2 << +
   DUP @ >R>
   [ HEX ] 80000000 OR SWAP FORTH ! [ DECIMAL ]
   R>
   ;

: DETECT-COLLISION ( BALL -> FLAG / X / Y )
   >R>
   BALLX @ R BALL-WIDTH @ +
   R BALLY @ R BALL-HEIGHT @ 1 >> + ( BOTTOM POINT )
   2DUP READ-POINT
   R BALL-CENTRE-COL @
   - -DUP IF
      R> DROP EXIT
   THEN
   R BALL-HEIGHT @ + ( TOP POINT )
   2DUP READ-POINT
   R BALL-CENTRE-COL @
   - -DUP IF
      R> DROP EXIT
   THEN
   R BALL-HEIGHT @ 1 >> -
   SWAP R BALL-WIDTH @ 1 >> - SWAP ( LEFT POINT )
   2DUP READ-POINT
   R BALL-CENTRE-COL @
   - -DUP IF
      R> DROP EXIT
   THEN
   SWAP R BALL-WIDTH @ + SWAP ( RIGHT POINT )
   2DUP READ-POINT
   R> BALL-CENTRE-COL @
   -
   ;

: RAND-DIRECTION ( BALL -> )
   >R 6 RANDOM 1 << 8 +
   R BALL-INCX @ 0 < IF
      NEGATE ( RANDOM NUMBER )
   THEN
   R BALL-INCX !
   3 RANDOM 2 << 12 +
   R BALL-INCY @ 0 < IF
      NEGATE
   THEN
   R> BALL-INCY !
   ;

: FLIP-BALLY ( DIR / BALL -> )
   >R> BALL-INCY @ NEGATE
   R BALL-INCY !
   1 AND IF
      R> RAND-DIRECTION
   ELSE
      R> DROP
   THEN
   ;

: FLIP-BALLX ( DIR / BALL -> )
   >R> BALL-INCX @ NEGATE
   R BALL-INCX !
   1 AND IF
      R> RAND-DIRECTION
   ELSE
      R> DROP
   THEN
   ;

HEX
: UP-RIGHT-CHANGE
   ( X / Y / XBRK-POS / YBRK-POS / BLOCK-LIST / ELT-NO / DIR / BALL -> )
   >R >R 2SWAP 2OVER 2OVER SWAP 1- SWAP FIND-BRICK -1 <> IF
      80000000 AND IF
         2DROP 2DROP
      ELSE
         2DROP 2DROP
         R> R> FLIP-BALLY
         2DROP 2DROP 2DROP
         EXIT
      THEN
   THEN
   FIND-BRICK
   2DROP 2DROP ( X / Y / BRK-BLX / BRK-BLY )
   >R SWAP R> ( X / BRK-BLX / Y / BRK-BLY )
   - >R - R> ( X - BRK-BLX / Y - BRK-BLY )
   < IF
      R> R> FLIP-BALLX
   ELSE
      R> R> FLIP-BALLY
   THEN
   ;

: DOWN-RIGHT-CHANGE
   ( X / Y / XBRK-POS / YBRK-POS / BLOCK-LIST / ELT-NO / DIR / BALL -> )
   >R >R 2SWAP 2OVER 2OVER SWAP 1- SWAP FIND-BRICK -1 <> IF
      80000000 AND IF
         2DROP 2DROP
      ELSE
         2DROP 2DROP
         R> R> FLIP-BALLY
         2DROP 2DROP 2DROP
         EXIT
      THEN
   THEN
   FIND-BRICK
   2DROP ( X / Y / BRK-BLX / BRK-BLY / BRK-TRX / BRK-TRY )
   SWAP DROP SWAP DROP ( X / Y / BRK-BLX / BRK-TRY )
   >R SWAP R> SWAP ( X / BRK-BLX / BRK-TRY / Y )
   - >R - R>
   < IF
      R> R> FLIP-BALLX
   ELSE
      R> R> FLIP-BALLY
   THEN
   ;

: UP-LEFT-CHANGE
   ( X / Y / XBRK-POS / YBRK-POS / BLOCK-LIST / ELT-NO / DIR / BALL -> )
   >R >R 2SWAP 2OVER 2OVER SWAP 1+ SWAP FIND-BRICK -1 <> IF
      80000000 AND IF
         2DROP 2DROP
      ELSE
         2DROP 2DROP
         R> R> FLIP-BALLY
         2DROP 2DROP 2DROP
         EXIT
      THEN
   THEN
   FIND-BRICK
   2DROP
   DROP ROT DROP ( X / Y / BRK-BLY / BRK-TRX )
   >R - SWAP R> - NEGATE ( Y - BRK-BLY / BRK-TRX - X )
   < IF
      R> R> FLIP-BALLY
   ELSE
      R> R> FLIP-BALLX
   THEN
   ;

: DOWN-LEFT-CHANGE
   ( X / Y / XBRK-POS / YBRK-POS / BLOCK-LIST / ELT-NO / DIR / BALL -> )
   >R >R 2SWAP 2OVER 2OVER SWAP 1+ SWAP FIND-BRICK -1 <> IF
      80000000 AND IF
         2DROP 2DROP
      ELSE
         2DROP 2DROP
         R> R> FLIP-BALLY
         2DROP 2DROP 2DROP
         EXIT
      THEN
   THEN
   FIND-BRICK
   2DROP
   2SWAP 2DROP ( X / Y / BLK-TRX / BLK-TRY )
   ROT - ( X / BLK-TRX / BLK-TRY - Y )
   >R SWAP - R> ( BLK-TRX - X / BLK-TRY - Y )
   > IF
      R> R> FLIP-BALLY
   ELSE
      R> R> FLIP-BALLX
   THEN
   ;
DECIMAL

HEX
: CHANGE-BALL-DIRECTION
 ( X / Y / XBRK-POS / YBRK-POS / BLOCK-LIST / ELT-NO / DIR-FLAG / BALL -> )
   >R> BALL-INCX @
   R BALL-INCY @
   XOR 80000000 AND 0= IF
      R BALL-INCX @ 0 >= IF
         R> UP-RIGHT-CHANGE
      ELSE
         R> DOWN-LEFT-CHANGE
      THEN
   ELSE
      R BALL-INCX @ 0 >= IF
         R> DOWN-RIGHT-CHANGE
      ELSE
         R> UP-LEFT-CHANGE
      THEN
   THEN
   ;
DECIMAL

: CHECK-BLOCK ( X / Y / BLK-BOT-LEFTX / BLK-BOT-LEFTY / WALL-BLOCK -> FLAG )
   >R
   SWAP 4 PICK - NEGATE ( X - BLK-BOT-LEFTX )
   DUP 0< IF
      R> DROP
      2DROP
      0 EXIT
   THEN
   R BLOCK-XSIZE @ / ( X / Y / BLK-BOT-LEFTY / X-BRICK-OFFSET )
   DUP R BLOCK-WIDTH @ >= IF
      R> DROP
      2DROP
      0 EXIT
   THEN
   3 PICK ROT - ( Y - BLK-BOT-LEFTY )
   DUP 0< IF
      R> DROP
      2DROP
      0 EXIT
   THEN
   R BLOCK-YSIZE @ / ( X / Y / X-BRICK-OFFSET / Y-BRICK-OFFSET )
   DUP R BLOCK-HEIGHT @ >= IF
      R> DROP
      2DROP
      0 EXIT
   THEN ( HAVE FOUND BRICK POSITION )
   R> DROP
   1
   ;

: FIND-COLLIDED-BRICK ( X / Y / WALL -> FLAG )
( IF FLAG = 1 THEN STACK = X / Y / XBRK-POS / YBRK-POS / ELT-NO / SCORE )
   WALL-BLOCK-LIST @ >R> ( SAVE ADDRESS OF FIRST ELT OF LIST )
   0 >R ( SAVE LIST ELT NO )
   >R ( SAVE CURRENT LIST ELT ADDRESS )
   BEGIN
      R BLOCK-BOT-LEFTX @
      R BLOCK-BOT-LEFTY @
      R> WALL-BLOCK @
      CHECK-BLOCK
      IF ( FOUND BRICK )
         2DUP
         R> ( RESTORE ELT NO )
         R ( ADDRESS OF FIRST ELT OF LIST )
         SWAP >R>
    ( X / Y / XBRK-OFF / YBRK-OFF / XBRK-OFF / YBRK-OFF / LIST / ELT-NO )

         2SWAP
         FIND-BRICK DROP
         DUP [ HEX ] 80000000 [ DECIMAL ] AND IF ( BLANK SPACE )
            R> R> 11 NDROP
            2 ( BRICK ALREADY DELETED )
         ELSE
            15 AND
            DRAW-BRICK
            2DUP R> R> SWAP >R>
            ERASE-BRICK
            R> SWAP
            1 ( DELETED BRICK )
         THEN
         EXIT
      THEN
      R> 1+ ( INCREMENT LIST ELT NO )
      DUP BLOCK-LIST-SIZE * R +
      SWAP >R ( ELT NO )
      >R> ( ADDRESS OF NEXT ELT )
      @ -1 = IF
         R> R> R> 2DROP 2DROP DROP
         0
         EXIT
      THEN
   AGAIN
   ;

: CHECK-BAT-HIT ( BALL / X / Y / BAT -> FLAG )
   >R DUP R BATY @ >= IF
      R BATY @ R BAT-HEIGHT @ + <= IF
         DUP R BATX @ >= IF
            R BATX @ R BAT-WIDTH @ + <= IF
               0 SWAP FLIP-BALLY R> DROP 1 EXIT
            ELSE
               R> 2DROP
            THEN
         ELSE
            R> 2DROP DROP
         THEN
      ELSE
         R> 2DROP DROP
      THEN
   ELSE
      R> 2DROP 2DROP
   THEN
   0
   ;

: BOUNCE-BALL ( BALL / BAT -> )
   >R
   BEGIN
      WAIT-SYNC
      DUP DUP 11 PLOT-BALL
      MOVE-BALL DROP
      DUP DUP 11 PLOT-BALL
      R BATY @ R BAT-HEIGHT @ +
      SWAP BALLY @ <
   UNTIL
   R> 2DROP
   ;

HEX
CODE FLUSH-KEYBOARD
   R1 1 # MOV,
   R0 0F # MOV,
   06 SWI,
   PC R14 MOV,
END-CODE
DECIMAL
FORTH

: INIT-BALL-POS ( BALL -> )
   >R 256 RANDOM 2 << R BALLX !
   150 R BALLY !
   R BALL-INCY @ ABS R> BALL-INCY !
   ;

20 CONSTANT SCORE-X
950 CONSTANT SCORE-Y
0 VARIABLE SCORE

: UPDATE-SCORE
   SCORE +!
   SCORE-X SCORE-Y SCORE @ 1 PRINT-NUMBER
   ;

: INIT-SCORE
   0 SCORE !
   0 UPDATE-SCORE
   ;

: SET-UP-SCREEN
   NOWIMPS
   12 MODE
   INIT-PALETTE
   ;

1200 CONSTANT LIVES-X
950 CONSTANT LIVES-Y
5 VARIABLE LIVES

: UPDATE-LIVES ( -> LIVES )
   -1 LIVES +!
   LIVES-X LIVES-Y LIVES @ PRINT-DIGIT 2DROP
   LIVES @
   ;

: INIT-LIVES
   6 LIVES !
   UPDATE-LIVES
   DROP
   ;

0 VARIABLE CURRENT-WALL

5 CONSTANT MAX-WALLS

: ARRAY
   <BUILDS
      2 << ALLOT
   DOES>
   ;

MAX-WALLS ARRAY WALL-TABLE

2 VARIABLE SCREEN-NUM

0 VARIABLE AUTOPLAY

: FIRST-SCREEN
   2 SCREEN-NUM !
   CLS
   AUTOPLAY @ IF
      PRINTHIGHTABLE
   ELSE
   THEN
   ;

: SELECT-WALL
   WALL-TABLE SCREEN-NUM @ MAX-WALLS /MOD DROP 2 << +
   @ CURRENT-WALL !
   ;

: INIT-WALL-TABLE
   WALL1 WALL-TABLE !
   WALL2 WALL-TABLE 4 + !
   WALL3 WALL-TABLE 8 + !
   WALL4 WALL-TABLE 12 + !
   WALL5 WALL-TABLE 16 + !
   ;

: CUR-WALL
   CURRENT-WALL @
   ;


: ONE-SCREEN
   SELECT-WALL
   CUR-WALL WALL-BLOCK-LIST @
   WALL-BLOCK @
   INIT-WALL-BLOCK
   CUR-WALL FIND-WALL-BRICKS
   CUR-WALL DISPLAY-WALL
   BALL1 INIT-BALL-POS
   BALL1 11 PLOT-BALL
   BAT1 11 PLOT-BAT
   BEGIN
      CHECK-PAUSE
      WAIT-SYNC
      AUTOPLAY @ IF
         BAT1 BALL1 AUTO-MOVE-BAT
      ELSE
         BAT1 CHECK-MOVE-BAT
      THEN
      BALL1 11 PLOT-BALL
      BALL1 MOVE-BALL
      IF ( LOST BALL )
         1000000 0 DO LOOP
         UPDATE-LIVES
         0= IF
            2 DUP ( END GAME FLAG )
         ELSE
            BALL1 >R
            R INIT-BALL-POS
            R BALL-INCY @ ABS R BALL-INCY !
            R> 11 PLOT-BALL
            0
         THEN
      ELSE
         BALL1 11 PLOT-BALL
         BALL1 DETECT-COLLISION
         IF
            2DUP ( X, Y COLLISION POINT )
            >R >R BALL1 R> R> BAT1 CHECK-BAT-HIT
            IF
               2DROP
               BALL1 BAT1 BOUNCE-BALL
               0
            ELSE
               CUR-WALL FIND-COLLIDED-BRICK
               1 = IF
                  DUP 18 >>
                  UPDATE-SCORE
                  5 >> 3 AND
                  CUR-WALL WALL-BLOCK-LIST @
                  ROT ROT
                  BALL1 CHANGE-BALL-DIRECTION
                  CUR-WALL WALL-NO-BRICKS @
                  1- DUP CUR-WALL WALL-NO-BRICKS !
                  IF
                     0
                  ELSE
                     3 DUP ( SCREEN CLEARED )
                  THEN
               ELSE
                  0
               THEN
            THEN
         ELSE
            2DROP
            0
         THEN
      THEN
      DUP 0= IF
         AUTOPLAY @ IF
            CHECK-QUIT IF
               DROP 5 DUP
            ELSE
               CHECK-RESTART IF
                  DROP 4 DUP
               ELSE
               THEN
            THEN
         ELSE
         THEN
      ELSE
      THEN
   UNTIL
   ;

: IND
   10 SPACES
   ;

: INTRO-TEXT
   12 EMIT CR CR
   20 SPACES ." BREAKOUT" CR
   20 SPACES ." --------" CR
   CR
   IND ." This is a demonstration of a Breakout Game" CR
   IND ." which has been created using the ARMForth" CR
   IND ." Forth compiler written by Rob Turner" CR
   IND ." It is an example of a standalone program" CR
   IND ." which is entirely ARMForth-produced" CR
   IND ." machine code. The game is by no means" CR
   IND ." completed yet!" CR CR
   IND ." Use the Z and X keys to move the bat." CR
   CR CR
   IND ." Press any key to start game" CR CR
   ;

: SHOWHIGHTABLE
   9 MODE
   SCORE @ UPDATEHIGHTABLE
   CLS PRINTHIGHTABLE
   ;

: CURSOR-OFF
   0 0 0 0 0 0 32 10 0 23
   10 0 DO VDU1 LOOP
   ;

: TEST
   WIMPS
   INTRO-TEXT
   KEY DROP
   0 AUTOPLAY !
   SET-UP-SCREEN
   BEGIN
      CURSOR-OFF
      FIRST-SCREEN
      INIT-WALL-TABLE
      INIT-SCORE
      INIT-LIVES
      BEGIN
         ONE-SCREEN
         DUP
         2 = IF
            1 AUTOPLAY !
            PRINTHIGHTABLE
         ELSE
            DUP 5 = IF ( QUIT )
               DROP WIMPS FLUSH-KEYBOARD
               EXIT
            ELSE
               DUP 4 = IF ( RESTART GAME )
                  0 AUTOPLAY !
               ELSE
                  3 = IF
                     1000000 0 DO LOOP
                     BALL1 11 PLOT-BALL
                     BAT1 11 PLOT-BAT
                     1 SCREEN-NUM +!
                     0
                  THEN
               THEN
            THEN
         THEN
      UNTIL
      FLUSH-KEYBOARD
(      SHOWHIGHTABLE )
(      KEY DROP )
(      WIMPS )
   AGAIN
   ;

