\ Dotty window example 01Oct88pJa This is a Forth version of the Dotty.c example from F.Fish#1 Compare the 'C' listing with this file. It tries to follow the 'C' version. Uses the random number generator in the kernel. Set the seed to a number you like, for a different sequence. Graphics library is used, and is normally opened in Utilities. \ Load screen for dotty.blk 01Oct88pJacr .( loading include files ) only forth also Exec definitions tload i:exec/ports tload i:exec/tasks Intuition definitions tload i:intuition/screen tload i:intuition/window tload i:intuition/intuimessage Graphics definitions tload i:graphics/rastport only forth Exec also forth Graphics also forth Intuition also forth also definitions cr .( loading program ) 2 7 thru \ Define constants etc. 01Oct88pJa 2 constant DEPTH 100 constant WIDTH 50 constant HEIGHT variable width variable height variable rp variable window variable message variable xoffset variable yoffset variable sizing? variable ended \ Define the window 01Aug88pJa NewWindow nw nw sizeoff NewWindow erase a" Dotty Window." nw Title s! 50 nw LeftEdge s! WIDTH nw Width s! 50 nw TopEdge s! HEIGHT nw Height s! 640 nw MaxWidth s! 200 nw MaxHeight s! 30 nw MinWidth s! 30 nw MinHeight s! -1 nw BlockPen s! -1 nw DetailPen s! WBENCHSCREEN nw Type s! CLOSEWINDOW REFRESHWINDOW or SIZEVERIFY or NEWSIZE or nw IDCMPFlags s! WINDOWCLOSE SIMPLE_REFRESH or WINDOWSIZING or WINDOWDRAG or WINDOWDEPTH or nw Flags s! \ Open the window and defaults. 01Aug88pJa: getwindow nw OpenWindow dup window ! 0= abort" No window???" ; : usable_width (s -- ) window @ { Window dup Width s@ over BorderLeft s@ - swap BorderRight s@ - width ! ; : usable_height (s -- ) window @ { Window dup Height s@ over BorderTop s@ - swap BorderBottom s@ - height ! ; : set_defaults usable_width usable_height window @ { Window RPort s@ rp ! window @ BorderLeft s@ xoffset ! window @ BorderTop s@ yoffset ! ; \ messages 01Oct88pJa: get_message (s -- ) { Window window @ UserPort s@ GetMsg message ! ; : waitwindow (s -- ) { Window window @ UserPort s@ { MsgPort mp_SigBit s@ 1 swap << Wait drop ; : dorefresh (s -- ) window @ BeginRefresh usable_width usable_height rp @ yoffset @ height @ + 1- xoffset @ width @ + 1- yoffset @ xoffset @ RectFill window @ true EndRefresh ; \ message actions. 01Oct88pJa: newsize (s -- ) sizing? off usable_width usable_height ; : finished (s -- ) window @ CloseWindow ended on ; : dots (s -- ) sizing? @ if waitwindow else rp @ 32 random SetAPen rp @ height @ random yoffset @ + width @ random xoffset @ + WritePixel then ; \ Main loop 01Oct88pJa: dotty getwindow set_defaults begin get_message message @ ?dup if dup { IntuiMessage Class s@ swap ReplyMsg dup CLOSEWINDOW and if drop finished else dup SIZEVERIFY and if drop sizing? on else dup REFRESHWINDOW and if drop dorefresh else NEWSIZE and if newsize then then then then else dots then ended @ until ; task: dottask : dodots 0 dottask activate dotty stop ; \ Dotty window example. 01Oct88pJa Another example of structures and include files usage with A4th Judge for yourself on readability etc. \ Load screen for dotty.blk 01Oct88pJa If you do not forget loaded include files between applications the applications will load faster. One of two ways to run this program: enter: dotty enter: dodots The last one allows you to continue using A4th, and uses a task. One problem: this program example doesn't initialize the variables when it starts, it expects to be run only once after it is loaded; it must be reloaded if you want to run it again. \ Define constants etc. 01Aug88pJaConstants and variables are similar except pointers, they point to specific classes in c. In Forth they are just addresses. We can force them to point at anything, without any 'typecast'. It is not required to open the libraries, that is done by Forth. All the variables have the same name except sizing?, it is similar to waiting_for_message in the c source. \ Define the window 01Aug88pJaThe newwindow structure nw is allocated, zeroed and filled in with the required numbers. This window will be in the WorkBench and responds to several messages. Closing, resizing, refreshing all have to be dealt with. Refreshing is a simple clearing of the window. Note that if MinHeight or Width is set to 10 as in the c-source, and the window is made smaller then the borders, it will crash. Rectfill in the dorefresh word will cause the crash. \ Open the window and defaults. 01Aug88pJagetwindow Opens the window and sets the window pointer. usable_width (s -- ) Sets the width variable to the usable space in the window. That is, the window less the borders. usable_height (s -- ) Sets the height variable to usable number of pixels in the vertical direction. set_defaults Gets the width and height of the windows usable area, sets the rasterpointer rp, and sets the xoffset and yoffset to the borders. All that to not draw in the borders. \ messages 01Aug88pJaget_message (s -- ) Gets a message from the port, null=0 if none there. waitwindow (s -- ) Waits until the window send a message. dorefresh (s -- ) Does a refresh on the window. Clears the rectangle in the window. Note the order of the parameters. Not the same as in c-source. The order is PUSH a-REGISTERS HIGH TO LOW then d-REGISTERS HIGH TO LOW. (s a7..a0/d7..d0 -- ). I use a book ( Amiga Programmers Handbook, Eugene P. Mortimore, Sybex ) listing all the registers under the parameters, as an aid. \ message actions. 01Oct88pJanewsize (s -- ) newsize message is received, get the new sizes. finished (s -- ) Close window message causes window to be closed and the main loop is ended. dots What the program does if nothing is happening. If the user is resizing the window, we also don't draw into it, but wait for the newsize message. Drawing the dot takes into account the borders, x/yoffsets. \ Main loop 01Aug88pJadotty The 'main' program. It doesn't have to save the message if it receives one, just the Class. Therefore no message variable. The CLOSEWINDOW, SIZEVERIFY etc are all bit masks they have to be 'and'ed with the message class to test if they are set. In my opinion, I can understand this loop a lot better then the c-source listing, which spans ± 2 (text)editor screens full.