home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This is the E version of the 'Tree of Pythagoras'.
- ** Written by Raymond Hoving, Waardgracht 30, 2312 RP Leiden,
- ** The Netherlands.
- ** E-mail address: hoving@stpc.wi.leidenuniv.nl
- ** Requires Kickstart V3.0+ and reqtools.library V38+
- ** Creation date: Sun Jul 17 17:30:07 1994, Version: 2.0
- */
-
- OPT REG=5,OSVERSION=39 /* Kickstart 3.0+ only. */
-
- MODULE 'intuition/intuition', 'intuition/screens', 'utility/tagitem',
- 'reqtools', 'exec/ports', 'exec/libraries',
- 'libraries/reqtools', 'graphics/modeid', 'graphics/text'
-
- DEF pythscreen=NIL : PTR TO screen,
- pythwindow=NIL : PTR TO window,
- pythidcmp=NIL : PTR TO mp,
- screenmodereq=NIL : PTR TO rtscreenmoderequester,
- scrwidth, scrheight, fontheight,
- winxsize, winysize, xbase, ybase, mbase,
- depth=1, mdepth=10,
- time0, time1
-
- CONST BORDERSIZE = 4
-
- ENUM MSG_READY, MSG_ABORT, ERROR_REQTLIB, ERROR_SCREEN,
- ERROR_WINDOW, ERROR_OOM
-
- PROC pythcleanup(errornumber)
-
- /* This procedure will deallocate all objects that were succesfully
- ** allocated. When an error occured, this will be told to the user.
- */
-
- IF pythwindow<>NIL THEN CloseWindow(pythwindow)
- IF pythscreen<>NIL THEN CloseScreen(pythscreen)
- IF screenmodereq<>NIL THEN RtFreeRequest(screenmodereq)
- IF reqtoolsbase<>NIL THEN CloseLibrary(reqtoolsbase)
- SELECT errornumber
- CASE ERROR_OOM
- WriteF('ERROR: Out of memory.\n')
- CASE ERROR_REQTLIB
- WriteF('ERROR: Couldn\at open reqtools.library.\n')
- CASE ERROR_SCREEN
- WriteF('ERROR: Couldn\at open new screen.\n')
- CASE ERROR_WINDOW
- WriteF('ERROR: Couldn\at open new window.\n')
- CASE MSG_ABORT
- WriteF('Drawing cancelled.\n')
- CASE MSG_READY
- WriteF('I just drew \d little house\s!\n',
- Shl(1,mdepth)-1,
- IF mdepth=1 THEN '' ELSE 's')
- ENDSELECT
- CleanUp(errornumber) /* Call the standard E finalizer. */
- ENDPROC
-
- PROC pythtree(a1,a2,b1,b2)
-
- /* This (recursively called) procedure will do the actual
- ** drawing of the tree.
- */
-
- DEF c1,c2,d1,d2,e1,e2,ci1,ci2,di1,di2
- IF GetMsg(pythidcmp)<>NIL THEN pythcleanup(MSG_ABORT)
- IF depth<=mdepth /* Check if we aren't too deep. */
- INC depth /* This depth is still allowed. */
- SetAPen(stdrast,depth) /* Drawing color depends on recursion depth. */
- c1 := !a1-a2+b2 ; ci1 := !c1!
- c2 := !a1+a2-b1 ; ci2 := !c2!
- d1 := !b1+b2-a2 ; di1 := !d1!
- d2 := !a1-b1+b2 ; di2 := !d2! /* Calculate all */
- e1 := !0.5 * (!c1-c2+d1+d2) /* needed coordinates. */
- e2 := !0.5 * (!c1+c2-d1+d2)
- /*
- ** e Note the use of ! between () in the calculations of e1 and
- ** /\ e2. We use some extra LONG's to minimize convertion
- ** / \ overhead.
- ** c+----+d The coordinates of c,d and e are calculated from the
- ** | | coordinates of a and b. Lineair Algebra is great fun!
- ** | |
- ** a+----+b
- */
- Move(stdrast,ci1,ci2)
- Draw(stdrast,!a1!,!a2!)
- Draw(stdrast,!b1!,!b2!)
- Draw(stdrast,di1,di2)
- Draw(stdrast,ci1,ci2)
- Draw(stdrast,!e1!,!e2!)
- Draw(stdrast,di1,di2) /* Draw the little house. */
- IF Rnd(2) = 0 /* Makes the growing a bit */
- pythtree(c1,c2,e1,e2) /* more interesting. */
- pythtree(e1,e2,d1,d2)
- ELSE
- pythtree(e1,e2,d1,d2)
- pythtree(c1,c2,e1,e2)
- ENDIF
- DEC depth /* Ready with this branch. */
- ENDIF
- ENDPROC
-
- PROC main()
-
- DEF a1,a2,b1,b2
-
- /* Open reqtools.library and allocate memory for requester structure.
- */
-
- IF (reqtoolsbase := OpenLibrary('reqtools.library',38)) = NIL THEN
- pythcleanup(ERROR_REQTLIB)
-
- IF (screenmodereq := RtAllocRequestA(RT_SCREENMODEREQ,NIL)) = NIL THEN
- pythcleanup(ERROR_OOM)
-
- /* Let the user decide which screenmode he/she wishes. Note that
- ** the tree looks best on a screen with approximately the same
- ** number of pixels in both directions, like 640x512.
- */
-
- IF RtScreenModeRequestA(screenmodereq,'Tree of Pythagoras', [
- RTSC_FLAGS,SCREQF_OVERSCANGAD OR SCREQF_AUTOSCROLLGAD OR SCREQF_SIZEGADS,
- RTSC_MINWIDTH,100,
- RTSC_MINHEIGHT,100,
- TAG_DONE]) = FALSE THEN pythcleanup(MSG_ABORT)
-
- /* Then ask the maximum depth of recursion.
- */
-
- IF (RtGetLongA({mdepth},'Tree of Pythagoras',NIL, [
- RTGL_MIN,1,
- RTGL_MAX,14,
- RTGL_TEXTFMT,'Enter maximum depth of the tree:',
- RT_WINDOW,pythwindow,
- TAG_DONE])) = FALSE THEN pythcleanup(MSG_ABORT)
-
- /* Get relevant data from the screenmode structure.
- */
-
- scrwidth := screenmodereq.displaywidth
- scrheight := screenmodereq.displayheight
-
- /* Open the screen the user decided to want.
- */
-
- IF (pythscreen := OpenScreenTagList(NIL, [
- SA_DEPTH,4,
- SA_TYPE,CUSTOMSCREEN,
- SA_DISPLAYID,screenmodereq.displayid,
- SA_WIDTH,scrwidth,
- SA_HEIGHT,scrheight,
- SA_TITLE,'Screen of Pythagoras',
- TAG_DONE])) = NIL THEN pythcleanup(ERROR_SCREEN)
-
- /* Now open a screen filling window on the sceen that was just opened.
- */
-
- IF (pythwindow:=OpenWindowTagList(NIL, [
- WA_WIDTH,scrwidth,
- WA_HEIGHT,scrheight,
- WA_IDCMP,IDCMP_CLOSEWINDOW,
- WA_FLAGS,WFLG_CLOSEGADGET OR WFLG_ACTIVATE,
- WA_TITLE,'Tree of Pythagoras by Raymond Hoving',
- WA_CUSTOMSCREEN,pythscreen,
- TAG_DONE])) = NIL THEN pythcleanup(ERROR_WINDOW)
-
- /* Get some useful data from the window structure.
- */
-
- stdrast := pythwindow.rport
- pythidcmp := pythwindow.userport
- fontheight := pythwindow.ifont::textfont.ysize
-
- /* Set the palette for this screen (brown to green).
- */
-
- LoadRGB4(ViewPortAddress(pythwindow), [
- $000,$89a,$640,$752,$762,$771,$781,$680,$580,$080,
- $090,$0a0,$0b0,$0c0,$0d0,$0e0] : INT, 16)
-
-
- /* Build a 'real random' seed from the current time
- */
-
- CurrentTime({time0},{time1})
- Rnd(-Abs(Eor(time0,time1)))
-
- /* Now calculate how big the tree can be on the selected screen.
- */
-
- winxsize := scrwidth - (2 * BORDERSIZE)
- winysize := scrheight - (6 * BORDERSIZE + fontheight)
- xbase := winxsize! / 12.2 /* Divider found by trial and error. */
- ybase := winysize! / 8.0 /* This one as well. */
- IF !xbase < ybase THEN mbase := xbase ELSE mbase := ybase
- a1 := scrwidth! / 2.0 - mbase
- b1 := scrwidth! / 2.0 + mbase
- a2 := scrheight - (4 * BORDERSIZE)!
- b2 := a2
-
- /* Set the busy pointer and start drawing.
- */
-
- SetWindowPointerA(pythwindow,[WA_BUSYPOINTER,TRUE,TAG_DONE])
- pythtree(a1,a2,b1,b2)
- SetWindowPointerA(pythwindow,TAG_DONE)
-
- /* Ready! Wait for the user to close the window.
- */
-
- WaitPort(pythidcmp)
- pythcleanup(MSG_READY)
- ENDPROC
-