home *** CD-ROM | disk | FTP | other *** search
- (in-package :oou)
- (oou-provide :screen-3buf)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; screen-3buf.Lisp
- ;;
- ;; Copyright ⌐ 1992 Northwestern University Institute for the Learning Sciences
- ;; All Rights Reserved
- ;;
- ;; author: Michael S. Engber
- ;;
- ;; Class of triple buffer screen buffers for doing smooth animation
- ;;
- ;; It's currently pretty nasty code, not for public consumption. Various things
- ;; which are easier to use will be built on top of it.
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (oou-dependencies :WMgr-view
- :simple-view-ce
- :GWorld-view
- :QuickDraw-u)
-
- (export '())
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defclass screen-3buf ()
-
- ((s3buf-position :initarg :s3buf-position
- :reader s3buf-position)
- (s3buf-size :initarg :s3buf-size
- :reader s3buf-size)
- (saved-GW-view :accessor saved-GW-view)
- (image-GW-view :accessor image-GW-view)
- (scrap-GW-view :accessor scrap-GW-view))
-
- (:default-initargs
-
- ))
-
- (defmethod initialize-instance :after ((s3b screen-3buf) &rest initargs)
- (declare (ignore initargs))
- (setf (saved-GW-view s3b) (make-instance 'GWorld-view
- :view-position (s3buf-position s3b)
- :view-size (s3buf-size s3b)
- :GW-depth 0))
- (setf (image-GW-view s3b) (make-instance 'GWorld-view
- :view-position (s3buf-position s3b)
- :view-size (s3buf-size s3b)
- :GW-depth 0))
- (setf (scrap-GW-view s3b) (make-instance 'GWorld-view
- :view-position (s3buf-position s3b)
- :view-size (s3buf-size s3b)
- :GW-depth 0
- :GW-init-flags #.(+ (ash 1 #$useTempMem) (ash 1 #$pixPurge))
- )))
-
-
- (defmethod s3buf-alloc ((s3b screen-3buf))
- (GWorld-alloc (saved-GW-view s3b))
- (GWorld-alloc (image-GW-view s3b))
- (GWorld-alloc (scrap-GW-view s3b))
- (s3buf-screen-to-saved s3b)
- (s3buf-saved-to-image s3b))
-
- (defmethod s3buf-dispose ((s3b screen-3buf))
- (GWorld-free (saved-GW-view s3b))
- (GWorld-free (image-GW-view s3b))
- (GWorld-free (scrap-GW-view s3b)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;buffer drawing fns
-
- (defmethod s3buf-draw-to-saved ((s3b screen-3buf) draw-fn)
- (with-slots (saved-GW-view) s3b
- (with-focused-view saved-GW-view
- (funcall draw-fn s3b (pref (GWorld saved-GW-view) :CGrafPort.portRect)))))
-
- (defmethod s3buf-draw-to-image ((s3b screen-3buf) draw-fn)
- (with-slots (image-GW-view) s3b
- (with-focused-view image-GW-view
- (funcall draw-fn s3b (pref (GWorld image-GW-view) :CGrafPort.portRect)))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;buffer <-> screen copy fns
-
- (defmethod s3buf-screen-to-saved ((s3b screen-3buf) &key (copy-rgn (%null-ptr)))
- (with-slots (saved-GW-view) s3b
- (with-macptrs ((r (pref (GWorld saved-GW-view) :CGrafPort.portRect)))
- (with-focused-view saved-GW-view
- (#_CopyBits (view-portBits *WMGr-view*) (view-portBits saved-GW-view) r r #$srcCopy copy-rgn)))))
-
- (defmethod s3buf-saved-to-image ((s3b screen-3buf) &key (copy-rgn (%null-ptr)))
- (with-slots (saved-GW-view image-GW-view) s3b
- (with-macptrs ((r (pref (GWorld saved-GW-view) :CGrafPort.portRect)))
- (with-locked-GWorld-view saved-GW-view
- (with-focused-view image-GW-view
- (#_CopyBits (view-portBits saved-GW-view) (view-portBits image-GW-view) r r #$srcCopy copy-rgn))))))
-
- (defmethod s3buf-saved-to-screen ((s3b screen-3buf) &key (copy-rgn (%null-ptr)))
- (with-slots (saved-GW-view) s3b
- (with-macptrs ((r (pref (GWorld saved-GW-view) :CGrafPort.portRect)))
- (with-locked-GWorld-view saved-GW-view
- (with-focused-view *WMGr-view*
- (#_CopyBits (view-portBits saved-GW-view) (view-portBits *WMGr-view*) r r #$srcCopy copy-rgn))))))
-
- (defmethod s3buf-image-to-screen ((s3b screen-3buf) &key (copy-rgn (%null-ptr)))
- (with-slots (image-GW-view) s3b
- (with-macptrs ((r (pref (GWorld image-GW-view) :CGrafPort.portRect)))
- (with-locked-GWorld-view image-GW-view
- (with-focused-view *WMGr-view*
- (#_CopyBits (view-portBits image-GW-view) (view-portBits *WMGr-view*) r r #$srcCopy copy-rgn))))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;buffer moving functions - very complicated - very ugly
- ;;
- ;; There are basically 2 concepts when repositioning a screen buffer:
- ;;
- ;; - sliping: Buffered rect changes but the saved bits don't change position.
- ;; Imagine, the frame of the buffer slipping over the screen to a new position.
- ;;
- ;; - moving: Buffered rect changes and the bits move with it.
- ;; Imagine, the frame of the buffer moving to a new position carrying the bits
- ;; with it as it goes - like a window does when you move it.
- ;;
- ;; Slipping is useful if you're buffering the screen for the draging some region
- ;; around. You need to move your buffer to reflect the new position of the object,
- ;; but the background bits you're saving don't move.
- ;;
- ;; Moving is useful if you're buffering the contents of a window and the window
- ;; moves. Also, when draging an object around, the bits in the region corresponding
- ;; to the object being dragged should be moved (the rest of the bits should slip)
-
- (defmethod s3buf-reposition ((s3b screen-3buf) topLeft botRight
- &key
- (restore-old-rgn-p nil)
- (saved-xfer-mode :slip)
- (image-xfer-mode :move)
- (image-sub-rgn (%null-ptr))
- (sub-rgn-new-pos nil))
- (declare (dynamic-extent s3b topLeft botRight restore-old-rgn-p saved-xfer-mode image-xfer-mode image-sub-rgn sub-rgn-new-pos))
- (with-slots (saved-GW-view image-GW-view scrap-GW-view) s3b
- (let ((old-pos (s3buf-position s3b)))
- (declare (dynamic-extent old-pos))
- (rlet ((old-r :Rect
- :topLeft old-pos
- :botRight (add-points old-pos (s3buf-size s3b)))
- (new-r :Rect
- :topLeft topLeft
- :botRight botRight))
-
- (setf (slot-value s3b 's3buf-position) topLeft)
- (setf (slot-value s3b 's3buf-size) (subtract-points botRight topLeft))
-
- ;;get the scrap GWorld ready to use
- (#_NoPurgePixels (#_GetGWorldPixMap (GWorld scrap-GW-view)))
- (GWorld-set-portRect scrap-GW-view old-r)
-
- ;;;;;;;;;;;
- ;;saved bits
- (ecase saved-xfer-mode
- (:none )
- (:slip (s3buf-slip-GW saved-GW-view scrap-GW-view old-r new-r))
- (:move (s3buf-move-GW saved-GW-view scrap-GW-view old-r new-r)))
-
- (when restore-old-rgn-p
- (with-macptrs ((old-rgn (#_NewRgn))
- (quayle-rgn (#_NewRgn)))
- (unwind-protect
- (with-locked-GWorld-view scrap-GW-view
- (with-focused-view *WMGr-view*
- (#_RectRgn quayle-rgn new-r)
- (#_RectRgn old-rgn old-r)
- (#_DiffRgn old-rgn quayle-rgn old-rgn)
- (#_CopyBits (view-portBits scrap-GW-view) (view-portBits *WMGr-view*) old-r old-r #$srcCopy old-rgn)))
- (#_DisposeRgn old-rgn)
- (#_DisposeRgn quayle-rgn))))
-
-
- ;;;;;;;;;;;
- ;;image bits
- (ecase image-xfer-mode
- (:none )
- (:slip (s3buf-slip-GW image-GW-view scrap-GW-view old-r new-r))
- (:move
- (rlet ((old-image-r :Rect)
- (new-image-r :Rect))
-
- ;;prepare the copy rects and regions
- (if (handlep image-sub-rgn)
- (let ((delta (if sub-rgn-new-pos
- (subtract-points sub-rgn-new-pos (href image-sub-rgn :Region.rgnBBox.topLeft))
- (subtract-points topLeft old-pos))))
- (declare (dynamic-extent delta))
- (pset old-image-r :Rect.topLeft (href image-sub-rgn :Region.rgnBBox.topLeft))
- (pset old-image-r :Rect.botRight (href image-sub-rgn :Region.rgnBBox.botRight))
- (#_OffsetRgn :pointer image-sub-rgn :long delta)
- (pset new-image-r :Rect.topLeft (href image-sub-rgn :Region.rgnBBox.topLeft))
- (pset new-image-r :Rect.botRight (href image-sub-rgn :Region.rgnBBox.botRight)))
- (let ((delta (subtract-points topLeft old-pos)))
- (declare (dynamic-extent delta))
- (pset old-image-r :Rect old-r)
- (pset new-image-r :Rect old-r)
- (#_OffsetRect :pointer new-image-r :long delta)))
-
- (s3buf-dup-and-resize image-GW-view scrap-GW-view old-r new-r)
- (s3buf-saved-to-image s3b)
- (with-locked-GWorld-view scrap-GW-view
- (with-focused-view image-GW-view
- (#_CopyBits (view-portBits scrap-GW-view) (view-portBits image-GW-view) old-image-r new-image-r #$srcCopy image-sub-rgn)))))))
-
- (#_AllowPurgePixels (#_GetGWorldPixMap (GWorld scrap-GW-view)))))
-
- t)
-
-
- (defun s3buf-dup-and-resize (gw-view gw-view-copy old-r new-r)
- (with-locked-GWorld-view gw-view
- (with-focused-view gw-view-copy
- (#_CopyBits (view-portBits gw-view) (view-portBits gw-view-copy) old-r old-r #$srcCopy (%null-ptr))))
- (GWorld-set-portRect gw-view new-r)
- t)
-
- (defun s3buf-slip-GW (gw-view temp-gw-view old-r new-r)
-
- (s3buf-dup-and-resize gw-view temp-gw-view old-r new-r)
-
- (rlet ((sect-r :Rect))
- (#_SectRect old-r new-r sect-r)
-
- (with-locked-GWorld-view temp-gw-view
- (with-focused-view gw-view
-
- ;;copy fresh bits in from the screen
- (#_CopyBits (view-portBits *WMGr-view*) (view-portBits gw-view) new-r new-r #$srcCopy (%null-ptr))
-
- ;;copy overlapping/reusable bits
- (#_CopyBits (view-portBits temp-gw-view) (view-portBits gw-view) sect-r sect-r #$srcCopy (%null-ptr)))))
- t)
-
-
- (defun s3buf-move-GW (gw-view temp-gw-view old-r new-r)
-
- (s3buf-dup-and-resize gw-view temp-gw-view old-r new-r)
-
- (rlet ((r :Rect))
- (pset r :Rect old-r)
- (let ((delta (subtract-points (pref new-r :Rect.topLeft) (pref old-r :Rect.topLeft))))
- (declare (dynamic-extent delta))
- (#_OffsetRect :pointer r :long delta))
-
- (with-locked-GWorld-view temp-gw-view
- (with-focused-view gw-view
-
- ;;copy fresh bits in from the screen
- (#_CopyBits (view-portBits *WMGr-view*) (view-portBits gw-view) new-r new-r #$srcCopy (%null-ptr))
-
- ;;copy overlapping/reusable bits
- (#_CopyBits (view-portBits temp-gw-view) (view-portBits gw-view) old-r r #$srcCopy (%null-ptr)))))
- t)
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defun erase-screen-buf-gWorld (gw-view &key (region nil) (rect nil))
- ;;erases the specified region or rectangle of a GWorld view using the background
- ;;pattern (including pattern alignment) and back/fore colors of the current port.
- (with-macptrs ((cur-port (%getport))
- (rgn (if (handlep region) region (#_NewRgn))))
- (unwind-protect
- (rlet ((rgb-fore :RGBColor)
- (rgb-back :RGBColor))
- (#_GetForeColor rgb-fore)
- (#_GetBackColor rgb-back)
- (unless (handlep region)
- (#_RectRgn rgn (if (pointerp rect) rect (pref (GWorld gw-view) :CGrafPort.portRect))))
-
- ;;need to draw the rgn in local coord to ensure pattern alginment - yuck!
- (let* ((old-rgn-tl (href rgn :Region.rgnBBox.topLeft))
- (new-rgn-tl (rlet ((pt_p :Point old-rgn-tl))
- (#_GlobalToLocal pt_p)
- (subtract-points (%get-point pt_p) (pref cur-port :GrafPort.portRect.topLeft))))
- (old-origin (view-origin gw-view))
- (new-origin (add-points old-origin (subtract-points new-rgn-tl old-rgn-tl))))
-
- (with-focused-view gw-view
- (with-fore-color (rgb-to-color rgb-fore)
- (with-back-color (rgb-to-color rgb-back)
- (move-region-to rgn new-rgn-tl)
- (GWorld-set-origin gw-view new-origin)
- (if (wptr-color-p cur-port)
- (with-back-pix-pat (pref cur-port :CGrafPort.bkPixPat) (#_EraseRgn rgn))
- (with-back-pat (pref cur-port :GrafPort.bkPat) (#_EraseRgn rgn)))
- (GWorld-set-origin gw-view old-origin)
- (move-region-to rgn old-rgn-tl))))))
-
- (unless (handlep region) (#_DisposeRgn rgn))))
- t)
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- #|
-
-
- example code can be found in kinesis-u
-
-
- |#