;*************************************************************************
;*  NB: SAVE THIS FILE FROM FULLVIEW'S MENU BEFORE USING, TO DE-CRUNCH IT
;*  PROGRAM:        CW-Example.asm
;*
;*  AUTHOR:         Mike Fuller
;*                  4 Sonego Ave
;*                  Kelmscott
;*                  W.A.  6111
;*                  (09) 390 9350
;*
;*                  The ColourWindow code was ported from the C program
;*                  written by Anders Bjerin of the Amiga C Club.
;*
;*                  Public Domain - NO RIGHTS RESERVED
;*
;*  DATE:           July 12, 1991
;*
;*  DESCRIPTION:    This is a program to create a multi-colour display
;*                  and demonstrate the use of the ColourWindow requester.
;*                  This program is certainly not fancy but was written
;*                  simply to show how to call the requester from within
;*                  a program. It will open a high-res, interlaced screen
;*                  and window, draw a set of intersecting lines (showing
;*                  moire patterns), and wait for you to click in the
;*                  window.  It will then open the ColourWindow requester.
;*                  Play with the ColourWindow gadgets and click on the
;*                  OK or CANCEL gadgets or the CLOSEWINDOW gadget to
;*                  close the ColourWindow requester.  Another mouseclick
;*                  in the main window should bring it back.
;*                  Close the main window, after closing the ColourWindow,
;*                  to exit from the program.
;*
;*  COLOURWINDOW:   To call the ColourWindow requester from your program
;*                  you need:
;*                          A pointer to the screen in register A0
;*                          A pointer to the ColourWindow title in A1
;*                          The X (left) position of the window in D0
;*                          The Y (top) position of the window in D1
;*                  If you are working from the workbench screen, pass 0
;*                  in A0.  If you want the default title (Colour Window),
;*                  pass 0 in A1.
;*                  If the X and Y coordinates will not allow the window
;*                  to fit on the screen, they will be adjusted to open
;*                  the window as close as possible to the given values.
;*                  The success or failure of the window opening will be
;*                  returned in D0.  If successful, 0 will be returned.
;*                  If the window could not be opened (eg. no memory),
;*                  a 5 will be returned.
;*                  All memory will be returned to the system after the
;*                  window is closed and registers A2-A7 and D2-D7 will
;*                  remain intact.  I consider A0, A1, D0 and D1 as
;*                  scratch registers and their contents will be trashed.
;*
;*  LEGAL:          This program is public domain with NO RIGHTS RESERVED
;*                  and may be used freely by anyone.  Although it has
;*                  worked well for me, no responsibility is accepted for
;*                  any damage the program may cause.
;*                  Any bug reports, suggestions, improvements (there are
;*                  probably heaps) or interest in organising or
;*                  assisting with an Amiga Assembly Association
;*                  (can you think of a better name for starters?)
;*                  please contact me at the above address.
;*

;**************************** INCLUDE ************************************
;*
;*      INCLUDE FILES - I have these files in a directory which I assign
;*                      as INCLUDE: in my startup-sequence.
;*                      To enable this to work using the A68K assembler,
;*                      assemble using the -i option.
;*                      (eg. A68k CW-Example.asm -iINCLUDE: ) 

        INCLUDE "intuition/intuition.i"
        INCLUDE "macros"


;**************************** MACROS *************************************
;*
;*      These are extra macros which speed up the drawing process slightly
;*      and speed up the coding considerably.
;*      They rely on the rastport remaining in register A1, and are
;*      only really meant to be used in this program.
;*      My usual macros are contained in the 'Macros' file, which should
;*      accompany this program, the ColourWindow source code, this
;*      program's executable and the ColourWindow.Doc file.
;*      

Penset  MACRO
        move.w  d6,d0               ;colour
        Syslib  SetAPen             ;set pen colour
        ENDM

;*      eg. Penset

Posit   MACRO
        move.w  d2,d0               ;x position
        move.w  d3,d1               ;y position
        Syslib  Move                ;position pen
        ENDM

;*      eg. Posit

Line    MACRO
        move.w  d4,d0               ;x position
        move.w  d5,d1               ;y position
        Syslib  Draw                ;draw line
        ENDM

;*      eg. Line

Drawloop MACRO
Loop\@:
        Posit                       ;position at centre
        Line                        ;draw line
        subq    #1,d6               ;colour
        bne     Nexcol\@            ;next step if more colours left
        moveq   #15,d6              ;else, renew colours
Nexcol\@:
        Penset                      ;set colour
        subq    #1,\1               ;1 less
        cmp.l   \2,\1               ;reached minimum?
        bge     Loop\@              ;if not, next line
        ENDM

;*      eg. Drawloop  d5,#0

Drawsquare MACRO
        move.w  #\1,d2              ;x centre
        move.w  #\2,d3              ;y centre
        move.w  #\3,d4              ;x maximum
        move.w  #\4,d5              ;y maximum
        move.l  #\5,a3              ;x minimum
        move.l  #\6,a4              ;y minimum

        Drawloop d5,a4              ;first quarter
        Drawloop d4,a3              ;second quarter
        move.w   #\3,d4             ;x maximum
        move.w   #\4,d5             ;y maximum
        Drawloop d4,a3              ;third quarter
        Drawloop d5,a4              ;fourth quarter
        ENDM

;*      eg. Drawsquare 100,100,200,200,0,0


;**************************** EXTERNAL REFERENCES ************************
;*
;*      Use the _LVO form of these system calls rather than the actual
;*      offsets, which can change with new operating systems.
;*      Link with amiga.lib to then convert to offset values.

        XDEF    Intbase             ;* Intuition library pointer
        XDEF    Graphbase           ;* Graphics library pointer

        XREF    _AbsExecBase        ;* Exec library pointer
        XREF    _LVOExit            ;* Clean exit from program
        XREF    _LVOOpenLibrary     ;* Open a system library
        XREF    _LVOCloseLibrary    ;* Close a system library
        XREF    _LVOOpenWindow      ;* Open a window
        XREF    _LVOCloseWindow     ;* Close a window
        XREF    _LVOOpenScreen      ;* Open a screen
        XREF    _LVOCloseScreen     ;* Close a screen
        XREF    _LVOMove            ;* Position drawing pen
        XREF    _LVODraw            ;* Draw line to position
        XREF    _LVOSetAPen         ;* Set foreground pen colour
        XREF    _LVOSetDrMd         ;* Set the drawing mode
        XREF    _LVOSetRGB4         ;* Change a colour
        XREF    _LVOWait            ;* Wait for intuition message
        XREF    _LVOGetMsg          ;* Get intuition message
        XREF    _LVOReplyMsg        ;* Reply to intuition message

        XREF    ColourWindow        ;* Colour window requester


        SECTION "Graphic",CODE

;**************************** CONSTANTS **********************************

WIDTH   equ     640                 ;* Hires
HEIGHT  equ     512                 ;* Interlace
DEPTH   equ     4                   ;* 16 colours

;*      These could be used if you wanted a more elaborate error routine

DOSERR  equ     1                   ;* Error opening DOS library
GRAPHERR equ    2                   ;* Error opening Graphics library
INTERR  equ     3                   ;* Error opening Intuition library
SCREENERR equ   4                   ;* Error opening screen
WINDOWERR equ   5                   ;* Error opening window

MINX    equ     2                   ;* Maximum and minimum X and Y values
MAXX    equ     WIDTH-2             ;*      (for drawing routine)
MINY    equ     12
MAXY    equ     HEIGHT-2

;**************************** MAIN ***************************************

;*      Open the required libraries

        moveq   #0,d6               ;error flag false
        Openlib #DOSname,DOSbase    ;open DOS library
        bne     Opengraph           ;continue if successful
        bra     Finish5             ;else, shut down
Opengraph:
        Openlib #Graphname,Graphbase ;open graphics library
        bne     Openint             ;continue if successful
        bra     Finish4             ;else, shut down
Openint:
        Openlib #Intname,Intbase    ;open intuition library
        bne     Openscreen          ;continue if successful
        bra     Finish3             ;else, shut down

;*      Open a screen and window

Openscreen:
        lea     Screenstruct,a0     ;screen structure address
        Syslib  OpenScreen,Intbase  ;open screen
        move.l  d0,Screenptr        ;save pointer to screen
        beq     Finish2             ;shut down if unsuccessful

;*      Save the viewport and rastport pointers

        move.l  d0,Winscreen        ;window's pointer to screen
        add.l   #sc_ViewPort,d0     ;get screen viewport
        move.l  d0,Vport            ;and save it
        sub.l   #sc_ViewPort,d0     ;restore pointer
        add.l   #sc_RastPort,d0     ;get screen rastport
        move.l  d0,Rport            ;and save it

;*      Open a window

        lea     Winstruct,a0        ;NewWindow structure address
        Syslib  OpenWindow          ;open window
        move.l  d0,Winptr           ;save window pointer
        beq     Finish1             ;shut down if unsuccessful

;*      Set the default colours

        move.l  Graphbase,a6        ;graphics library pointer
        lea     ColourRange,a3      ;start of default colour data
        moveq   #0,d4               ;colour counter
Getcol:
        SetRGB  Vport,d4,(a3)+,(a3)+,(a3)+  ;set colour
        addq    #1,d4               ;next colour
        cmpi.l  #16,d4
        bne     Getcol              ;if more colours, set another

        move.l  Rport,a1            ;pointer to rastport
        move.b  RP_JAM1,d0          ;JAM1 draw mode
        Syslib  SetDrMd             ;set draw mode


;*      Set up and draw squares - call the Drawsquare macro with the
;*      x and y coordinates for the centre, the bottom right and the
;*      top left of the square.

        movea.l Rport,a1            ;rastport pointer
        moveq   #15,d6              ;colour counter
        Drawsquare MAXX/4,MAXY/4,MAXX/2,MAXY/2,MINX,MINY
        moveq   #14,d6              ;colour counter
        Drawsquare 3*MAXX/4,MAXY/4,MAXX,MAXY/2,MAXX/2,MINY
        moveq   #10,d6              ;colour counter
        Drawsquare MAXX/4,3*MAXY/4,MAXX/2,MAXY,MINX,MAXY/2
        moveq   #6,d6               ;colour counter
        Drawsquare 3*MAXX/4,3*MAXY/4,MAXX,MAXY,MAXX/2,MAXY/2


;*      Wait for a message to be received. (MOUSEBUTTONS or CLOSEWINDOW)

Waitmessage:

        moveq   #0,d1               ;clear register
        movea.l Winptr,a2           ;pointer to Window structure
        movea.l wd_UserPort(a2),a2  ;pointer to user port
        move.b  MP_SIGBIT(a2),d1    ;signal bit number - set up the
        moveq   #1,d0               ;   actual signal set by shifting a
        lsl.l   d1,d0               ;   1 in D0 left this number of bits
        Syslib  Wait,_AbsExecBase   ;wait for signal

;*      Get the message and save it. I could get fancy with some of the
;*      messages, such as the mouse coordinates to enable the ColourWindow
;*      to be opened in that position, but this is only a simple example.

Getmessage:
        movea.l Winptr,a0           ;pointer to Window structure
        movea.l wd_UserPort(a0),a0  ;pointer to Window's UserPort
        Syslib  GetMsg,_AbsExecBase ;get intuimessage
        tst.l   d0                  ;was message sent?
        beq     Waitmessage         ;if not, wait for next one
        move.l  d0,a1               ;else, save its pointer
        move.l  im_Class(a1),Iclass ;save IDCMP flag
        move.w  im_Code(a1),Icode   ;extra information
        move.w  im_MouseX(a1),mousex    ;mouse X position
        move.w  im_MouseY(a1),mousey    ;mouse Y position

;*      Reply to Intuition quickly.

        Syslib  ReplyMsg,_AbsExecBase   ;reply to message

;*      Check which message was sent.

        cmpi.l  #MOUSEBUTTONS,Iclass ;was mouse clicked inside window?
        bne     Winclose            ;if not, check CLOSEWINDOW
        cmpi.w  #SELECTDOWN,Icode    ;else, was left mousebutton pressed?
        bne     Getmessage          ;if not, check next message

;*      Left mousebutton pressed, open ColourWindow requester

        moveq   #0,d0               ;clear buffers
        moveq   #0,d1
        movea.l Screenptr,a0        ;this screen
        lea     Colwintitle,a1      ;title of colour window requester
        move.w  mousex,d0           ;window's x position
        move.w  mousey,d1           ;window's y position
        jsr     ColourWindow        ;open colour window requester

;*      You would normally insert an error routine in here to check
;*      for opening success or failure.  I will just branch back to
;*      check for another message.

        bra     Getmessage


Winclose:
        cmpi.l  #CLOSEWINDOW,Iclass  ;was close window gadget selected?
        bne     Getmessage          ;if not, check next message

;*      If CLOSEWINDOW clicked, close the main window and screen.

        movea.l Winptr,a0           ;pointer to Window structure
        Syslib  CloseWindow,Intbase ;close the window

;*      Close according to which items were successfully opened.
;*      (This is not an efficient error routine)

Finish1:
        movea.l Screenptr,a0        ;pointer to screen
        Syslib  CloseScreen         ;close the screen
Finish2:
        Closelib Intbase            ;close intuition library
Finish3:
        Closelib Graphbase          ;close graphics library
Finish4:
        Syslib  Exit,DOSbase        ;exit gracefully
Finish5:
        rts                         ;return to system


;**************************** DATA SECTION *******************************

        SECTION "Graphic",DATA

DOSname dc.b    'dos.library',0
Graphname dc.b  'graphics.library',0
Intname dc.b    'intuition.library',0
STitle  dc.b    'Example Screen',0
WTitle  dc.b    'Click in the window to open the requester',0
Colwintitle dc.b 'My Colour Window',0

        even

Vport   dc.l    0                   ;screen viewport
Rport   dc.l    0                   ;window rastport

Iclass  dc.l    0                   ;IDCMP flag
Icode   dc.w    0                   ;extra IDCMP information

ColourRange:
            dc.b    0,0,0,0,15,15,1,14,15,2,13,15,3,12,15,4,11,15
            dc.b    5,10,15,6,9,15,8,8,15,9,6,15,10,5,15,11,4,15,
            dc.b    12,3,15,13,2,15,14,1,15,15,0,15

mousex  dc.w    0                   ;mouse X position
mousey  dc.w    0                   ;mouse Y position

        even

DOSbase dc.l    0
Intbase dc.l    0
Graphbase dc.l  0

Screenptr dc.l  0

SModes  equ     V_HIRES|V_LACE

Screenstruct:
        dc.w    0,0                 ;left and top edges
        dc.w    WIDTH
        dc.w    HEIGHT
        dc.w    DEPTH
        dc.b    5                   ;detail pen
        dc.b    15                  ;block pen
        dc.w    SModes              ;view modes
        dc.w    CUSTOMSCREEN        ;screen type
        dc.l    0                   ;TextAttr pointer (fonts)
        dc.l    STitle              ;screen title
        dc.l    0,0                 ;gadgets and custombitmap

Winptr  dc.l    0

WFlags  equ    SMART_REFRESH|ACTIVATE|WINDOWDEPTH|WINDOWDRAG|WINDOWCLOSE

Winstruct:
        dc.w    0,0                 ;left,top edges
        dc.w    WIDTH               ;you can work these out
        dc.w    HEIGHT
        dc.b    0,1                 ;detail and block pens
        dc.l    MOUSEMOVE|MOUSEBUTTONS|CLOSEWINDOW  ;IDCMP flags
        dc.l    WFlags              ;window flags
        dc.l    0                   ;gadget pointer
        dc.l    0                   ;menu image structure
        dc.l    WTitle              ;window title
Winscreen dc.l  0                   ;pointer to screen
        dc.l    0                   ;pointer to bitmap
        dc.w    0,0,0,0             ;min and max window sizes
        dc.w    CUSTOMSCREEN        ;screen type

        END
