; X-Specs interrupt code for double-buffered 3-D animated drawings
;
; Copyright 1988 by Raymond S. Brand, All rights reserved.
;  19880830
;
;  This code is designed to be part of the Copper interrupt, Vertical Blank
;  interrupt or Software interrupt server chains. If this code is made part
;  of the Software interrupt chain, some other interrupt will need to
;  Cause() this code to be executed.
;
;  See SetLens routine for assumptions about interface to X-Specs.
;
; Theory of Operation:
;  Each time this code is invoked, it changes which lens is transparent and
;  which is opaque. If this change opens the left lens, a check is made to
;  see if the "hidden" display buffers should now be displayed and the
;  "visible" display buffers made hidden. If so, the change is made. At this
;  point, the appropriate visible buffer for the open lens is displayed
;  using LoadView().
;
; Warnings:
;  This is a brute force method of achiving 3-D double-buffered animated
;  drawings in that it requires 4 complete Views to work.
;
;  This is NOT friendly with intuition since it simply takes over the
;  display with a LoadView().
;
;  The multiple Views method of double buffering is probably NOT compatible
;  with the Amiga animation routines.
;
;  LoadView() is not listed as being safe to use durring interrupts.


        SECTION text

        NOLIST                ; no need to output this stuff

        INCLUDE "exec/types.i"
        INCLUDE "exec/libraries.i"

CALLSYS MACRO
        CALLLIB _LVO\1
        ENDM

XLIB    MACRO
        XREF    _LVO\1
        ENDM

        LIST

        XDEF    _LensInt      ; this is the start of it all....

        XREF    SetLens
        XREF    _custom

        XLIB    Signal        ; in Exec
        XLIB    LoadView      ; in Graphics

        PAGE
LEFT    equ     $00
RIGHT   equ     $80

 STRUCTURE      LensIntData,0 ; WARNING!!! This structure and the "C"
                              ;            version MUST match!!!!
        APTR    ExecLib       ; ExecBase
        APTR    GraphicsLib   ; GfxBase
        APTR    Task          ; task to signal
        LONG    SignalMask    ; signal(s) to send to task
        APTR    CurrentLeftView  ; View to LoadView() for open left lens
        APTR    CurrentRightView ; View to LoadView() for open right lens
        APTR    LeftView0     ; left lens View 0
        APTR    LeftView1     ; left lens View 1
        APTR    RightView0    ; right lens View 0
        APTR    RightView1    ; right lens View 1
        UWORD   Frame         ; which left & right Views do I want
        UBYTE   Lens          ; which lens is open
        UBYTE   Flip          ; flag to change Views

        PAGE
_LensInt:
        move.l  A1,A5         ; need A1, make A5 point to LensIntData
        cmpi.b  #LEFT,Lens(A5)   ; check current lens state
        bne.b   OpenLeftLens

OpenRightLens:
        move.b  #RIGHT,D0     ; go open the right lens
        move.b  D0,Lens(A5)   ; save as new lens state
        jsr     SetLens

        move.l  CurrentRightView(A5),A1   ; get the right View
        bra.b   CommonCode    ; go put it up

OpenLeftLens:
        move.b  #LEFT,D0      ; go open the left lens
        move.b  D0,Lens(A5)   ; save as new lens state
        jsr     SetLens

        tst.b   Flip(A5)      ; hidden buffers ready?
        beq.b   NoChange      ; nope
        clr.b   Flip(A5)      ; yes, clear flip request

        tst.w   Frame(A5)     ; determine which frame to display
        bne.b   Frame2

Frame1:
        move.l  LeftView0(A5),CurrentLeftView(A5)     ; make frame 0 display
        move.l  RightView0(A5),CurrentRightView(A5)
        move.w  #1,Frame(A5)  ; set hidden frame to 1
        bra.b   Signal        ; hop

Frame2:
        move.l  LeftView1(A5),CurrentLeftView(A5)     ; make frame 1 display
        move.l  RightView1(A5),CurrentRightView(A5)
        clr.w   Frame(A5)     ; set hidden frame to 0

Signal:
        move.l  SignalMask(A5),D0   ; signal task it can start drawing into
        move.l  Task(A5),A1         ; hidden Views
        move.l  ExecLib(A5),A6
        CALLSYS Signal

NoChange:
        move.l  CurrentLeftView(A5),A1 ; get the left View

        PAGE
CommonCode:
        move.l  GraphicsLib(A5),A6  ; LoadView the View
        CALLSYS LoadView

        moveq   #0,D0         ; let other handlers in the chain run
        lea     _custom,A0    ; I shouldn't have to do this
        rts


        END

