\ Make screen and window for HAMmmm display. \ Use double buffering to achieve smooth animation. \ \ Author: Phil Burk \ Copyright 1987 Phil Burk \ This code is considered to be in the public domain and \ may be freely distributed but may not be sold for profit. ANEW TASK-MMM_SCREEN \ Declare Intuition structures. NewScreen HAMNewScreen NewWindow HAMNewWindow VARIABLE HAMScreen ( holder for relative screen pointer ) \ Define drawing surface. 0 constant HAM_XMIN 10 constant HAM_YMIN 320 constant HAM_XMAX 200 constant HAM_YMAX : HAM.OPEN ( -- , open custom HAM screen ) gr.init \ Set to default values. HAMNewScreen NewScreen.Setup HAMNewWindow NewWindow.Setup \ \ Modify defaults for this demo. HAM HAMNewScreen ..! ns_viewmodes ( Change to HAM ) 6 HAMNewScreen ..! ns_depth 0" HAMmmm by Phil Burk" >abs HAMNewScreen ..! ns_DefaultTitle \ \ Open Screen and store pointer in NewWindow structure. HAMNewScreen openscreen() dup HAMScreen ! ( Open screen. ) >abs HAMNewWindow ..! nw_screen ( Modify window for this screen. ) \ \ Set up Backdrop window. CUSTOMSCREEN HAMNewWindow ..! nw_type 0 HAMNewWindow ..! nw_TopEdge ham_xmax HAMNewWindow ..! nw_Width ham_ymax HAMNewWindow ..! nw_Height BACKDROP ACTIVATE | BORDERLESS | HAMNewWindow ..! nw_flags MENUVERIFY MENUPICK | HAMNewWindow ..! nw_IDCMPFlags HAMNewWindow gr.openwindow gr.set.curwindow \ \ Sometimes the Amiga can build a bad COPPER list for screens. \ This can happen if you have Emacs up in INTERLACE mode and open a \ NON-INTERLACE screen. \ The following call will correct this problem (hopefully). RemakeDisplay() ; : HAM.CLOSE ( -- , Close screen and window.) gr.closecurw HAMScreen @ closescreen() ; \ ----------------------------------------------- \ ------- Double Buffering ---------------------- \ ----------------------------------------------- \ \ A BACKDROP window's Rastport points to the Bitmap \ that is contained in the screen structure. This \ Bitmap points to 6 planes allocated by intuition. \ We can switch to a new drawing surface by replacing \ the original 6 plane pointers with pointers to \ our own 6 planes. We can then draw into these planes \ using the Rastport from the window. When we are through \ drawing we can make these visible by rebuilding the \ display Copper lists. By repeating this process we can \ always be drawing into a surface that is not visible \ thus eliminating visual breakup of the display. 6 array BIT-PLANES-0 ( store pointers to drawing surfaces ) 6 array BIT-PLANES-1 : ALLOC.BIT.PLANES ( -- , allocate second drawing surface ) 6 0 DO 320 200 allocraster() >abs i bit-planes-1 ! LOOP ; : FREE.BIT.PLANES ( -- , free when done ) 6 0 DO i bit-planes-1 @ >rel 320 200 freeraster() LOOP ; : SCREEN.PLANE.BASE ( -- addr , of pointer to first plane ) hamscreen @ .. sc_bitmap .. bm_planes ; variable PLANES-CURRENT ( 0/1 ) : GRAB.FIRST.BUFFER ( -- , get planes allocated by OpenScreen ) screen.plane.base 0 bit-planes-0 6 cells move 0 planes-current ! ; : HAM.REBUILD ( -- , rebuild HAM screen , make changes visible ) hamscreen @ >abs call intuition_lib makescreen drop call intuition_lib rethinkdisplay drop ; : SWAP.BUFFERS ( -- , swap bit planes so draw in next buffer ) planes-current @ 0= IF 0 bit-planes-1 ELSE 0 bit-planes-0 THEN screen.plane.base 6 cells move planes-current @ 1 xor planes-current ! ; : HAM.SHOW&SWAP ( flag -- ) dup not HAMScreen @ swap showtitle() ( force REdraw ) HAMScreen @ swap showtitle() swap.buffers ; : BUFFERS.INIT ( -- ) alloc.bit.planes grab.first.buffer swap.buffers 1 ham.show&swap ; : BUFFERS.TERM ( -- ) \ Make sure CloseScreen deallocates proper planes. planes-current @ 0= 0= IF swap.buffers THEN free.bit.planes ;