

 ( This software is freely provided for your entertainment and help.

   Please use it for any purposes which you wish, and incorporate any parts
   which you find useful into your own programs.

   Instead of the usual simple "single function" example, we have here
   given you a fairly long program which, although it is primitive, does
   at least give you working examples of many commonly used functions.

   This source code shows methods of getting user input, outputting text
   and simple graphics, and generally getting your feet wet in the muddy
   waters of some fairly messy code!  And, yes....some of this code shows
   you how not to do things too.....

   The demo uses admittedly simple and crude programming techniques to
   demonstrate simple text output.  In fact it does nothing much else but
   present a lot of simple text screens with a few fractal demos thrown
   in to alleviate the boredom!

   It would have been much better to use nicely drawn line and bevel boxes
   to make the displays more professional and attractive looking, and this
   actually would not be hard to do.  However, we wanted to keep things
   really simple and emphasise the basic text commands rather than make
   the code more complex.

   In fact you will find that all the demo code is quite simple except for
   some of the fractal routines.

   The fractal code is not sophisticated but may prove incomprehensible
   if you haven't seen this type of thing before.  We recommand that you
   don't waste time trying to follow this code unless you are really a
   great fractal enthusiast.

   Really the fractals are an excuse to use a variety of text displays,
   and we don't recommend that you try to re-use the fractal code itself,
   which is not intended as tutorial material.

   The real point of this demo is to show how you can get a useable piece
   of software of reasonable length running without complication, and show
   how to output simple text and get user keyboard input.

   Every routine has been kept at a fairly elementary and obvious level,
   sacrificing elegance, cleverness, or speed in an effort to make the code
   fairly comprehensible and clear.  You might like to try, as an exercise,
   improving some of this code and writing your own faster and more elegant
   version.  Certainly you should not assume that the way things are done
   here is the only or best way.

   Various different methods are employed to do the same job in different
   parts of the code, simply to give you an idea of the options available.
   For example, cursor positioning and text formatting can be carried out
   in many different ways, and in many cases it doesn't really matter how
   you choose to do it.

   Note that all text has been stored in the dictionary, which is lazy and
   wasteful of dictionary space, but nice and simple!  A more serious text
   generating program would store the text in external memory, leaving the
   dictionary uncluttered.

   The first section demonstrates how easy it is to format text output
   using the HeliOS stream system, and lots of different streams are used
   throughout to give you some experience of using them.

   Actually, you could write this simple program using only one stream.....

   If you don't know where to start looking through a long-ish program
   like this, then go first to the end of the file, where you will find
   the main program control words.

   In general, in HeliOS, you write all the sub-routines and subsidiary
   words first, then call them later in the more "high-level" routines.
   This means that HeliOS programs tend to start with a number of small
   "utility" word definitions, which in turn are used to build all the main
   working components of the program.  Finally the whole thing is brought
   together at the very end of the code by words which define the highest
   level of the overall program structure.  In other words, HeliOS programs
   exhibit a sort of pyramidal or hierarchical structure, with the "command
   and control centre" at the end of the source code.

   This means that if you want an overview of any HeliOS program you should
   go to the end first.  If you want to inspect the small "nuts and bolts"
   routines you should look, in general, at the start of the program.

   Note that the final thing in most HeliOS programs is a single word which
   invokes the main program definition word.  In the present case the last
   thing in the program is the word "Demo", which runs the demo main control
   routine.

   The placement of the main command word "Demo" at the end of the program
   means that once you have compiled this code it will run automatically.

   Subsequently, if you wish, you can re-run the program by typing its main
   control word "Demo" at the command line (or in a program of course).

   You could omit the final word "Demo" in this program, and if you did so
   you would find that the program would compile without auto-running.  You
   would then need to type the word "Demo" at the command line to run the
   program.

   Considering source code format and style, note that plenty of blank
   lines can be employed to space out your code and make it less cluttered.
   Because all trailing spaces are suppressed when lines of text are stored,
   each blank line only takes up one byte of memory and file space.

   Some of the code in this demo is very untidy, and you will notice that
   the badly laid out code is unreadable and therefore harder to debug and
   maintain.  You will see that short, self contained, sections of code are
   easiest to read and become almost self explanatory, because you can take
   in the whole of the logical structure on one page.

   Sometimes it is reasonable to create long word definitions for simple
   sequential operations which contain no program flow control logic, since
   these are fairly clear to read anyway.  In general, though, you should
   always confine tricky bits of logic, or any code defining individual
   functional units, to short self-contained word definitions.

   If you do this you will find that it is easy to change these "units"
   without in any way compromising the main program logic.  Notice also
   that all small functional "units" of code should have "stack diagrams"
   telling you exactly how they interact with the main program when they
   are "called".  In a language such as HeliOS which uses the stack for
   parameter passing it is important to always make absolutely clear just
   what is happening to the stack when each word executes.

   Look at the word "TEXTDEMO" for an example of horrible code, and look
   at "DEMOCOLOURS" for an example of fairly neat and readable code.  Make
   your own judgments as to which is best.........

   Notice that throughout this program we have used upper case characters
   for word names.  This is not essential, and in fact you can define a
   word in one case (or mixed case) and then call it with characters in
   either upper or lower case.

   In this program we used upper case for commands so that your eye could
   easily pick out the command words from all the text and commentary.
   This can sometimes be useful, but on other occasions it might be useful
   to have CORE words in upper case and ones you have defined yourself in
   mixed case.  Really this is simply a matter of what you think looks best
   and is easiest to read, so try out various combinations until you feel
   comfortable that your code is easy to read.

   Note that we have sometimes used "indenting" to make structured sections
   of code such as DO-LOOP and BEGIN-UNTIL constructs more readable.  In
   general this is a very good idea, and if you compare the word "RAYS"
   with the word "TURNWINDOW" you will perhaps see what we mean.

   Finally, you might be interested that the Mandelbrot generator uses a
   tiny fragment of assembler code, just to give you a taste of how this
   is done in HeliOS.

   *******
   WARNING
   *******

   This code makes extensive use of comments, which is always a good idea.

   However you MUST BE CAREFUL of one or two things which sometimes cause
   problems with HeliOS comments:

   1.  You MUST include spaces before AND after "(" (comment start) symbols.

   2.  You MUST include spaces before AND after ")" (comment end) symbols.

   3.  You MUST include spaces before AND after "\" (line comment) symbols.

   4.  Be careful not to mis-type a "/" (divide) character instead of a "\".

   5.  You can use "(" and ")" brackets within comments delimited by these
       same characters, but if you do so you must NOT use spaces around the
       brackets WITHIN the comment.

   6. If you get strange compile errors with "Word not found" etc., always
      check for mistakes in your comment markers.

   Look at the way this comment is written as an example. )

 \ ---------------------------------------------------------------------------

   ( First clear dictionary down to core vocabulary )

   FORGET **CORE**

 \ ---------------------------------------------------------------------------

   ( Load and compile ASSEMBLER vocabulary for later use )

   RUN Helios:Assembler

 \ ----------------------------------------------------------------------------

   ( Next make new definitions of some non-time-critical words which
     are used frequently in the Demo.

     This is not really necessary in this particular case, but is
     included simply to demonstrate the technique.

     Here we are making simple "compound" words to use instead of
     continually making multiple repeated use of the one word "CR".

     In this way we:

      1. Save compile time  as the compiler will not have to search
         deep in the dictionary for the word "CR" all the time.

      2. Make our source code shorter and less cluttered with "CR"s.

     There is a small execution time penalty, but this is unimportant. )

   : 1CR  CR ;                    \ Redefine Carriage Return

   : 2CR  1CR 1CR ;               \ 2 CRs

   : 3CR  2CR 1CR  ;              \ 3 CRs

   : 4CR  2CR 2CR ;               \ 4 CRs

 \ ----------------------------------------------------------------------------

   ( A word to clear the two pixel lines above the start of the text area
     in the HeliOS main display.  This does not get cleared by the console
     text window SCRCLR routine because the console window starts two pixels
     below the start of the window. )

   : CLEARWINDOWTOP    ( Colour - - - )

   GFXSETAPEN                       \ Set drawing pen from stack value
   0 0  GFXORIGIN                   \ Set drawing origin to top left corner
   4 13 GFXMOVE 635 13 GFXDRAW      \ Draw horizontal line at pixel 13
   4 14 GFXMOVE 635 14 GFXDRAW      \ Draw horizontal line at pixel 14
   ;

 \ ---------------------------------------------------------------------------

   ( A word to clear up and quit the demo )

   : DEMOQUIT     ( - - - )

   RESETCOLOURS                          \ Restore HeliOS colour defaults

   SP!                                   \ Clear Stack

   INITFSTREAMS FSTATUS                  \ Remake HeliOS display

   2 STREAM                              \ Enter main display area stream

   6 6 CURPUT

   ." This is the end....hope you've had fun...."

   6 8 CURPUT 6 FPENSET

   ." Press any key to finally exit."

   KEY DROP                              \ Wait for response

   SCRCLR                                \ Clear display

   QUIT                                  \ Quit
   ;

 \ ----------------------------------------------------------------------------

   ( A simple word which we shall use to permit the user to control
     progress through the demo )

   : WAIT              ( - - - )

   6 FPENSET

   ."  Press <SPACE> or L-Mouse to continue..."

   BEGIN                                \ Wait for any previous key
     ?TERMINAL 0=                       \ press to be released
   UNTIL

   WAITSPACE                            \ Wait for <SPACE> to be pressed
   ;

 \ ----------------------------------------------------------------------------

   ( A bit of demonstration text )

   : DEMOTEXT          ( - - - )

   ." This is a HeliOS demonstration........"
   ;

 \ ----------------------------------------------------------------------------

   ( A bit of demonstration text repeated 60 times with 1/50 second delay )

   : DEMOTEXT1         ( - - - )

   60 0
   DO
     DEMOTEXT
     1 DELAY
   LOOP
   ;

 \ ----------------------------------------------------------------------------

   ( A bit of demonstration text output 50 times to 3 different streams )

   : DEMOTEXT2         ( - - - )

   50 0
   DO
     6 STREAM   DEMOTEXT
     7 STREAM   DEMOTEXT
     8 STREAM   DEMOTEXT
   LOOP ;

 \ ----------------------------------------------------------------------------

 ( A simple graphical display of a pulsating HeliOS sun logo, with
   a subsidiary word RAYS first which generates the radiating pattern

   Note that you could replace the repeating code

   DDUP  2/ SWAP 2/ SWAP      GFXMOVE  GFXDRAW

   with a single word defined to take its place.

   Normally you would probably do this to make your code more compact
   and readable. )


   : RAYS              ( colour1 colour2 - - - colour1 colour2 )

   45 0 DO

   OVER   GFXSETAPEN                                 \ Set Colour1

   150 I 3 LSL     GFXSIN 32767 */  DUP  NEGATE      \ X-Coords
   75  I 3 LSL     GFXCOS 32767 */  TUCK NEGATE      \ Y-Coords

   DDUP  2/ SWAP 2/ SWAP      GFXMOVE  GFXDRAW       \ Draw negative ray
   DDUP  2/ SWAP 2/ SWAP      GFXMOVE  GFXDRAW       \ Draw positive ray

   DUP   GFXSETAPEN                                  \ set Colour2

   180 I 3 LSL 2+  GFXSIN 32767 */  DUP  NEGATE      \ Draw longer rays
   90  I 3 LSL 2+  GFXCOS 32767 */  TUCK NEGATE

   DDUP  2/ SWAP 2/ SWAP      GFXMOVE  GFXDRAW
   DDUP  2/ SWAP 2/ SWAP      GFXMOVE  GFXDRAW

   LOOP  ;


   : HELIOS            ( - - - )

   BEGIN                                          \ Wait for any previous key
     ?TERMINAL 0=                                 \ press to be released
   UNTIL

   STREAMNO                                       \ Get current Stream

   0 DUP INITSTREAM STREAM                        \ Init/Enter 0 Stream

   2 BPENSET                                      \ Set Colour 2 background

   CUROFF 0 STREAM SCRCLR                         \ Set up display

   2 CLEARWINDOWTOP                               \ Clear top of window

   7 GFXSETAPEN                                   \ Set Colour 7

   316 120 DDUP GFXORIGIN                         \ Set GFX Origin

   68 34  GFXAREAELLIPSE    GFXAREAEND            \ Draw Disk

   37 13 CURPUT 6 FPENSET 7 BPENSET   ." HeliOS"  \ Write Text
   38 14 CURPUT 6 FPENSET 7 BPENSET   ." text"
   38 15 CURPUT 6 FPENSET 7 BPENSET   ." demo!"

   3  26 CURPUT 1 FPENSET 2 BPENSET ." Press <SPACE> to continue..."

   53 26 CURPUT ." Press <Q> to quit Demo."

   6 7                                            \ Colours for RAYS

   BEGIN                                          \ Start loop

     RAYS                                         \ Display Rays

     SWAP                                         \ Alternate colours

     ?TERMINAL DUP KEYLCASE ASCII q =
     IF
       DEMOQUIT
     THEN                                         \ ? QUIT

     32 =
   UNTIL                                          \ Loop until <Space>

   25 DELAY                                       \ 1/2 second delay

   DDROP                                          \ Drop colours

   0 INITSTREAM                                   \ Reset 0 stream

   STREAM  ;                                      \ Restore start stream

 \ ----------------------------------------------------------------------------

   ( Start of demo ...... Clear screen and output initial message )

   : INTRO

   0 DUP INITSTREAM STREAM CUROFF   \ Enter and initialise 0 Stream

   2 BPENSET                        \ Text background 2 for screen clearing

   SCRCLR                           \ Clear screen

   4 3 CURPUT                       \ Set cursor etc etc

   ." HeliOS has been exclusively developed on the Amiga with the intention "

   4 4 CURPUT

   ." of providing a high performance programming language which is both"

   4 5 CURPUT

   ." easy to learn and comprehensive in scope."

   4 7 CURPUT

   ." HeliOS is a very fast and efficient programming language, explicitly"

   4 8 CURPUT

   ." designed for the Amiga, with an integrated graphical user interface."

   4 10 CURPUT

   ." All critical parts of HeliOS are written in machine code for maximum"

   4 11 CURPUT

   ." speed and power, giving performance equal to any Amiga application."

   4 13 CURPUT

   ." HeliOS has a unique Interactive mode which allows ideal freedom to"

   4 14 CURPUT

   ." creative programmers who enjoy experimentation at the keyboard."

   4 16 CURPUT

   ." HeliOS has an excellent user interface with integrated editor, debugger,"

   4 17 CURPUT

   ." compiler, and interactive interpreter for ultra rapid program development."

   4 19  CURPUT

   ." HeliOS is more powerful, and easier to use, than C, Basic, or assembler."

   4 21  CURPUT

   ." This program will show you a few simple HeliOS text handling and graphic"

   4 22  CURPUT

   ." drawing functions, and provides an easy-to-follow source code example."

   4 24  CURPUT

   ." You can freely modify the source code to create your own simple Demo."

   3 27  CURPUT

   WAIT
   ;

 \ ----------------------------------------------------------------------------

 ( A small colour selection word, DEMOCOLOURS, with a few subsidiary words.

   Notice how this code is broken down into simple functional sub-units. )

   0   VARIABLE   RED
   0   VARIABLE   BLUE
   0   VARIABLE   GREEN
   0   VARIABLE   PEN
   0   VARIABLE   NUMCOLS

   FIND  NOOP   VARIABLE   EXTERNAL

   : SETCOLS      ( - - - )       \ Set RGB values

   PEN @
   RED @
   GREEN @
   BLUE @

   GFXSETRGB
   ;

   : GETCOLS      ( - - - )       \ Get RGB values

   PEN @
   GFXGETRGB

   BLUE !
   GREEN !
   RED !
   ;

   : SHOWCOLOUR    ( - - - )      \ Display Colour Values

   CURREAD                        \ Get cursor position on stack

   25 CURFW CURSAVE   PEN   ?     \ Output colour values
   CURSET    1 CURDN  RED   ?
   CURSET    2 CURDN  GREEN ?
   CURSET    3 CURDN  BLUE  ?

   CURPOS                         \ Restore stored cursor position
   ;

   : USERCOLOUR    ( c - - - c )  \ Translate user input

   ASCII c OVER=                  \ Was "c" pressed?
   IF
     PEN NUMCOLS @ CYCLE
     GETCOLS
   ELSE
     ASCII x OVER=                \ Was "x" pressed
     IF
       RESETCOLOURS
       GETCOLS
     ELSE
       ASCII r OVER=              \ Was "r" pressed
       IF
         RED 16 CYCLE
       ELSE
         ASCII g  OVER=           \ Was "g" pressed
         IF
           GREEN 16 CYCLE
         ELSE
           ASCII b  OVER=         \ Was "b" pressed
           IF
             BLUE 16 CYCLE
           THEN
         THEN
       THEN
     THEN
   THEN
   ;

   : DEMOCOLOURS       ( Number-of-colours - - - )

   NUMCOLS !                        \ Store number of colours

   PEN 0!                           \ Set pen to zero

   CURSTAT                          \ Check Cursor status and save on stack

   CUROFF                           \ Set up and display text

   CURSAVE            ."  COLOUR BEING ADJUSTED =    "
   CURSET 1 CURDN     ."  RED   COMPONENT       =    "
   CURSET 2 CURDN     ."  GREEN COMPONENT       =    "
   CURSET 3 CURDN     ."  BLUE  COMPONENT       =    "
   CURSET

   GETCOLS                          \ Update colour variables

   SHOWCOLOUR                       \ Display values

   BEGIN                            \ Begin loop

     KEY  KEYLCASE                  \ Get a key and translate case

     USERCOLOUR                     \ Check user input

     SETCOLS                        \ Set display colours

     SHOWCOLOUR                     \ Display new values

     EXTERNAL @EXECUTE              \ Execute subsidiary word

     32 =

   UNTIL                            \ Loop until <Space> pressed

   RESETCOLOURS                     \ Restore HeliOS default colours

   IF                               \ Check cursor status on stack
     CURON                          \ Restore cursor status
   THEN
   ;


 \ ----------------------------------------------------------------------------

 ( Set up 3 text streams )

   : INIT3STREAMS  ( - - - )

   1 STREAM     1 1  80 5  SCRWIN     0 BPENSET 3 FPENSET  CUROFF SCRCLR
   2 STREAM     1 6  80 20 SCRWIN     7 BPENSET 1 FPENSET  CUROFF SCRCLR
   3 STREAM     1 26 80 5  SCRWIN     2 BPENSET 6 FPENSET  CUROFF SCRCLR
   ;

 \ ----------------------------------------------------------------------------

 ( A short text stream demonstration - of how NOT to do it!.

   The style of this code is not good, because runs to quite a length
   of in-line code which is relatively unreadable and awkward to maintain.

   This code section is around 350 lines long!

   Old fashioned programming languages used to do this kind of thing,
   and it certainly works on a purely technical level, but just look
   how awkward it is finding your way around 350 lines of code!

   A more modular approach with subdivisions of the code would be more
   readable and easy to modify.  In general it is easiest to maintain
   code in which individual sections are self contained "modules" of
   maybe a couple of screens in size.

   For example, all the sections of code between the WAIT words could
   be defined as separate words.

   You should NOT normally write long single sections of code like this
   and we have only put this here as a demonstration of how awkward such
   code is to read in terms of program structure.

   Don't do it like this yourself! )


   : TEXTDEMO

   0 DUP INITSTREAM STREAM        \ Set full size window in 0 Stream

   2 BPENSET                      \ Background pen 2

   2 CLEARWINDOWTOP               \ Clear top lines

   SCRCLR CUROFF                  \ Clear screen and switch off cursor

   18 4 CURPUT                    \ Place cursor

   7 FPENSET 6 BPENSET BOLDON     \ Set text colour contrast and style

   ."                                         "
                                  \ Blank line = top of colour contrast area

   18 5 CURPUT

   ."   A Simple HeliOS Text Demonstration    "
                                  \ Colour contrast text

   18 6 CURPUT

   ."                                         "
                                  \ Blank line = bottom of colour contrast


   3 FPENSET 2 BPENSET BOLDOFF    \ Reset style and colour to normal

   4 10 CURPUT

   ."  This demonstration uses very simple text commands at an elementary level."

   4 12 CURPUT

   ."  Everything here can be done easily, even by inexperienced programmers."

   4 16 CURPUT

   ."  HeliOS text output routines are comprehensive but very easy to learn."

   4 19 CURPUT BOLDON 1 FPENSET

   ."  In fact everything you see in this demo is simple to do using HeliOS."

   4 23 CURPUT BOLDOFF 3 FPENSET

   WAIT

   0 BPENSET 3 FPENSET

   0 CLEARWINDOWTOP

   SCRCLR

   5 3 CURPUT

   ."  First we can look at some elementary text output formatting."

   5 6 CURPUT

   ."  HeliOS provides you with ten automatically organised text streams,"

   5 8 CURPUT

   ."  and many powerful and versatile screen display control commands."

   5 11 CURPUT 2 FPENSET 1 BPENSET

   ."  Power with simplicity of operation allows you freedom to be creative."

   5 14 CURPUT 1 FPENSET 0 BPENSET

   ."  Every aspect of your text display is associated with a HeliOS stream."

   5 16 CURPUT

   ."  HeliOS remembers many details of the text format within each stream,"

   5 18 CURPUT

   ."  and allows you to switch streams effortlessly with a SINGLE word."

   5 21 CURPUT

   ."  Let's set up some streams and output some text into them now."

   5 24 CURPUT

   WAIT

   INIT3STREAMS                   \ Set up 3 streams

   1 STREAM DEMOTEXT1
   2 STREAM DEMOTEXT1
   3 STREAM DEMOTEXT1

   2 STREAM                       \ Central screen output stream

   CURHM 7 SCRDN                  \ Scroll text down 7 lines

   5 3 CURPUT

   ."  Here the screen has been split into three text streams."

   5 5 CURPUT

   WAIT

   SCRCLR

   1 FPENSET

   5 3 CURPUT

   ."  Let's open up the text display to the full window area now."

   5 5 CURPUT

   ."  We can also do some other tricks with text, as we shall see."

   5 9 CURPUT

   WAIT

   5 DUP INITSTREAM STREAM        \ Enter and initialise stream number 5

   CUROFF                         \ Switch off cursor

   2 BPENSET  1 FPENSET           \ Set colours

   2 CLEARWINDOWTOP

   SCRCLR                         \ Clear Stream text area

   DEMOTEXT1                      \ Fill stream window with text

   CURHM 10 SCRDN                 \ Make space at top of text

   5 2 CURPUT

   ."  This text stream fills the whole window."

   5 4 CURPUT

   ."  We have also set up plain text, in black, on a white background."

   5 6 CURPUT

   ."  Now we can set up some more streams with smaller text windows."

   5 9 CURPUT

   WAIT

   6 DUP INITSTREAM STREAM        \ Enter stream number 6 and initialise

   CUROFF

   3 BPENSET  2 FPENSET

   2 17 39 5  SCRWIN              \ Set up stream text output window

   BOLDON                         \ Set Bold text

   SCRCLR  1CR                    \ Clear stream window

   ."  This text stream has different colours .....and Bold text."

   WAITSPACE

   7 DUP INITSTREAM STREAM        \ Enter stream number 7 and initialise

   CUROFF

   7 BPENSET  3 FPENSET

   8 24 55 5  SCRWIN

   SCRCLR  1CR

   ULINEON                        \ Set underlined text

   ."  This stream has underlined text,"

   2CR

   ."  and different colours again."

   WAITSPACE


   8 DUP INITSTREAM STREAM        \ Enter stream number 8 and initialise

   CUROFF

   0 BPENSET  3 FPENSET

   40 11 37 6  SCRWIN

   SCRCLR 1CR

   ."  And this is yet another variation."

   2CR

   ."  You have many choices, to make your"

   1CR

   ."  text more attractive."

   WAITSPACE

   5 STREAM

   SCRCLR

   5 3 CURPUT

   ."  You can have ten different uniquely formatted streams simultaneously."

   5 5 CURPUT

   ."  Each stream can have its own text styles and mini scrolling text window."

   5 7 CURPUT

  ."  All the Amiga console functions are supported, with additional features."


   4 10 CURPUT  \ Set up another colour contrasted area

   BOLDON 3 FPENSET 2 BPENSET

   ."                                                                          "

   4 11 CURPUT

   ."   The system automatically remembers all the features of each stream.    "

   4 12 CURPUT

   ."                                                                          "

   4 13 CURPUT

   ."   Powerful text control is available with minimum programming effort.    "

   4 14 CURPUT

   ."                                                                          "


   5 17 CURPUT  BOLDOFF 1 FPENSET 2 BPENSET

   ."  Now perhaps we can try outputting text to each of our new streams."

   5 20 CURPUT

   ."  First we shall send the whole block of text to each stream in turn,"

   5 22 CURPUT

   ."  and then try sending the text to all the streams line by line."

   5 24 CURPUT

   ."  Let's see what happens."

   5 27 CURPUT

   WAIT

   SCRCLR

   DEMOTEXT1

   6 STREAM SCRCLR DEMOTEXT1
   7 STREAM SCRCLR DEMOTEXT1
   8 STREAM SCRCLR DEMOTEXT1

   DEMOTEXT2

   9 DUP INITSTREAM STREAM

   CUROFF

   0 BPENSET 3 FPENSET

   7 6 67 18  SCRWIN

   SCRCLR

   2 3 CURPUT

   ."  The Helios text output formatting system can be set up"

   2 5 CURPUT

   ."  in any window, on any screen, with a SINGLE command!"

   2 8 CURPUT

   ."  HeliOS provides a large number of useful specialised text"

   2 10 CURPUT

   ."  formatting functions, which make sophisticated text oriented"

   2 12 CURPUT

   ."  programs very quick and easy to write."

   2 16 CURPUT

   WAIT

   SCRCLR

   6 2 CURPUT BOLDON 2 FPENSET 3 BPENSET

   ."                                                          "

   6 3 CURPUT

   ."    Would you like to experiment with the text colours?   "

   6 4 CURPUT

   ."                                                          "

   2 6 CURPUT BOLDOFF 3 FPENSET 0 BPENSET

   ."  Press <C> to step through colours, <X> to reset default values."

   2 8 CURPUT

   ."  The display shows which colour is currently being adjusted."

   2 10 CURPUT

   ."  Tap, or hold down, the <R>, <G>, and <B> keys to alter"

   2 12 CURPUT

   ."  the Red, Green, and Blue components of your chosen colour."

   33 17 CURPUT

   6 FPENSET

   ."  Press space to continue........"

   3 14 CURPOS

   ' NOOP CFA EXTERNAL !

   2 FPENSET 3 BPENSET 8 DEMOCOLOURS
   ;

 \ ----------------------------------------------------------------------------

 ( The word which controls progress through the Graphics Demo, allowing
   the user to either play around with the colours or carry on.

   The word DEMOWAIT does the serious work of adjusting colours etc. )


   : COLOURWAIT   ( - - - )    \ Wait for colour change or <Space>

   8 STREAM                    \ Lower right corner of screen = stream 8

   2 4 CURPUT ." Press <SPACE> to continue ...."

   7 STREAM CURHM              \ Lower left corner of screen = stream 7

   DEMOCOLOURS                 \ Allows colour change,
                               \ runs demo loop,
                               \ waits for <Space>

   8 STREAM                    \ Returns to stream 8
   ;

 \ ----------------------------------------------------------------------------

   ( Set up window handle storage variables etc. for "Window" demo )

   D0    DVARIABLE    WINDOW1
   D0    DVARIABLE    WINDOW2
   D0    DVARIABLE    WINDOW3

   280    VARIABLE    X1
   80     VARIABLE    Y1
   0      VARIABLE    X2
   0      VARIABLE    Y2
   0      VARIABLE    X3
   0      VARIABLE    Y3

   60     VARIABLE    RADIUS
   0      VARIABLE    ANGLE

 \ ---------------------------------------------------------------------------

 ( Moves window through a circular path )

   : TURNWINDOW      ( - - - )                 \ Move window in circle

   WINDOW2 D@   MAKEOUTWINDOW   CUROFF         \ Set text output to Window2

   12 0                                        \ Loop 12 times

   DO                                          \ Start loop

     WINDOW2 D@                                \ Get window handle

     X1 @                                      \ Calculate new X position
     DUP  RADIUS @ ANGLE @ GFXSIN 15 *ASR +
     DUP X1 ! -

     Y1 @                                      \ Calculate new Y position
     DUP  RADIUS @ ANGLE @ GFXCOS 15 *ASR 2/ +
     DUP Y1 ! -

     MOVEWINDOW                                \ Move window to new position

     30 ANGLE +!                               \ Update Angle

     7 RND 7 RND                               \ Random colours
     DDUP =                                    \ Are both colours the same?
     IF                                        \ If so, drop and ....
       DDROP 1 0                               \ .....use 1 and 0 instead
     THEN

     FPENSET BPENSET SCRCLR  DEMOTEXT1         \ Output some text

   LOOP                                        \ End 12 times loop
   ;

 \ ----------------------------------------------------------------------------

   ( A Windows demo

     This code is not very stylish, and although not as long as the
     earlier text demo it is still a little messy.

     This section is around 100 lines long, and is just about manageable
     because it lacks any serious logic and is a very simple piece of
     linear progression.

     The real problem here, and in the earlier text demo, is that the
     in-line text spoils the readability of the code.

     If you write a serious text based application you would need to
     create some scheme whereby text was stored neatly in external memory
     and referred to by pointers within your code.

     Notice how miscellaneous different methods of placing the cursor and
     setting the start of text lines have been used.

     Again this is quite "legal" but aesthetically nasty!

     Notice also that embedded in this code is the word TURNWINDOW which
     we defined earlier.

     But why DID we define TURNWINDOW separately?

     Usually we define short words like this for various reasons:

     1. Because they are used often, and defining them as a words allows
        them to be used repeatedly without including all the code each time.

     2. They form a neat logical functional unit which is easy to debug and
        maintain, and which may require change without interfering with the
        main program code.

     3. We simply want to break down a long section of code into sub-units
        for purposes of readability and maintenance.

     In this case reason 3 is closest, because we don't use TURNWINDOW
     anywhere else, and we won't really need to change it or play around
     with it later.

     However, if we have used this strategy with TURNWINDOW, why have we
     not broken down the rest of the code in a similar fashion?

     You may think all this is unimportant, but once you start writing
     large programs the way you organise your code is going to make a vast
     difference to how easy it is to debug, modify, and maintain. )


   : WINDOWSDEMO    ( - - - )


   9 DUP INITSTREAM STREAM                        \ Use stream 9 this time

   CUROFF 0 BPENSET 3 FPENSET                     \ Set cursor and colours

   0 CLEARWINDOWTOP                               \ Clear top of window

   SCRCLR    1 3 CURPUT                           \ Clear screen etc.

   ."      So far we have only operated within the main HeliOS display window,"

   1CR

   ."      but we can very easily create other windows, or indeed new screens."

   3CR   BOLDON   2 FPENSET   1 BPENSET   BOLDON    4 CURFW

   ."  The Helios system does all the tedious work involved in creating new "

   1CR   4 CURFW

   ."  screens or windows automatically, leaving you free to be creative.   "

   3CR   BOLDOFF   0 BPENSET   3 FPENSET

   ."      Your programming effort can be reduced to as little as entering only"

   1CR

   ."      ONE word for operations which would require a lot of code in other Amiga"

   1CR

   ."      languages.  HeliOS even keeps track of what Amiga resources you use, so"

   1CR

   ."      when you quit HeliOS everything is automatically closed down for you. "

   3CR   2 FPENSET   1 BPENSET   BOLDON   4 CURFW

   ."  It is absolutely simple to create windows, to appear on any screen,  "

   1CR   4 CURFW

   ."  and to do any kind of Input or Output using any Helios function.     "

   3CR

   BOLDOFF   0 BPENSET   3 FPENSET


   ."      Let's make a few windows now, and output some text to them."

   2CR

   ."      For now your input will still be via the main HeliOS display window,"

   1CR

   ."      so make sure that this main window is active before pressing <SPACE>."

   2CR   4 CURFW   WAIT   SCRCLR

   STDWINDOW HFWINDOW

   2 1 WINCOLS WINQUIET
   LIT$ DEMO WINDOW 1$    40  30  256 125  3 0  OPENWINDOW  WINDOW1 D!

   7 3 WINCOLS WINQUIET
   LIT$ DEMO WINDOW 2$    280 80  200 85   3 0  OPENWINDOW  WINDOW2 D!

   2 6 WINCOLS WINQUIET
   LIT$ DEMO WINDOW 3$    360 120 256 85   3 0  OPENWINDOW  WINDOW3 D!

   WINDOW1 D@ MAKEOUTWINDOW  1 BPENSET 2 FPENSET  CUROFF  DEMOTEXT1
   WINDOW2 D@ MAKEOUTWINDOW  3 BPENSET 7 FPENSET  CUROFF  DEMOTEXT1
   WINDOW3 D@ MAKEOUTWINDOW  2 BPENSET 3 FPENSET  CUROFF  DEMOTEXT1

   FORTHOUTWINDOW
   4 21 40 6 SCRWIN
   3 BPENSET 2 FPENSET
   SCRCLR
   1CR

   ."  We can also move windows around."

   2CR    WAIT   SCRCLR   2CR

   ."  Watch what happens ........"

   TURNWINDOW

   FORTHOUTWINDOW   SCRCLR   1CR

   ."  We can move windows in front of .....   or behind each other."

   2CR    WAIT   SCRCLR   2CR

   ."  Watch what happens ........"

   WINDOW1 D@ WINDOWTOBACK  50 DELAY
   WINDOW2 D@ WINDOWTOBACK  50 DELAY
   WINDOW3 D@ WINDOWTOBACK  50 DELAY
   WINDOW1 D@ WINDOWTOFRONT 50 DELAY
   WINDOW2 D@ WINDOWTOFRONT 50 DELAY
   WINDOW3 D@ WINDOWTOFRONT 50 DELAY
   WINDOW1 D@ WINDOWTOFRONT 50 DELAY
   WINDOW2 D@ WINDOWTOFRONT 50 DELAY
   WINDOW3 D@ WINDOWTOFRONT 50 DELAY


   FORTHOUTWINDOW   SCRCLR   1CR

   ."  Let's close these windows now."

   2CR      WAIT   SCRCLR


   WINDOW1 D@ CLOSEWINDOW
   WINDOW2 D@ CLOSEWINDOW
   WINDOW3 D@ CLOSEWINDOW
   ;

 \ ----------------------------------------------------------------------------

 ( Clear GFX window display area to colour )

   : CANVAS  ( colour - - - )        \ Clear area including top line

   GFXSETAPEN

   4 13 635 214 GFXRECTFILL ;

   : CANVAS2 ( colour - - - )        \ Clear are excluding top line

   GFXSETAPEN

   4 24 635 214 GFXRECTFILL ;

 \ ----------------------------------------------------------------------------

 ( Clip pixel write coordinates to screen drawing area )

   : GFXLIMITWRITE      ( X, Y - - - )

   OVER 4 635 WITHIN
   IF
     DUP 26 212 WITHIN
     IF
       GFXWRITE
     ELSE
       DDROP
     THEN
   ELSE
     DDROP
   THEN
   ;

 ( Pixel write Spriral Galaxy Demo )

   : GALAXY    ( - - - )    \ Draw a spiral of "semi-random" pixels

   0 0 GFXORIGIN
   1500 0
   DO

     7 RNDX  GFXSETAPEN
     I I GFXCOS 20000 */ 3 ASR 300 + DUP  24 RND +
     I I GFXSIN 32767 */ 4 ASR 100 + TUCK 12 RND +        GFXLIMITWRITE

     7 RNDX  GFXSETAPEN
     10 RND UNDER+
     5  RND +                                             GFXLIMITWRITE

     7 RND  GFXSETAPEN   632 RND 4 +     200 RND 11 +     GFXLIMITWRITE
     2      GFXSETAPEN   632 RND 4 +     200 RND 11 +     GFXLIMITWRITE

     3
   +LOOP
   ;

 \ ---------------------------------------------------------------------------

 ( Implements Galaxy Demo in COLOURWAIT loop )

   : GALAXYDEMO   ( c - - - c )

   ASCII m OVER=
   IF
     GALAXY
   THEN
   ;

 \ ----------------------------------------------------------------------------

 ( Displays Galaxy Demo )

   : SHOWGALAXY    ( - - - )

   1 CLEARWINDOWTOP
   5 STREAM
   1 BPENSET 2 FPENSET
   SCRCLR
   20 1 CURPUT
   ." Spiral Galaxy   8-Colour Pixel Write Demo"

   GALAXY

   8 COLOURWAIT
   ;

 \ ----------------------------------------------------------------------------

   ( Some variables for the 16 colour Mandelbrot demo. )

   D0     DVARIABLE SCREEN1
   3230   VARIABLE  P
   425    VARIABLE  Q
   0      VARIABLE  PP
   0      VARIABLE  QQ
   0      VARIABLE  X
   0      VARIABLE  Y
   0      VARIABLE  MANP
   0      VARIABLE  MANQ
   0      VARIABLE  INITIAL

 \ ----------------------------------------------------------------------------

   ( Set the 16 "Mandelbrot" screen colours )

   : SET16COLS    ( - - - )

   0  0  0  0   GFXSETRGB
   1  15 14 2   GFXSETRGB
   2  15 15 15  GFXSETRGB
   3  15 12 2   GFXSETRGB
   4  15 2  2   GFXSETRGB
   5  14 2  2   GFXSETRGB
   6  12 2  2   GFXSETRGB
   7  10 2  2   GFXSETRGB
   8  8  2  2   GFXSETRGB
   9  7  2  2   GFXSETRGB
   10 6  2  2   GFXSETRGB
   11 5  2  2   GFXSETRGB
   12 4  2  2   GFXSETRGB
   13 3  2  2   GFXSETRGB
   14 2  2  2   GFXSETRGB
   15 15 14 2   GFXSETRGB
   ;

 \ ----------------------------------------------------------------------------

   ( Open the 16 colour "Mandelbrot" screen and window )

   : GFX16COLWINDOW   ( - - - )

   1 STDSCREEN

   0 2 SCRCOLS

   LIT$ HeliOS                 ***<< Demo 16-Colour Screen >>***$

   640 256 4 OPENSCREEN

   SCREEN1 D!

   STDWINDOW HFWINDOW

   SCREEN1 D@ WINDOWSTRUCT 30 + D!

   0 2 WINCOLS

   LIT$ HeliOS                 ***<< Demo 16-Colour Window >>***$

   0 11   640 237   4 0  OPENWINDOW

   WINDOW1 D!

   WINDOW1 D@ MAKEGFXWINDOW

   SET16COLS ;

 \ ----------------------------------------------------------------------------

   ( Set up the 16 colour "Mandelbrot" window graphic lines )

   : DIVIDERS   ( - - - )

   5 GFXSETAPEN

   320 10 GFXMOVE   320 194 GFXDRAW
   319 10 GFXMOVE   319 194 GFXDRAW
   0  169 GFXMOVE   639 169 GFXDRAW
   0  194 GFXMOVE   639 194 GFXDRAW
   ;

 \ ----------------------------------------------------------------------------

  ( Set up streams and text for Mandelbrot demo )

  : MANDELSTREAMS  ( - - - )


  WINDOW1 D@ MAKEOUTWINDOW CUROFF

  2 FPENSET 0 BPENSET

  14 22  CURPUT  ." JULIA SET DEMO"

  51 22  CURPUT  ." MANDELBROT SET DEMO"

  7 DUP INITSTREAM STREAM CUROFF 1 FPENSET 0 BPENSET

  1 24  30 4 SCRWIN

  8 DUP INITSTREAM STREAM CUROFF 5 FPENSET 0 BPENSET

  31 24 49 4 SCRWIN

  7 STREAM SCRCLR 8 STREAM SCRCLR
  ;

 \ ----------------------------------------------------------------------------

   ( Now a bit of HeliOS Assembler for you to have fun with! )

   CODE MANDCALC                            ( PP QQ SC - - - C )

   WORD                                     \ Set assembler size

   FSP ()+ D5 MOVE                          \ Unload scaling factor > D5

   FSP ()+ D4 MOVE                          \ Unload Y > D4

   FSP ()+ D3 MOVE                          \ Unload X > D3

   63 # D2 MOVE                             \ Set loop index D2 = 63

   D2 DO                                    \ Initiate loop with D2 as index

   D3 D6 MOVE                               \ Store old X (D3) value

   D3 D0 MOVE                               \ Calculate scaled X*X
   D3 D0 MULS
   LONG D5 D0 ASR WORD                      \ ( D3*D3  11 ASR > D0 )

   D4 D1 MOVE                               \ Calculate scaled Y*Y
   D4 D1 MULS
   LONG D5 D1 ASR WORD                      \ ( D4*D4  11 ASR > D1 )

   2 FSP D() D3 MOVE                        \ X*X - Y*Y + P (= new X) > D3
   D0        D3 ADD
   D1        D3 SUB                         \ ( D0 - D1 + PP  > D3 )

   LONG D1 D0 ADD WORD                      \ LONG add D1 to D0 for limit

   D4 D1 MOVE                               \ X*Y/2 >D1
   D6 D1 MULS
   LONG 1 # D1 LSL D5 D1 ASR  WORD          \ D6*D4  10 ASR > D1

   FSP () D4 MOVE                           \ X*Y/2 + Q (=new Y) > D4
   D1     D4 ADD                            \ (  D1 + QQ > D4 )

   LONG 180000. # D0 CMP WORD               \ ? D0 (=limit) > 180000

   DBGT                                     \ Loop

   0< IF 0 # D2 MOVE THEN                   \ ? Reached loop limit

   2 # D2 LSR                               \ Scale iteration count

   4 # FSP ADDA                             \ Clear stack

   D2 FSP -() MOVE                          \ Colour (0-15) > stack

   EXITCODE

   ENDCODE

 \ ---------------------------------------------------------------------------

   ( Here we go with the Julia set code.

     If you don't understand it, don't worry about it! )

   : JULIA  ( - - - )

   2 11 GFXORIGIN

   3230 512 10000 */ PP !
   425  512 10000 */ QQ !

   158 0
   DO
     317 0
     DO

       PP @ QQ @

       I  2 LSL 640 -
       J  3 LSL 640 -
       9   MANDCALC

       DUP
       IF
         26 SWAP -
       THEN

       DUP 15 >
       IF
         13 -
       THEN

       DUP 12 =
       IF
         DROP 8
       THEN

       DUP 14 =
       IF
         DROP 3
       THEN

       GFXSETAPEN
       I J GFXWRITE
     LOOP
   LOOP
   ;

 \ ---------------------------------------------------------------------------

  ( Now for the Mandebrot.

   Anyone understand this?

   Don't worry about it!

   But it is simple isn't it! )

   : MANDEL  ( - - - )

   -.5777777  10000 M/  8883608. 1000 M/ 12 *ASR   MANP !
   -.6370000  10000 M/  8883608. 1000 M/ 12 *ASR   MANQ !

   321 11 GFXORIGIN

   158 0
   DO
     317 0
     DO

       I   2/  MANP @  +                \ P value
       J       MANQ @  +                \ Q value
       0                                \ X value
       0                                \ Y value
       11                               \ Scaling value

       MANDCALC

       GFXSETAPEN I J GFXWRITE

     LOOP
   LOOP
   ;

 \ ---------------------------------------------------------------------------

   ( Run the MandeBrot and Julia demo )

   : MANDELDEMO  ( - - - )

   JULIA
   MANDEL
   ;

 \ ---------------------------------------------------------------------------

   ( Close the MandeBrot and Julia demo )

  : MANDELEND  ( - - - )

   FORTHINWINDOW FORTHOUTWINDOW

   FWINDOW MAKEGFXWINDOW

   WINDOW1 D@ CLOSEWINDOW

   SCREEN1 D@ CLOSESCREEN
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show Mandelbrot Pictures )

  : DOMANDEL

  2 CANVAS
  7 STREAM SCRCLR 8 STREAM SCRCLR 6 STREAM SCRCLR

 ."  The next part of the Demo opens a new 16-Colour Screen and Window."
  1CR
 ."  You will find that this is an extremely simple operation in HeliOS."
  2CR
 ."  The 16-Colour Demo will involve COMPUTING and drawing two pictures which"
  1CR
 ."  derive from the Mandelbrot Set. ( One is actually a related Julia Set )"
  2CR
 ."  These pictures do take a considerable time to compute, but they actually"
  1CR
 ."  show that HeliOS is very fast indeed, because they use only code"
  1CR
 ."  written using the high level HeliOS system for all computations."
  1CR
 ."  Dedicated Mandelbrot Set generators often employ code written using a"
  1CR
 ."  separate assembler to achieve reasonable speed. Obviously you could"
  1CR
 ."  do the same and gain even more performance, but the idea of the Demo is"
  1CR
 ."  to show the exceptional speed of the high level HeliOS system."
  2CR
 ."  This is good news for creative programmers, because at last you have"
  1CR
 ."  access to an Interactive high level software system which is fast enough"
  1CR
 ."  to cope with the most demanding applications."
  2CR
 ."  The other good news is that if you are interested in the Mandelbrot Set"
  1CR
 ."  you are now in a position to write your own customised software, building"
  1CR
 ."  on the basis of the Demo source code provided."

  8 COLOURWAIT

  0 STREAM 0 BPENSET 1 FPENSET SCRCLR

  ' NOOP  CFA EXTERNAL !

  GFX16COLWINDOW

  MANDELSTREAMS

  DIVIDERS

  8 STREAM

  2 1 CURPUT  ." These pictures involve intensive computation."

  2 2 CURPUT  ." Please wait for the images to complete......."

  2 3 CURPUT  ." ....when finished you can adjust the colours."

  MANDELDEMO

  SCRCLR

  WINDOW1 D@ MAKEINWINDOW

  16 COLOURWAIT

  MANDELEND
  ;

 \ ---------------------------------------------------------------------------

   ( Various variables used in calculating fractals )

   0      VARIABLE   LINERATIO
   0      VARIABLE   HEIGHTRATIO
   0      VARIABLE   WIDTHRATIO
   0      VARIABLE   LINELENGTH
   0      VARIABLE   RECDEPTH
   0      VARIABLE   NODE

   0      VARIABLE   X0
   0      VARIABLE   Y0

   0      VARIABLE   GRECDEPTH
   0      VARIABLE   GX
   0      VARIABLE   GY
   0      VARIABLE   GX1
   0      VARIABLE   GY1
   0      VARIABLE   GX2
   0      VARIABLE   GY2
   0      VARIABLE   GX3
   0      VARIABLE   GY3
   0      VARIABLE   GXA
   0      VARIABLE   GYA
   0      VARIABLE   GXB
   0      VARIABLE   GYB
   0      VARIABLE   GXC
   0      VARIABLE   GYC
   0      VARIABLE   GA
   0      VARIABLE   GL
   0      VARIABLE   GL*C
   0      VARIABLE   GL*S

   0      VARIABLE   DODRAW
   0      VARIABLE   DOMOVE
   0      VARIABLE   RECLIMIT

 \ ---------------------------------------------------------------------------

   ( Fractal demo scaled screen rendering routines )

   ' NOOP CFA VARIABLE TINT

   : SCALEMOVE   ( X, Y - - - )

   SWAP 6 ASR SWAP 7 ASR
   DOMOVE @EXECUTE
   ;

   : SCALEDRAW   ( X,Y - - - )

   TINT @EXECUTE

   SWAP 6 ASR SWAP 7 ASR
   DODRAW @EXECUTE
   ;

 \ ---------------------------------------------------------------------------

   ( Set area or line plot functions )

   : MAKEAREAPLOT

   ' GFXAREAMOVE  CFA DOMOVE !
   ' GFXAREADRAW  CFA DODRAW !
   ;


   : MAKELINEPLOT

   ' GFXMOVE  CFA DOMOVE !
   ' GFXDRAW  CFA DODRAW !
   ;

 \ ---------------------------------------------------------------------------

   ( Generate new coordinates from a line

     Don't bother trying to follow this......... )

   : GENERATE

   GRECDEPTH ! GY2 ! GX2 ! GY1 ! GX1 !    \ Unload line end Coords etc

   GX2 @ GX1 @ - GX !                     \ X dimension     > GX
   GY2 @ GY1 @ - GY !                     \ Y dimension     > GY

   GX @ DUP M* GY @ DUP M* D+ GFXDSQROOT  \ Sq root of (X*X + Y*Y)

   DUP RECLIMIT @  >
   IF
     GL !                                 \ Length of line  > GL

     GY @  ABS  0  15 DLSL   GL @ U/   GFXARCSIN GA !

     GX @ 0<   IF GY @ 0 >= IF  180 GA @ - GA ! THEN  THEN   \ Adj quadrant

     GX @ 0 <= IF GY @ 0<   IF  180 GA +!       THEN  THEN

     GX @ 0>   IF GY @ 0<   IF  360 GA @ - GA ! THEN  THEN

     GL @  GA @ GFXSIN 15 *ASR   GL*S !    \ Intermediate result
     GL @  GA @ GFXCOS 15 *ASR   GL*C !    \ Intermediate result

     90 GA +!                               \ Angle + 90 degrees

     LINERATIO @ GL*C @ 13 *ASR  GX1 @ + GX3 !
     LINERATIO @ GL*S @ 13 *ASR  GY1 @ + GY3 !

     LINERATIO @ WIDTHRATIO @ - DUP GL*C @ 13 *ASR GX1 @ + GXA !
                                    GL*S @ 13 *ASR GY1 @ + GYA !

     LINERATIO @ WIDTHRATIO @ + DUP GL*C @ 13 *ASR GX1 @ + GXB !
                                    GL*S @ 13 *ASR GY1 @ + GYB !

     HEIGHTRATIO @ GL @ 13 *ASR GA @ DDUP
                                    GFXCOS 15 *ASR GX3 @ + GXC !
                                    GFXSIN 15 *ASR GY3 @ + GYC !


     GRECDEPTH @ GY2 @ GX2 @ GYC @ GXC @ GYB @ GXB @ GYA @ GXA @ GY1 @ GX1 @

     NODE @EXECUTE
   ELSE
     DROP
   THEN
   ;

 \ ---------------------------------------------------------------------------

   ( Don't bother trying to follow this either! )

   : NODE1

   5 PICK  7 PICK  SCALEMOVE                 \ Draw sub-lines
   7 PICK  9 PICK  SCALEDRAW
   3PICK   5 PICK  SCALEDRAW    GFXAREAEND

   11 PICK IF                                \ Process sub-lines

   DUP     3PICK  5 PICK  7 PICK      15 PICK 1-  GENERATE
   3PICK  5 PICK  9 PICK 11 PICK      15 PICK 1-  GENERATE
   7 PICK 9 PICK  7 PICK  9 PICK      15 PICK 1-  GENERATE
   5 PICK 7 PICK 11 PICK 13 PICK      15 PICK 1-  GENERATE

   THEN  11 DROPS ;

 \ ---------------------------------------------------------------------------

   ( Don't bother trying to follow this either! )

   : NODE2

   11 PICK 0= IF

   DUP 3PICK       SCALEMOVE       7 PICK 9 PICK  SCALEDRAW

   9 PICK 11 PICK  SCALEDRAW           DUP 3PICK  SCALEDRAW

   GFXAREAEND

   ELSE

   7 PICK 9 PICK   3PICK  5 PICK 15 PICK 1- GENERATE

   7 PICK 9 PICK 11 PICK 13 PICK 15 PICK 1- GENERATE

   THEN 11 DROPS ;

 \ ---------------------------------------------------------------------------

   ( Don't bother trying to follow this either! )

    : NODE3

    11 PICK 0= IF

    DUP 3PICK       SCALEMOVE   7 PICK 9 PICK  SCALEDRAW

    9 PICK 11 PICK  SCALEDRAW       DUP 3PICK  SCALEDRAW

    GFXAREAEND

    ELSE

    DUP 3PICK       9 PICK 11 PICK    15 PICK 1-  GENERATE

    7 PICK 9 PICK   11 PICK 13 PICK   15 PICK 1-  GENERATE

    THEN 11 DROPS ;

 \ ---------------------------------------------------------------------------

 ( Colours for various fractal demos )

   : LANDCOL

   BEGIN
     7 RND DUP 2 =
   WHILE
     DROP
   REPEAT
   GFXSETAPEN
   ;

   : SNOWCOL1

   1 GFXSETAPEN
   ;

   : SNOWCOL2

   GRECDEPTH @ 3 AND DUP 2 =
   IF
     5 RND + 1+
   THEN
   GFXSETAPEN
   ;

 \ ---------------------------------------------------------------------------

  ( Snowflake Fractal )

   : SNOWFLAKE  ( - - - )

   ' SNOWCOL1   CFA      TINT !
   ' NODE1      CFA      NODE !

   4096                  LINERATIO   !
   2100     1600 RND +   HEIGHTRATIO !
   1800     1600 RND -   WIDTHRATIO  !
   3        4    RND +   RECDEPTH    !
   128                   RECLIMIT    !
   12800                 LINELENGTH  !


   LINELENGTH @ 60 GFXCOS 15 *ASR X3 !
   LINELENGTH @ 60 GFXSIN 15 *ASR Y3 !

   310 LINELENGTH @ 128 / -   120 Y3 @ 256 / -  GFXORIGIN

   X1 0!   Y1 0!       LINELENGTH @ X2 !  Y2 0!

   X1 @  Y1 @   SCALEMOVE          \ Draw Triangle
   X2 @  Y2 @   SCALEDRAW
   X3 @  Y3 @   SCALEDRAW
   X1 @  Y1 @   SCALEDRAW

   GFXAREAEND

   ' SNOWCOL2  CFA TINT !

   X3 @ Y3 @ X2 @ Y2 @ RECDEPTH @ GENERATE
   X2 @ Y2 @ X1 @ Y1 @ RECDEPTH @ GENERATE
   X1 @ Y1 @ X3 @ Y3 @ RECDEPTH @ GENERATE
   ;

 \ ---------------------------------------------------------------------------

  ( Landscape fractal )

   : LANDSCAPE    ( - - - )

   ' LANDCOL  CFA        TINT !
   ' NODE1    CFA        NODE !

   1600 2400 RND +       LINERATIO   !
   -1700 1700 RND -      HEIGHTRATIO !
   110 170 RND +         WIDTHRATIO  !
   5 4 RND +             RECDEPTH    !
   128                   RECLIMIT    !
   32000                 LINELENGTH  !

   316 LINELENGTH @ 128 / -    170 GFXORIGIN


   X1 0! Y1 0!               LINELENGTH @ X2 !  Y2 0!

   X1 @ Y1 @ SCALEMOVE
   X2 @ Y2 @ SCALEDRAW
   GFXAREAEND

   X1 @
   Y1 @
   X2 @
   Y2 @
   RECDEPTH @
   GENERATE
   ;

 \ ---------------------------------------------------------------------------

  ( Dragon Fractal )

   : DRAGON    ( - - - )

   ' LANDCOL  CFA     TINT !
   ' NODE2    CFA     NODE !

   3800  480 RND +    LINERATIO   !
   -3800  480 RND -   HEIGHTRATIO !
   3800 640 RND +     WIDTHRATIO  !
   10 2 RND +         RECDEPTH    !
   32                 RECLIMIT    !
   12800              LINELENGTH  !

   195 125            GFXORIGIN

   X1 0! Y1 0!        LINELENGTH @ X2 ! Y2 0!

   X1 @
   Y1 @
   X2 @
   Y2 @
   RECDEPTH @
   GENERATE
   ;

 \ ---------------------------------------------------------------------------

  ( C-Curve Fractal )

   : CCURVE   ( - - - )

   ' LANDCOL  CFA    TINT !
   ' NODE3    CFA    NODE !

   4096              LINERATIO   !
   -3900 350 RND -   HEIGHTRATIO !
   3900  350 RND +   WIDTHRATIO  !
   8 4 RND +         RECDEPTH    !
   32                RECLIMIT    !
   12800             LINELENGTH  !

   210 140           GFXORIGIN

   X1 0! Y1 0!       LINELENGTH @ X2 ! Y2 0!

   X1 @
   Y1 @
   X2 @
   Y2 @
   RECDEPTH @
   GENERATE
   ;

 \ ---------------------------------------------------------------------------

  ( Display Snowflake Demo )

   : SHOWSNOWFLAKE  ( - - - )

   2 CLEARWINDOWTOP
   5 STREAM
   2 BPENSET 1 FPENSET
   SCRCLR
   22 1 CURPUT
   ." Snowflake       8-Colour Fractal Demo"

   SNOWFLAKE

   8 COLOURWAIT
   ;

   : SNOWFLAKEDEMO   ( c - - - c )

   ASCII m OVER=
   IF
     2 CANVAS2
     SNOWFLAKE
   THEN
   ;

 \ ---------------------------------------------------------------------------

  ( Display Landscape Demo )

   : SHOWLANDSCAPE  ( - - - )

   2 CLEARWINDOWTOP
   5 STREAM
   2 BPENSET 1 FPENSET
   SCRCLR
   22 1 CURPUT
   ." LandScape       8-Colour Fractal Demo"

   LANDSCAPE

   8 COLOURWAIT
   ;

   : LANDSCAPEDEMO   ( c - - - c )

   ASCII m   OVER=
   IF
     2 CANVAS2
     LANDSCAPE
   THEN
   ;

 \ ---------------------------------------------------------------------------

  ( Display Dragon Demo )

   : SHOWDRAGON   ( - - - )

   2 CLEARWINDOWTOP
   5 STREAM
   2 BPENSET 1 FPENSET
   SCRCLR
   22 1 CURPUT
   ." Dragon          8-Colour Fractal Demo"

   DRAGON

   8 COLOURWAIT
   ;

   : DRAGONDEMO    ( c - - - c )

   ASCII m  OVER=
   IF
     2 CANVAS2
     DRAGON
   THEN
   ;

 \ ---------------------------------------------------------------------------

  ( Display C-Curve Demo )

   : SHOWCCURVE   ( - - - )

   2 CLEARWINDOWTOP
   5 STREAM
   2 BPENSET 1 FPENSET
   SCRCLR
   22 1 CURPUT
   ." C-Curve         8-Colour Fractal Demo"

   CCURVE

   8 COLOURWAIT
   ;

   : CCURVEDEMO   ( c - - - c )

   ASCII m  OVER=
   IF
     2 CANVAS2
     CCURVE
   THEN
   ;

  \ ---------------------------------------------------------------------------

  ( Graphics demo Introduction )

   : GFXINTRO     ( - - - )

   7 DUP INITSTREAM STREAM CUROFF 2 FPENSET 6 BPENSET
   1 26  30 4 SCRWIN SCRCLR

   8 DUP INITSTREAM STREAM CUROFF 2 FPENSET 3 BPENSET
   31 26 49 4 SCRWIN SCRCLR

   6 DUP INITSTREAM STREAM CUROFF 2 BPENSET 1 FPENSET
   3 3 76 22 SCRWIN

   5 DUP INITSTREAM STREAM CUROFF 2 BPENSET 1 FPENSET
   1 1 79 25 SCRWIN SCRCLR

   2CR

   ."    Look carefully at the way the present screen is organised, which"

   1CR

   ."    will be similar for all the Graphics Demonstrations."

   3CR 3 FPENSET

   ."    The Graphics Demonstrations themselves will occupy the upper window."

   3CR

   ."    All instructions will be presented in the lower right screen area."

   3CR 1 FPENSET

   .$    Whenever the "Press <SPACE>" or any other command option is indicated$

   1CR

   ."    in the lower right area, you will always have the additional option of"

   1CR

   ."    using the Colour adjustment keys to modify the displayed image."

   2CR

   ."    This will give you the freedom to enjoy creating new graphic effects"

   1CR

   ."    and exploring your own colour preferences."

   3CR

   8 COLOURWAIT
   ;


 \ ---------------------------------------------------------------------------

  ( Introduce and show Snowflake )

   :   DOSNOWFLAKE   ( - - - )

   6 STREAM SCRCLR

   .$  The first Fractal we shall produce is the well known "Koch Snowflake",$
   1CR
   ."  which builds its form on a triangular initial generator."
   2CR
   ."  You can use the <M> key to redraw the image, each new Snowflake being"
   1CR
   ."  constructed using different random parameters."
   2CR
   ."  Notice how the various patterns are generated by imposing a similar"
   1CR
   ."  deformation upon each of the lines which make up the design."
   2CR
   ."  Again the colour control keys can be used to experiment with different"
   1CR
   ."  colour combinations."
   2CR
   ."  By now you should be getting a feel for the way in which simple eight"
   1CR
   ."  colour displays can be combined in attractive mutually enhancing ways."
   2CR
   ."  N.B."
   1CR
   ."  This and the following Fractal designs have an ENORMOUS number of"
   1CR
   ."  possible random variations. It is well worth trying many versions of"
   1CR
   ."  each because amongst a run of fairly mundane examples suddenly, from"
   1CR
   ."  time to time, a really spectacular and beautiful design will emerge."

   8 COLOURWAIT

   ' SNOWFLAKEDEMO  CFA EXTERNAL !

   8 STREAM

   2 1 CURPUT   ." Try adjusting the colours."

   2 2 CURPUT   ." Press <M> to generate a new Snowflake."

   2 3 CURPUT   ." Notice how the forms subtly metamorphose."

   SHOWSNOWFLAKE

   ' NOOP  CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show Galaxy )

   : DOGALAXY   ( - - - )

   2 CANVAS 6 STREAM CURHM

   .$  The first graphics demo, "Spiral Galaxy", displays simple pixel plotting.$
   2CR
   ."  We retain the standard eight colour screen for this demonstration."
   3CR
   ."  You can use the <M> key to repeatedly overplot the display area, creating"
   1CR
   ."  various semi-randomised effects."
   2CR
   ."  Try holding down the <M> key for some time, allowing various colour"
   1CR
   ."  effects to manifest."
   4CR
   ."  Use the colour control keys to get a feel for the effects of various"
   1CR
   ."  colour combinations."
   3CR
   ."  See how the numerical values of the red, green, and blue components"
   1CR
   ."  correlate with the colours and visual impressions produced."

   8 COLOURWAIT

   ' GALAXYDEMO CFA EXTERNAL !

   8 STREAM

   2 1 CURPUT  ." Let's try writing a few pixels."

   2 2 CURPUT  ." Press <M> to slowly define the spiral."

   2 3 CURPUT  ." Don't forget to play with the colours!"

   SHOWGALAXY

   ' NOOP CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce Fractals )

   : FRACTALINTRO    ( - - - )

   2 CANVAS 6 STREAM CURHM

   ."  Next we shall demonstrate simple line drawing by generating a series of"
   1CR
   ."  well known Fractal designs, again using the standard eight colour screen."
   2CR
   ."  Notice that ALL the graphics in this Demo are COMPUTED images as distinct"
   1CR
   ."  from predrawn pictures created in an art package and simply displayed."
   2CR
   ."  Considerable computing is required to generate even these simple images,"
   1CR
   ."  and they give a good indication of the speed and power of HeliOS."
   2CR
   ."  The Fractals you will see are all very well known examples, and you may"
   1CR
   ."  have access to other software which generates similar images.  If so you"
   1CR
   ."  you may like to compare the speed of HeliOS fractal generation with the"
   1CR
   ."  other software to get some idea of how just how fast HeliOS is."
   2CR
   ."  You may also be interested to know that computing these Fractal images"
   1CR
   ."  makes use of RECURSION, which is readily implemented in HeliOS."
   2CR
   ."  Remember that all the source code for this Demo is provided for you as a"
   1CR
   ."  simple tutorial exercise, so that by using and modifying the Demo code"
   1CR
   ."  you can soon be generating all manner of Fractal designs for yourself!"

   8 COLOURWAIT
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show Landscape )

   : DOLANDSCAPE   ( - - - )

   2 CANVAS 6 STREAM CURHM

   ."  The second Fractal is another variant on the Koch design, this time"
   1CR
   ."  building on a horizontal line initial generator. It is known as the"
   1Cr
   .$  "Koch Landscape", for reasons only requiring a little imagination.$
   2CR
   ."  It is interesting that there is only a minor difference in the computing"
   1CR
   ."  procedure required to produce this and the previous design."
   2CR
   ."  Again you can use the <M> key to redraw the image, with each Landscape"
   1CR
   ."  constructed using slightly different random parameters."
   2CR
   ."  Notice again how the pattern is generated by imposing a similar"
   1CR
   ."  deformation upon each of the lines which make up the design."
   3CR
   ."  Again the colour control keys can be used to experiment with different"
   1CR
   ."  colour combinations."
   2CR
   ."  N.B."
   1CR
   ."  There are very many variations of these Fractal designs, so be sure"
   1CR
   ."  to press <M> plenty of times to view the possibilities."

   8 COLOURWAIT

   '  LANDSCAPEDEMO CFA  EXTERNAL !

   8 STREAM

   2 1 CURPUT  ." Try adjusting the colours."

   2 2 CURPUT  ." Press <M> to generate a new Landscape."

   2 3 CURPUT  ." Notice the simple repeated procedure."

   SHOWLANDSCAPE

   ' NOOP  CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show Dragon )

   : DODRAGON     ( - - - )

   2 CANVAS 6 STREAM CURHM

   ."  The next Fractal is yet another variant on the Koch curve, this time"
   1CR
   ."  building on a simple bent line initial generator. It is known as the"
   1CR
   .$  "Dragon Curve" because of its similarity to Chinese Dragon designs.$
   2CR
   ."  Once again the program to produce this Fractal is very similar to the"
   1CR
   ."  ones for the earlier designs."
   2CR
   ."  Again you can use the <M> key to redraw the image, with each Dragon"
   1CR
   ."  constructed using slightly different random parameters."
   2CR
   ."  These many different Fractals are produced by minor procedural changes,"
   1CR
   ."  and you will find many new interesting forms by experimenting with the"
   1CR
   ."  material provided in the Demo source code."


   8 COLOURWAIT

   ' DRAGONDEMO  CFA EXTERNAL !

   8 STREAM

   2 1 CURPUT  ." Try adjusting the colours."

   2 2 CURPUT  ." Press <M> to generate a new Dragon."

   2 3 CURPUT  ." Some are more Dragon-like than others. Why?"

   SHOWDRAGON

   ' NOOP    CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show C-Curve )

   : DOCCURVE     ( - - - )

   2 CANVAS 6 STREAM CURHM

   ."  The final Koch curve example is called the C-Curve, for the unimaginative"
   1CR
   .$  reason that it resembles a "C" turned on its side!$
   2CR
   ."  Once again the program to produce the C-Curve is nearly identical to the"
   1CR
   ."  ones for the earlier designs."
   2CR
   ."  Again you can use the <M> key to redraw the image, with each C-Curve"
   1CR
   ."  constructed using slightly different random parameters."
   2CR
   ."  Remember that there are a very large number of semi-random designs"
   1CR
   ."  possible, and you will often generate spectacularly fine pictures quite"
   1CR
   ."  suddenly within a long run of more mundane examples."
   2CR
   ."  KEEP trying!"

   8 COLOURWAIT

   ' CCURVEDEMO  CFA  EXTERNAL !

   8 STREAM

   2 1 CURPUT  ." Try adjusting the colours."

   2 2 CURPUT  ." Press <M> to generate a new C-Curve."

   2 3 CURPUT  ." This uses a slightly modified Dragon process."

   SHOWCCURVE

   ' NOOP   CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

  ( Introduce and show Area Demos )

   :  DOAREADEMOS    ( - - - )

   2 CANVAS 6 STREAM CURHM

   ."  Of course the HeliOS system will also do area fill graphics, so let's go"
   1CR
   ."  round the Fractals once again, this time using filled coloured areas."
   1CR
   ."  You will notice that in many cases the speed of the plot, and also the"
   1CR
   ."  detail revealed, is not really affected by changing to filled graphics."
   2CR
   ."  In fact, only the less detailed displays really benefit from the filled"
   1CR
   ."  area approach, because with the more detailed designs the line plotting"
   1CR
   ."  effectively fills the display area with fine detail."
   2CR
   ."  One of the parameters randomly assigned for each Fractal generation is"
   1CR
   .$  "Depth of Recursion", which effectively determines the amount of detail$
   1CR
   ."  generated within the picture. The deeper the recursion, the slower the"
   1CR
   ."  overall drawing becomes, but within limits the detail becomes finer."
   2CR
   ."  After a certain point, the resolution of the display limits the detail"
   1CR
   ."  which further levels of recursion can reveal, but slowness of drawing can"
   1CR
   ."  also give greater colour variation from the semi-random colour routine."
   2CR
   ."  You can see from all this that creative graphic computing involves many"
   1CR
   ."  diverse and complex factors, and in fact becomes almost artistic."

   MAKEAREAPLOT

   8 COLOURWAIT

   8 STREAM

   2 1 CURPUT  ." Try adjusting the colours."

   2 2 CURPUT  ." Press <M> to generate a new picture."

   2 3 CURPUT  ." Experiment!"

   ' SNOWFLAKEDEMO   CFA EXTERNAL !

   SHOWSNOWFLAKE

   2 CANVAS2

   ' LANDSCAPEDEMO  CFA  EXTERNAL !

   SHOWLANDSCAPE

   2 CANVAS2

   ' DRAGONDEMO  CFA EXTERNAL !

   SHOWDRAGON

   2 CANVAS2

   ' CCURVEDEMO  CFA EXTERNAL !

   SHOWCCURVE

   2 CANVAS2

   ' NOOP CFA EXTERNAL !

   8 STREAM SCRCLR

   6 STREAM SCRCLR
   ;

 \ ---------------------------------------------------------------------------

   : DEMO      ( - - - )

   FSCREEN SCREENTOFRONT          \ Make sure HeliOS screen is at front

   FWINDOW MAKEGFXWINDOW          \ Make FWINDOW the current GFX window

   HELIOS                         \ Sun

   INTRO                          \ Introduction

   TEXTDEMO                       \ Text demo

   HELIOS                         \ Sun

   WINDOWSDEMO                    \ Windows demo

   HELIOS                         \ Sun

   MAKELINEPLOT                   \ Set up for line plotting

   GFXINTRO                       \ Introduce graphic demos

   DOGALAXY                       \ Spiral Galaxy

   FRACTALINTRO                   \ Introduce fractals

   DOSNOWFLAKE                    \ Snowflake fractal

   DOLANDSCAPE                    \ Landscape fractal

   DODRAGON                       \ Dragon fractal

   DOCCURVE                       \ C-Curve fractal

   DOAREADEMOS                    \ Area fractal demos

   HELIOS                         \ Sun

   DOMANDEL                       \ Mandelbrot demo

   HELIOS                         \ Sun

   DEMOQUIT                       \ Quit demo
   ;

 \ ----------------------------------------------------------------------------

  DEMO

 \ ----------------------------------------------------------------------------
