MODULE BLACKHOLE;
(*----------------------------------------------------------------------------
 * System-Version: MOS 3.5
 *----------------------------------------------------------------------------
 * Version       : 1.0
 *----------------------------------------------------------------------------
 * Text-Version  : V#00041
 *----------------------------------------------------------------------------
 * Modul-Holder  : Meinolf Schneider
 *----------------------------------------------------------------------------
 * Copyright July 1990 by Digital Art Meinolf Schneider
 *----------------------------------------------------------------------------
 * MS  : Meinolf Schneider
 *----------------------------------------------------------------------------
 * Datum    Autor Version Bemerkung (Arbeitsbericht)
 *----------------------------------------------------------------------------
 * 23.07.90 MS    1.0     Grundversion
 *----------------------------------------------------------------------------
 * MODUL-BESCHREIBUNG:
 * -------------------
 * Accessory, bei dem das Icon fr den Papierkorb in ein schwarzes Loch
 * gendert wird, das sich bei Selektierung dreht.
 *----------------------------------------------------------------------------
 *) (*$C-,M-,R-,S-,N+,L-*)


FROM    System          IMPORT  BYTE, ADDRESS;

FROM    MSSystems       IMPORT  EnterSuperVisorMode;


CONST   (* Zugriffoffsets fr LineA-Variablen *)
        V_REZ_HZ           =       -$C;
        V_REZ_VT           =       -$4;
        BytesOfOneLine     =         2;


TYPE    Bool            =       BYTE; (* $00 = FALSE oder $FF = TRUE *)

        Handle          =       POINTER TO ADDRESS;

        ObjectFlags     =       ( selectable, default, isexit, editable,
                                  rbutton, lastob, touchexit, hidetree,
                                  indirect );
        ObjectStates    =       ( selected, crossed, checked, disabled,
                                  outlined, shadowed, draw3d, whitebak,
                                  fe1, fe2 );

        ObjectRec       =       RECORD
                                  next          : CARDINAL;
                                  head          : CARDINAL;
                                  tail          : CARDINAL;
                                  typ           : CARDINAL;
                                  flags         : SET OF ObjectFlags;
                                  state         : SET OF ObjectStates;
                                  spec          : ADDRESS;
                                  x             : INTEGER;
                                  y             : INTEGER;
                                  width         : CARDINAL;
                                  height        : CARDINAL;
                                END;

        IconBlk         =       RECORD
                                  pmask         : ADDRESS;
                                  pdata         : ADDRESS;
                                  ptext         : ADDRESS;
                                  chr           : CARDINAL;
                                  xchr          : INTEGER;
                                  ychr          : INTEGER;
                                  xicon         : INTEGER;
                                  yicon         : INTEGER;
                                  wicon         : INTEGER;
                                  hicon         : INTEGER;
                                  xtext         : INTEGER;
                                  ytext         : INTEGER;
                                  wtext         : INTEGER;
                                  htext         : INTEGER;
                                  reserved      : INTEGER;
                                END;




VAR     (* Felder fr AES-Aufrufe *)
        control                         : ARRAY[1..5] OF INTEGER;
        global                          : ARRAY[1..15] OF INTEGER;
        intin                           : ARRAY[1..16] OF INTEGER;
        intout                          : ARRAY[1..7] OF INTEGER;
        addrin                          : ARRAY[1..3] OF ADDRESS;
        addrout                         : ADDRESS;
        AESPB                           : ARRAY[1..6] OF ADDRESS;


        DesktopObjectTreeHdl            : Handle;
        (* Zeiger auf Variable mit Zeiger auf Desktopobjektbaum *)
        
        DesktopObjectTree               : ADDRESS;
        (* Zeiger auf Desktop-Objektbaum *)
        
        TrashObjectPtr                  : ADDRESS;
        (* Zeiger auf das Papierkorbobjekt *)
        
        TrashIconMask, TrashIconData    : ADDRESS;
        (* Zeiger auf die entsprechenden Bilddaten des Papierkorbs *)
        
        OldTrashState                   : SET OF ObjectStates;
        
        MustDrawTrash                   : Bool;
        (* Wird auf TRUE gesetzt, wenn ein FORM_DIAL durchgefhrt werden mu *)
        
        BytesOfLine                     : CARDINAL;
        IsSM124                         : Bool;
        (* TRUE = ist monochrome Modus => Zeilensynchronisation mglich! *)
        
        HoleAniPhase                    : CARDINAL;
        (* Animationszhler *)



TABLE.L         (* NEUE ICONS FR DEN PAPIERKORB *)
StillHole:      $00000000, $00000000, $00000000, $00008000,
                $00008000, $0001C000, $0001C000, $0009C800,
                $00C1C180, $00EBEB80, $007FFF00, $003FFE00,
                $017FFF40, $003FFE00, $007FFF00, $07FFFFF0,
                $1FFFFFFC, $07FFFFF0, $007FFF00, $003FFE00,
                $017FFF40, $003FFE00, $007FFF00, $00EBEB80,
                $00C1C180, $0009C800, $0001C000, $0001C000,
                $00008000, $00008000, $00000000, $00000000;
                
MotionHole1:    $00000000, $00000000, $00000000, $00000000,
                $0000C300, $00FC6380, $03FF71C0, $07FF31C0,
                $0F0FF8E0, $0C0FF8E0, $003FFCE0, $00FFFCE0,
                $03FFFFE0, $07FFFFE0, $0EFFFFC0, $08FFFFC0,
                $03FFFF10, $03FFFF70, $07FFFFE0, $07FFFFC0,
                $073FFF00, $073FFC00, $071FF030, $071FF0F0,
                $038CFFE0, $038EFFC0, $01C63F00, $00C30000,
                $00000000, $00000000, $00000000, $00000000;
                
MotionHole2:    $00000000, $00000000, $00000000, $000E0000,
                $003F8000, $007FE000, $0061F300, $00007B00,
                $0000FB00, $00FFF998, $03FFFF98, $003FFF98,
                $00FFFF9C, $01FFFF1C, $07FFFF1C, $07FFFF3C,
                $0FFFFFF8, $0E3FFFF8, $1E7FFFF0, $1C7FFFF0,
                $1C7FFFC0, $0C7FFE00, $0C7FFF60, $0C67FFE0,
                $00778780, $00378000, $0033E000, $0003FF80,
                $0000FF00, $00003800, $00000000, $00000000;
       
MotionHole3:    $00000000, $00000000, $00000000, $00007000,
                $00007C00, $000E0E00, $0007C700, $0073C300,
                $01FFE780, $07FFFF80, $0FFFFFB0, $0F3FFF30,
                $1C7FFF60, $18FFFFE0, $19FFFFE0, $19FFFFC0,
                $01FFFF98, $03FFFF18, $037FFF38, $037FFC70,
                $00FFFFF0, $00FFFFE0, $00F7FFC0, $0071EF00,
                $0070F000, $00387800, $003C1800, $001F0000,
                $00078000, $00000000, $00000000, $00000000;
               

PROCEDURE LineSync ( BottomLineNo       : CARDINAL );
BEGIN
  ASSEMBLER
  tst.b         IsSM124
  beq.w         ED
  
  jsr           EnterSuperVisorMode
  move.w        -(A3),D1
  mulu          BytesOfLine,D1
  move.l        #$FF8201,A0
  clr.l         D0
  movep.w       0(A0),D0
  lsl.l         #8,D0
  move.b        $C(A0),D0       ; Video Base
  add.l         D1,D0
  move.l        $466,D2
 
 !WaitTopOfLine
  move.l        $466,D1
  sub.l         D2,D1
  cmpi.w        #3,D1
  bhi           WaitEnd
  clr.l         D1
  movep.w       4(A0),D1
  lsl.l         #8,D1
  move.b        $8(A0),D1       ; Video Address Counter
  cmp.l         D0,D1
  bhi           WaitTopOfLine
 
  move.l        $466,D2
 
 !WaitBottomOfLine
  move.l        $466,D1
  sub.l         D2,D1
  cmpi.w        #3,D1
  bhi           WaitEnd
  clr.l         D1
  movep.w       4(A0),D1
  lsl.l         #8,D1
  move.b        $8(A0),D1       ; Video Address Counter
  cmp.l         D0,D1
  bcs           WaitBottomOfLine
 
 !WaitEnd
  andi.w        #$DFFF,SR
 !ED
  END;
END LineSync;



PROCEDURE SetStillHole;
BEGIN
  ASSEMBLER
  st            MustDrawTrash
  lea           StillHole,A2
  move.l        TrashIconMask,A0
  move.l        TrashIconData,A1
  move.w        #31,D0
 !CopyIcon
  move.l        (A2),(A0)+
  move.l        (A2)+,(A1)+
  dbf           D0,CopyIcon
  END;
END SetStillHole;


               
BEGIN
  ASSEMBLER
  ; APPL_INIT
  lea           control,A0
  move.w        #10,(A0)
  clr.w         2(A0)
  move.w        #1,4(A0)
  clr.w         6(A0)
  clr.w         8(A0)
  
  lea           AESPB,A0
  move.l        #control,(A0)+
  move.l        #global,(A0)+
  move.l        #intin,(A0)+
  move.l        #intout,(A0)+
  move.l        #addrin,(A0)+
  move.l        #addrout,(A0)+
  
  move.l        #AESPB,D1
  move.w        #200,D0
  trap          #2              ; AES-Aufruf
  
  
  ; MENU_REGISTER
  lea           control,A0
  move.w        #35,(A0)
  move.w        #1,2(A0)
  move.w        #1,4(A0)
  move.w        #1,6(A0)
  clr.w         8(A0)
  lea           intin,A0
  lea           global,A1
  move.w        4(A1),(A0)
  pea           copyright(PC)
  move.l        (A7)+,addrin
  move.l        #AESPB,D1
  move.w        #200,D0
  trap          #2              ; AES-Aufruf
  bra           goon
 !copyright
  acz           'BH 1990 M.Schneider'
  sync
 !goon
  
  
  ; TOS-Version ermitteln, wodurch sich die Variable mit dem Zeiger
  ; auf die aktuelle Desktop-Objektliste ergibt.
  jsr           EnterSuperVisorMode
  move.l        $4F2,A0
  move.w        $2(A0),D1       ; D1 = TOSVersion
  move.l        24(A0),D2       ; D2 = Erstellungsdatum
  clr.l         DesktopObjectTreeHdl
  cmpi.w        #$0100,D1
  bne           NoTOS10
  move.l        #$A0C4,DesktopObjectTreeHdl
  bra           TOSOk
 !NoTOS10
  cmpi.w        #$0102,D1
  bne           NoTOS12
  move.l        #$C942,DesktopObjectTreeHdl
  bra           TOSOk
 !NoTOS12
  cmpi.w        #$0104,D1
  bne           NoTOS14
  cmpi.l        #$08081988,D2
  bne           IsNewTOS14
  move.l        #$71E2,DesktopObjectTreeHdl     ; TOS 1.4 vom 8.8.88
  bra           TOSOk
 !IsNewTOS14
  move.l        #$6E38,DesktopObjectTreeHdl     ; TOS 1.4 > 8.8.88 z.B. 6.4.89
  bra           TOSOk
 !NoTOS14
  cmpi.w        #$0106,D1
  bne           NoTOS16
  cmpi.l        #$06191989,D2
  bne           IsNewTOS16
  move.l        #$6E3C,DesktopObjectTreeHdl     ; altes TOS 1.6
  bra           TOSOk
 !IsNewTOS16
  move.l        #$6E7C,DesktopObjectTreeHdl     ; neues TOS 1.6 v. 29.7.90
 !NoTOS16
 !TOSOk
  andi.w        #$DFFF,SR       ; SuperMode verlassen
  
  dc.w          $A000
  move.w        BytesOfOneLine(A0),BytesOfLine
  sf            IsSM124
  cmpi.w        #400,V_REZ_VT(A0)
  bne           IsNoSM124
  cmpi.w        #640,V_REZ_HZ(A0)
  bne           IsNoSM124
  st            IsSM124
 !IsNoSM124
  
  lea           StillHole,A0
  lea           MotionHole1,A0
  lea           MotionHole2,A0
  lea           MotionHole3,A0  ; wegen optimierenden Linker!
  END;
  
  
  REPEAT
    ASSEMBLER
    ; EVNT_TIMER
    lea           control,A0
    move.w        #24,(A0)
    move.w        #2,2(A0)
    move.w        #1,4(A0)
    clr.w         6(A0)
    clr.w         8(A0)
    
    lea           intin,A0
    move.w        #100,(A0)       ; 100 Millisekunden fr andere Prozesse...
    move.w        #0,2(A0)
    
    move.l        #AESPB,D1
    move.w        #200,D0
    trap          #2              ; AES-Aufruf
    
    
    tst.l         TrashObjectPtr
    bne           IHaveTheTrashObject
    
    tst.l         DesktopObjectTreeHdl
    beq.w         UnknownTOS
    move.l        DesktopObjectTreeHdl,A0
    tst.l         (A0)
    beq.w         ThatsNotTheDesktopObjectTree
    
   !SearchTrash
    ; Suchen des Papierkorbobjekts, es ist das erste Icon-Objekt in der Liste
    move.l        DesktopObjectTreeHdl,A0
    move.l        (A0),A0
    move.l        A0,DesktopObjectTree
    
   !NoTrashFound
    lea           2(A0),A0
    cmpi.l        #$FFFF001F,(A0)
    bne           NoTrashFound
    subq.l        #4,A0
    move.l        A0,TrashObjectPtr
    move.l        ObjectRec.spec(A0),A0
    move.l        IconBlk.pmask(A0),TrashIconMask
    move.l        IconBlk.pdata(A0),TrashIconData
    
    ; ... und gleich mal das Icon ndern:
    jsr           SetStillHole
    
   !IHaveTheTrashObject
    move.l        DesktopObjectTreeHdl,A1
    tst.l         (A1)
    beq.w         ThatsNotTheDesktopObjectTree
    move.l        DesktopObjectTree,A0
    cmpa.l        (A1),A0
    bne.w         SearchTrash                  ; Objektbaum wurde neu erstellt!
    
    move.l        TrashObjectPtr,A0
    move.w        ObjectRec.state(A0),D0
    btst          #selected,D0
    beq           TrashIsNotSelected
    move.w        D0,OldTrashState
   
    ; Papierkorb ist selektiert, also animieren. Da selektierte Icons
    ; invertiert werden, mu das neue Icon ebenfalls invertiert werden,
    ; damit es hinterher wieder normal aussieht.
    addq.w        #1,HoleAniPhase
    cmpi.w        #3,HoleAniPhase
    bne           NoAniRestart
    clr.w         HoleAniPhase
   !NoAniRestart
    move.w        HoleAniPhase,D1
    add.w         D1,D1
    lea           MotionHole1,A2
    adda.w        HoleAniOffsets(PC,D1.W),A2
    move.l        TrashIconData,A0
    move.l        TrashIconMask,A1
    move.w        #31,D0
   !CopyMotionHole
    move.l        (A2)+,(A1)+
    clr.l         (A0)+
    dbf           D0,CopyMotionHole
    st            MustDrawTrash
    bra           DrawTrash
   !HoleAniOffsets
    dc.w          0,128,256
   
   
   !TrashIsNotSelected
    move.w        OldTrashState,D0
    btst          #selected,D0
    beq           TrashWasNotSelected
    
    move.l        TrashObjectPtr,A0
    move.w        ObjectRec.state(A0),D0
    btst          #selected,D0
    bne           TrashStillSelected
    
    move.w        D0,OldTrashState
    jsr           SetStillHole
    
   !TrashStillSelected
   !TrashWasNotSelected
   !DrawTrash
    tst.b         MustDrawTrash
    beq.w         NoTrashDraw
    sf            MustDrawTrash
    
    ; WIND_UPDATE (BEGIN)
    lea           control,A0
    move.w        #107,(A0)
    move.w        #1,2(A0)
    move.w        #1,4(A0)
    clr.w         6(A0)
    clr.w         8(A0)
    lea           intin,A0
    move.w        #1,(A0)
    move.l        #AESPB,D1
    move.w        #200,D0
    trap          #2              ; AES-Aufruf
    
    
    ; FORM_DIAL
    lea           control,A0
    move.w        #51,(A0)
    move.w        #9,2(A0)
    move.w        #1,4(A0)
    clr.w         6(A0)
    clr.w         8(A0)
    
    lea           intin,A0
    move.w        #3,(A0)
    move.w        #0,2(A0)
    move.w        #0,4(A0)
    move.w        #0,6(A0)
    move.w        #0,8(A0)
    move.l        TrashObjectPtr,A1
    move.w        ObjectRec.x(A1),10(A0)
    move.w        ObjectRec.y(A1),12(A0)
    move.w        ObjectRec.width(A1),14(A0)
    move.w        ObjectRec.height(A1),16(A0)
    
    move.w        ObjectRec.y(A1),(A3)+
    jsr           LineSync
    
    move.l        #AESPB,D1
    move.w        #200,D0
    trap          #2              ; AES-Aufruf
    
    ; WIND_UPDATE (END)
    lea           control,A0
    move.w        #107,(A0)
    move.w        #1,2(A0)
    move.w        #1,4(A0)
    clr.w         6(A0)
    clr.w         8(A0)
    lea           intin,A0
    move.w        #0,(A0)
    move.l        #AESPB,D1
    move.w        #200,D0
    trap          #2              ; AES-Aufruf
   
   
   !UnknownTOS
   !NoTrashDraw
   !ThatsNotTheDesktopObjectTree
    END;
  
  UNTIL FALSE;

END BLACKHOLE.
