home *** CD-ROM | disk | FTP | other *** search
/ The AGA Experience 2 / agavol2.iso / software / utilities / programmers / misc / graphics / c / sas / graphics_base.s < prev    next >
Text File  |  1996-02-06  |  58KB  |  2,562 lines

  1. ;-------- Initialisation routines ------------------------------------------
  2. ;    Graphics_Init()        
  3. ;    Graphics_Close()
  4. ;    Open_Screen(d0,d1,d2,d3,a0)    width, height, depth, viewmodes, cmap
  5. ;    Close_Screen(a0)            screen
  6. ;    Init_Mask(d0,d1,d2,d3,d4,d5)    x_min,y_min,x_max,y_max,sreen x,screen y
  7. ;    Free_Mask(a0)            maskplane struct
  8.  
  9. ;-------- Drawing routines -------------------------------------------------
  10. ;    Fill_Polygon(a0,a1,d0,d1)      screen, vertex list, npoints, colour
  11. ;    Draw_Polygon(a0,a1,d0,d1)        screen, vertex list, npoints, colour
  12. ;    Draw_Line(a0,d0,d1,d2,d3,d4)    screen, x1, y1, x2, y2, colour        
  13. ;    Write_Pixel(a0,d0,d1,d2)        screen, x1, x2, colour
  14. ;    Screen_Clear(a0)            screen
  15. ;    Show(a0)                screen
  16.  
  17. ;-------- Fade Routines------------------------------------------------
  18. ;    Fade_To_White(a0,a1)    source screen,source colourmap
  19. ;    Fade_To_Black(a0,a1)    source screen,source colourmap
  20. ;    Fade(a0,a1,a2)        screen,source,destination
  21.  
  22. ;-------- IFF Handling routines reading and writing of bitmaps -------------
  23. ;    Save_IFF(a0,a1)=filename APTR, screen ADDR
  24. ;    Load_IFF(a0,a1)=filename APTR, screen ADDR
  25.  
  26. ;-------- File handling Routines -------------------------------------------
  27. ;    Load_Data(a0,d0,a1)        filename, buffer length, destination
  28. ;    Save_Data(a0,d0,a1)        filename, buffer length, source
  29.  
  30. ;-------- Text handling routines -------------------------------------------
  31. ;    Write_Text(a0,a1,d0,d1,d2,d3)    screen, text, x, y, colour, length
  32. ;    Num_To_String(d0)            word
  33.  
  34. ;-------- Copper  handling routines -------------------------------------
  35. ;    Add_Copper(a0,a1)        screen,copper list
  36.  
  37. ;-------- Input Handling Routines ------------------------------------------
  38. ;    GetKey()
  39.  
  40.  
  41. ;-------- Initialisation routines ------------------------------------------
  42. ;    Graphics_Init()        
  43. ;    Graphics_Close()
  44. ;    Open_Screen(d0,d1,d2,d3,a0)    width, height, depth, viewmodes, cmap
  45. ;    Close_Screen(a0)            screen
  46. ;    Init_Mask(d0,d1,d2,d3,d4,d5)    x_min,y_min,x_max,y_max,sreen x,screen y
  47. ;    Free_Mask(a0)            maskplane struct
  48.  
  49.     include     system.gs
  50.     include    custom/graphics_base.i
  51.  
  52.     xdef     _Graphics_Init
  53.     xdef     _Graphics_Close
  54.     xdef     _Open_Screen
  55.     xdef     _Close_Screen
  56.     xdef     _Init_Mask
  57.     xdef     _Free_Mask
  58.  
  59.     xdef    _Fill_Polygon
  60.     xdef    _Draw_Polygon
  61.     xdef    _Draw_Line
  62.     xdef    _Write_Pixel
  63.     xdef    _Screen_Clear
  64.     xdef     _Show
  65.  
  66.     xdef    _Fade_To_White
  67.     xdef    _Fade_To_Black
  68.     xdef    _Fade
  69.  
  70.     xdef    _Save_IFF
  71.     xdef    _Load_IFF
  72.  
  73.     xdef    _Load_Data
  74.     xdef    _Save_Data
  75.  
  76.     xdef    _Write_Text
  77.     xdef    _Num_To_String
  78.  
  79.     xdef    _Add_Copper
  80.  
  81.     xdef    _GetKey
  82.  
  83.  
  84. _Graphics_Init
  85. ;    sets a high taskpri, opens the graphics library
  86. ;    and loads a null view
  87. ;    returns 0 if failure
  88. ;            1 if success
  89.  
  90.     PUSH    d2-d7/a2-a6
  91.  
  92.     move.l    #0,d7
  93.  
  94.     OPENLIB     _graphics_lib,0,_GfxBase
  95.     tst.l    d0
  96.     beq.s    G_Init_Failed
  97.  
  98.     move.l  4.w,a6
  99.            sub.l   a1,a1                     Zero - Find current task
  100.           jsr     _LVOFindTask(a6)
  101.  
  102.            move.l  d0,a1
  103.            moveq   #127,d0                task priority to very high...
  104.            jsr     _LVOSetTaskPri(a6)
  105.  
  106.     move.l    _GfxBase,a0            get GfxBase
  107.     move.l    gb_ActiView(a0),a1        get the current view
  108.     move.l    a1,_oldview            store the address
  109.  
  110.     move.l    #0,a1
  111.     CALLGRAF    LoadView                load a null view
  112.  
  113.     CALLGRAF    WaitTOF
  114.  
  115.     moveq.l    #SETCHIPREV_AA,d0            set chipset to AGA
  116.     CALLGRAF    SetChipRev            call SetChipRev
  117.  
  118.     move.l    #1,d7
  119. G_Init_Failed
  120.     move.l    d7,d0
  121.  
  122.     PULL    d2-d7/a2-a6
  123.  
  124.     rts
  125.  
  126. _Graphics_Close
  127. ;    closes the graphics library and restores the view
  128.  
  129.     PUSH    d2-d7/a2-a6
  130.  
  131.     tst.l    _oldview
  132.     beq.s    Graphics_Close_1
  133.     move.l    _oldview,a1            get the previous address view
  134.     CALLGRAF    LoadView                load it into the view
  135.  
  136.     CALLGRAF    WaitTOF                wait a bit
  137. Graphics_Close_1
  138.     tst.l    _GfxBase
  139.     beq.s    Graphics_Close_2
  140.     CLOSELIB    _GfxBase
  141. Graphics_Close_2
  142.     PULL    d2-d7/a2-a6
  143.     rts
  144.  
  145.     
  146. _Open_Screen
  147. ; opens a view
  148. ;    d0.l=pixel width
  149. ;    d1.l=pixel height
  150. ;    d2.l=depth
  151. ;    d3.l=viewmodes
  152. ;    a0.l=colourmap
  153.  
  154. ;     d0.l=returns screen address
  155.  
  156.     PUSH    d2-d7/a2-a6
  157.  
  158.     movem.l    d0-d3/a0,-(sp)        store inputs
  159.  
  160.     moveq.l    #0,d7            set d7 to failure
  161.     
  162.     move.l    #Screen_Store_SIZEOF,d0    the screen storage structure 
  163.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  164.     CALLEXEC    AllocMem            allocate it
  165.     
  166.     tst.l    d0
  167.     beq    Screen_Failed        failed to allocate my screen
  168.     
  169.     move.l    d0,a4            base of storage structure
  170.  
  171. ;    moveq.l    #0,d7            
  172.  
  173.     move.l    #18,d0            size of a view structure
  174.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  175.     CALLEXEC    AllocMem            allocate memory for view struct
  176.     move.l    d0,SS_View(a4)        store the address
  177.  
  178.     tst.l    d0
  179.     beq    Screen_Failed        failed to open the view structure
  180.  
  181.     move.l    SS_View(a4),a1        init view structure
  182.     CALLGRAF    InitView                  
  183.  
  184.     move.l    #VIEW_EXTRA_TYPE,d0    set up a view extra 
  185.     CALLGRAF    GfxNew            structure for the view
  186.  
  187.     move.l    d0,SS_ViewExtra(a4)    store the viewextra structure
  188.  
  189.     tst.l    d0            
  190.     beq    Screen_Failed        couldn't allocate one so off we go
  191.  
  192.     move.l    SS_View(a4),a0        associate view extra
  193.     move.l    SS_ViewExtra(a4),a1    with view
  194.     CALLGRAF    GfxAssociate
  195.  
  196.     move.l    SS_View(a4),a0            tell the view struct
  197.     move.l    #EXTEND_VSTRUCT,v_Modes(a0)    that there is a view extra
  198.     
  199.     move.l    #0,a1            open the monitor and
  200.     move.l    #DEFAULT_MONITOR_ID,d0    get it's default spec
  201.     CALLGRAF    OpenMonitor
  202.     move.l    d0,SS_MonSpec(a4)
  203.  
  204.     tst.l    d0
  205.     beq    Screen_Failed        couldn't allocate the monitor
  206.  
  207.     move.l    SS_ViewExtra(a4),a0        put the monitor spec
  208.     move.l    SS_MonSpec(a4),ve_Monitor(a0)    into the view extra
  209.  
  210.     move.l    #40,d0            size of a bitmap struct
  211.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  212.     CALLEXEC    AllocMem            allocate it
  213.     
  214.     move.l    d0,SS_BitMap(a4)
  215.  
  216.     tst.l    d0
  217.     beq    Screen_Failed        couldn't allocate a bitmap structure
  218.  
  219.     move.l    SS_BitMap(a4),a0        set up the bitmap 
  220.     move.l    8(sp),d0            NPLANES 
  221.     move.l    (sp),d1            WIDTH    
  222.     move.l    4(sp),d2            HEIGHT
  223.     CALLGRAF    InitBitMap        
  224.  
  225.     move.l    (sp),d0            WIDTH
  226.     lsr.l    #3,d0            /8
  227.     muls.l    4(sp),d0            *HEIGHT
  228.     muls.l    8(sp),d0            *NPLANES
  229.     move.l    #MEMF_CHIP!MEMF_CLEAR,d1    chip mem
  230.     CALLEXEC    AllocMem            allocate the memory
  231.  
  232.     move.l    d0,SS_Screen(a4)
  233.  
  234.     tst.l    d0                
  235.     beq    Screen_Failed        couldn't allocate a screen memory
  236.  
  237.     move.l    SS_BitMap(a4),a2        get the bitmap struct
  238.     lea    bm_Planes(a2),a2        address of bitplanes
  239.     move.l    SS_Screen(a4),a3        screen 1 :-prev alloc
  240.  
  241.     move.l    (sp),d0            WIDTH
  242.     lsr.l    #3,d0            /8
  243.     muls.l    4(sp),d0            *HEIGHT
  244.  
  245.     move.l    8(sp),d7            NPLANES
  246.     sub.l    #1,d7            -1
  247. .bpl_loop
  248.     move.l    a3,(a2)+            put bitplane into struct
  249.     add.l    d0,a3            add plane size
  250.     dbra    d7,.bpl_loop        loop round 
  251.  
  252.     move.l    #12,d0            size of rasinfo structure
  253.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  254.     CALLEXEC    AllocMem            memory for rasinfo struct
  255.     
  256.     move.l    d0,SS_RasInfo(a4)
  257.     
  258.     tst.l    d0
  259.     beq    Screen_Failed        couldn't allocate a rasinfo struct
  260.  
  261.     move.l    SS_RasInfo(a4),a0        
  262.     move.l    SS_BitMap(a4),a1
  263.     move.l    a1,ri_BitMap(a0)        rasinfo into bitmap
  264.  
  265.     move.l    #40,d0            size of a viewport structure
  266.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  267.     CALLEXEC    AllocMem            memory for viewport struct
  268.  
  269.     move.l    d0,SS_ViewPort(a4)
  270.     
  271.     tst.l    d0
  272.     beq    Screen_Failed        couldn't allocate the viewport struct
  273.  
  274.     move.l    d0,a0            viewport address into a0
  275.     CALLGRAF    InitVPort        initialise the viewport
  276.     
  277.     move.l    SS_ViewPort(a4),a0
  278.     move.w    14(sp),vp_Modes(a0)    viewmodes into viewport
  279.     
  280.     move.l    SS_View(a4),a1        viewport is already in a0 
  281.     move.l    a0,v_ViewPort(a1)        associate the view and viewport
  282.     
  283.     move.l    SS_RasInfo(a4),a1        viewport already in a0
  284.     move.l    a1,vp_RasInfo(a0)        associate the vport & rasinfo
  285.     move.w    2(sp),vp_DWidth(a0)    WIDTH
  286.     move.w    6(sp),vp_DHeight(a0)    HEIGHT
  287.     
  288.     move.l    #VIEWPORT_EXTRA_TYPE,d0    gfx extra type
  289.     CALLGRAF    GfxNew            make a vpextra struct
  290.  
  291.     move.l    d0,SS_ViewPortExtra(a4)    store the vpextra address
  292.  
  293.     tst.l    d0
  294.     beq    Screen_Failed        couldn't allocate a vpextra
  295.  
  296.     lea    vctags,a0            the vctag structure
  297. ;    lea    12(a0),a0
  298.     move.l    SS_ViewPortExtra(a4),12(a0)    vpextra into vctags
  299.  
  300.     move.l    #88,d0            size of a dim info structure
  301.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  302.     CALLEXEC    AllocMem            allocate memory for diminfo struct    
  303.  
  304.     move.l    d0,SS_DimensionInfo(a4)
  305.     
  306.     tst.l    d0
  307.     beq    Screen_Failed        couldn't allocate the memory
  308.  
  309.     move.l    #0,a0
  310.     move.l    SS_DimensionInfo(a4),a1
  311.     move.l    #88,d0
  312.     move.l    #DTAG_DIMS,d1
  313.     move.l    #DEFAULT_MONITOR_ID,d2
  314.     CALLGRAF    GetDisplayInfoData    get the diminfo struct
  315.  
  316.     move.l    SS_ViewPortExtra(a4),a0    link these bits together 
  317.     lea    vpe_DisplayClip(a0),a0
  318.     move.l    SS_DimensionInfo(a4),a1
  319.     lea    dim_Nominal(a1),a1
  320.     move.l    (a1)+,(a0)+
  321.     move.l    (a1),(a0)        
  322.  
  323.     move.l    #DEFAULT_MONITOR_ID,d0    get the display ID
  324.     CALLGRAF    FindDisplayInfo        for this display!
  325.  
  326.     lea    vctags,a0        
  327.     lea    20(a0),a0        store this in the tag list
  328.     move.l    d0,(a0)            
  329.  
  330.     moveq.l    #0,d0            clear d0
  331.     move.l    8(sp),d1            set bit number for no of colours
  332.     bset    d1,d0            
  333.     CALLGRAF    GetColorMap        allocate a colourmap structure
  334.  
  335.     move.l    d0,SS_ColorMap(a4)
  336.  
  337.     tst.l    d0
  338.     beq    Screen_Failed        couldn't allocate a colourmap struct
  339.  
  340.     lea    vctags,a0
  341.     lea    4(a0),a0            stick the vieport into
  342.     move.l    SS_ViewPort(a4),a1    the tag list structure
  343.     move.l    a1,(a0)
  344.     
  345.     move.l    SS_ColorMap(a4),a0
  346.     lea    vctags,a1
  347.     CALLGRAF    VideoControl        
  348.  
  349.     tst.l    d0
  350.     bne    Screen_Failed
  351.     
  352.     move.l    #100,d0            size of a rastport structure
  353.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    don't care about the memory
  354.     CALLEXEC    AllocMem            memory for rastport structure
  355.  
  356.     move.l    d0,SS_RastPort(a4)
  357.     
  358.     tst.l    d0
  359.     beq.s    Screen_Failed        couldn't allocate a rastport
  360.     
  361.     move.l    d0,a1
  362.     CALLGRAF    InitRastPort        init the rastport
  363.     
  364.     move.l    SS_BitMap(a4),a0
  365.     move.l    SS_RastPort(a4),a1
  366.     move.l    a0,rp_BitMap(a1)        bitmap struct into rastport
  367.  
  368.     
  369.     move.l    SS_ViewPort(a4),a0
  370.     move.l    16(sp),a1        colortable into a0
  371.     CALLGRAF    LoadRGB32        load the colortable into the viewport
  372.  
  373.     move.l    SS_View(a4),a0
  374.     move.l    SS_ViewPort(a4),a1
  375.     CALLGRAF    MakeVPort        make the viewport
  376.  
  377.     tst.l    d0
  378.     bne.s    Screen_Failed        couldn't make the viewport
  379.  
  380.     move.l    SS_View(a4),a1
  381.     CALLGRAF    MrgCop            build the copperlist
  382.  
  383.     tst.l    d0
  384.     bne.s    Screen_Failed        couldn't build the copperlist
  385.  
  386.     move.l    SS_View(a4),a1        all done so
  387.     CALLGRAF    LoadView            load the view up :-)<-<
  388.  
  389.     movem.l    (sp)+,d0-d3/a0        outputs back out.
  390.  
  391.     move.l    d0,SS_Width(a4)        store the width
  392.     move.l    d1,SS_Height(a4)        store the height    
  393.     move.l    d2,SS_Planes(a4)        store the number of planes
  394.     move.l    a0,SS_ColorTable(a4)    store the colourtable
  395.     
  396.     move.l    a4,d7            screen store base address
  397. Screen_Failed
  398.     move.l    d7,d0            return value.
  399.     bne.s    Screen_Done        not zero so out we go
  400.     movem.l    (sp)+,d0-d3/a0        pull outputs off if we haven't done it
  401. Screen_Done
  402.  
  403.     PULL    d2-d7/a2-a6
  404.  
  405.     rts                all done!
  406.     
  407. _Close_Screen:
  408. ; Closes a view
  409. ;    in:-a0=screen storage structure
  410.  
  411.     PUSH    d2-d7/a2-a6
  412.  
  413.     move.l    a0,a4        
  414.  
  415.     move.l    SS_UserCopperList(a4),a0
  416.     tst.l    a0            have we got any user coppers ?
  417.     beq.s    Close_Screen14        
  418.     move.l    SS_ViewPort(a4),a0
  419.     CALLGRAF    FreeVPortCopLists        free the user copperlists
  420.  
  421. Close_Screen14
  422.     move.l    SS_View(a4),a0
  423.     tst.l    a0            have we got a view structure ?
  424.     beq.s    Close_Screen12        
  425.     lea    v_LOFCprList(a0),a0
  426.     move.l    (a0),a0
  427.     CALLGRAF    FreeCprList        free the copper lists 
  428.  
  429.     move.l    SS_RastPort(a4),a1
  430.     tst.l    a1            have we got a rastport struct ?
  431.     beq.s    Close_Screen12
  432.     move.l    #100,d0
  433.     CALLEXEC    FreeMem            free the rastport
  434.  
  435. Close_Screen13
  436.     move.l    SS_View(a4),a1
  437.     tst.l    a1            have we got a view structure ?
  438.     beq.s    Close_Screen12
  439.     move.l    #18,d0
  440.     CALLEXEC    FreeMem            free the view structure
  441. Close_Screen12
  442.     move.l    SS_ViewPort(a4),a0
  443.     tst.l    a0            have we got a viewport struct ?
  444.     beq.s    Close_Screen11
  445.     CALLGRAF    FreeVPortCopLists        free the viewport copper lists
  446. Close_Screen11
  447.     move.l    SS_ColorMap(a4),a0
  448.     tst.l    a0            colour map structure ?
  449.     beq.s    Close_Screen10
  450.     CALLGRAF    FreeColorMap        free the colourmap structure
  451. Close_Screen10
  452.     move.l    SS_ViewPortExtra(a4),a0
  453.     tst.l    a0            vpextra structure ?
  454.     beq.s    Close_Screen9
  455.     CALLGRAF    GfxFree            free it
  456. Close_Screen9
  457.     move.l    SS_MonSpec(a4),a0
  458.     tst.l    a0            have we got a monitor spec ?
  459.     beq.s    Close_Screen8
  460.     CALLGRAF CloseMonitor        close the monitor spec
  461. Close_Screen8
  462.     move.l    SS_BitMap(a4),a1
  463.     tst.l    a1            bitmap structure ?
  464.     beq.s    Close_Screen7
  465.     move.l    #40,d0
  466.     CALLEXEC    FreeMem            free it.
  467. Close_Screen7
  468.     move.l    SS_Screen(a4),a1
  469.     tst.l    a1            have we got bitplane memory ?
  470.     beq.s    Close_Screen6
  471.     move.l    SS_Width(a4),d0        WIDTH
  472.     lsr.l    #3,d0            /8    
  473.     muls.l    SS_Height(a4),d0        *HEIGHT
  474.     muls.l    SS_Planes(a4),d0        *NPLANES
  475.     CALLEXEC    FreeMem            free the memory
  476. Close_Screen6
  477.     move.l    SS_RasInfo(a4),a1
  478.     tst.l    a1            have we got a ras info structure ?
  479.     beq.s    Close_Screen5
  480.     move.l    #12,d0
  481.     CALLEXEC    FreeMem            free it
  482. Close_Screen5
  483.     move.l    SS_ViewPort(a4),a1
  484.     tst.l    a1            have we got a viewport structure ?
  485.     beq.s    Close_Screen4
  486.     move.l    #40,d0
  487.     CALLEXEC    FreeMem            free it.
  488. Close_Screen4
  489.     move.l    SS_ViewExtra(a4),a0
  490.     tst.l    a0            have we got a view extra struct ?
  491.     beq.s    Close_Screen3
  492.     CALLGRAF    GfxFree            free it.
  493. Close_Screen3    
  494.     move.l    SS_DimensionInfo(a4),a1
  495.     tst.l    a1            a dim info struct ?
  496.     beq.s    Close_Screen2
  497.     move.l    #88,d0
  498.     CALLEXEC    FreeMem            free the memory.
  499. Close_Screen2
  500.     move.l    a4,a1
  501.     move.l    #Screen_Store_SIZEOF,d0
  502.     CALLEXEC    FreeMem            free the screen store memory.
  503. Close_Screen1
  504.     moveq.l    #0,d0
  505.  
  506.     PULL    d2-d7/a2-a6
  507.  
  508.     rts
  509.  
  510.  
  511. _Init_Mask
  512. ;    allocates a maskplane to be linked into
  513. ;    a screen for the polygon filling
  514. ;    operations
  515. ;    d0.l=x_min
  516. ;    d1.l=y_min
  517. ;    d2.l=x_max
  518. ;    d3.l=y_max
  519. ;    d4=screen x
  520. ;    d5-screen y
  521.  
  522. ;    returns
  523. ;    d0=maskplane address
  524.  
  525. ;*** Notes This could do with some better error checking!!!
  526.  
  527.     PUSH    d2-d7/a2-a6
  528.  
  529.     PUSH    d0-d3            store the inputs
  530.  
  531.     move.l    #MaskPlane_SIZEOF,d0    enough space for a maskplane
  532.     move.l    #MEMF_ANY!MEMF_CLEAR,d1    any type of memory
  533.     CALLEXEC    AllocMem            allocate it
  534.     
  535.     move.l    d0,d7            store base address of the mem.
  536.  
  537.     move.l    d0,a3            get memory address
  538.  
  539.     PULL    d0-d3            inputs of stack
  540.  
  541.     move.w    d0,MP_Clip_X_Min(a3)    store min clip x 
  542.     move.w    d1,MP_Clip_Y_Min(a3)    store min clip y
  543.     move.w    d2,MP_Clip_X_Max(a3)    store max clip x
  544.     move.w    d3,MP_Clip_Y_Max(a3)    store max clip y
  545.  
  546.     lsr.l    #3,d4            the bit size of the mask memory.
  547.     muls    d5,d4            times the height of the memory
  548.  
  549.     move.l    d4,(a3)+            store the memory size in the struct
  550.  
  551.     move.l    d4,d0
  552.     move.l    #MEMF_CHIP!MEMF_CLEAR,d1    chip memory
  553.     
  554.     CALLEXEC    AllocMem            allocate the mask memory
  555.  
  556.     move.l    d0,(a3)+            store the memory area
  557.         
  558.     move.l    d7,d0            return base address of mem.
  559.  
  560.     PULL    d2-d7/a2-a6        
  561.  
  562.     rts
  563.  
  564. _Free_Mask:
  565. ;    Frees a previously allocated maskplane
  566.  
  567. ;    a0.l=maskplane address returned by Init_Mask
  568.  
  569. ;*** like above this could use some better error checking!!!
  570.  
  571.     PUSH    d2-d7/a2-a6
  572.  
  573.     move.l    a0,a5
  574.     move.l    MP_MaskPlane(a5),a1    
  575.     move.l    MP_PlaneSize(a5),d0
  576.     CALLEXEC    FreeMem            free the mask memory
  577.     
  578.     move.l    a5,a1
  579.     move.l    #MaskPlane_SIZEOF,d0
  580.     CALLEXEC    FreeMem            free the maskplane structure memory
  581.  
  582.     PULL    d2-d7/a2-a6
  583.  
  584.     rts
  585.  
  586. ;------------------------------------------------------------------------        
  587.  
  588. ;-------- Drawing routines -------------------------------------------------
  589. ;    Fill_Polygon(a0,a1,d0,d1)      screen, vertex list, npoints, colour
  590. ;    Draw_Polygon(a0,a1,d0,d1)        screen, vertex list, npoints, colour
  591. ;    Draw_Line(a0,d0,d1,d2,d3,d4)    screen, x1, y1, x2, y2, colour        
  592. ;    Write_Pixel(a0,d0,d1,d2)        screen, x1, x2, colour
  593.  
  594. _Fill_Polygon
  595. ;    a0=screen to draw onto
  596. ;    a1=list of vertices
  597. ;    d0=npoints
  598. ;    d1=colour
  599.  
  600.     PUSH    d2-d7/a2-a6
  601.  
  602.     PUSH    a0/d1            store the screen and number of points
  603.     exg.l    a0,a1            swap the screen and point list.
  604. clip:
  605. ;    clips a polygon
  606. ;    internal routine called by Fill_Polygon
  607. ;    DONT CALL THIS PROCUDURE YOURSELF
  608.  
  609. ;    d0=number of points coming in
  610. ;    a0=points coming in
  611. ;    a1=screen structure
  612.  
  613.     move.l    SS_MaskPlane(a1),a6    get the maskplane address
  614.     lea    clip_out,a2        temporary variable
  615.  
  616. ; the source buffer is already in a0
  617.  
  618.     lea    MP_PointBuffer(a6),a1    initial destination buffer
  619.     move.l    a1,a4            store this address
  620.  
  621.     clr.w    (a2)            clear the clip out variable
  622.  
  623.     move.w    d0,d7            get the number of points
  624.     beq    clip_end            no points so jump out
  625.     subq.w    #1,d7            sub 1 for the loop
  626.     
  627.     move.w    (a0)+,d5            get the first x point
  628.     move.w    (a0)+,d6            get the first y point    
  629.     move.w    MP_Clip_X_Min(a6),d0    get the clip value
  630.     cmp.w    d0,d5            compare the point to the clip value
  631.  
  632.     bge.s     xmin_save        point is in so store it
  633.     bra.s     xmin_update        point is out so update the temp var.
  634.  
  635. xmin_next:
  636.     move.w    (a0)+,d3            get the next x point
  637.     move.w    (a0)+,d4            get the next y point
  638.     move    d3,d5            store these values
  639.     move    d4,d6
  640.  
  641.     sub.w    d0,d3            subtract the clip value
  642.     bge.s    xmin_x2in        the point is in so check the other
  643.  
  644. ;    the point must be outside so check the other point
  645.  
  646.     sub.w    d0,d1            subtract the clip value
  647.     blt.s    xmin_update        do this if both points are outside
  648.  
  649. ;    if we get to here then the first point is outside but the 
  650. ;     second is inside so we have to clip the line
  651.  
  652.     beq.s    .yint_out
  653.     
  654.     movem    d5/d6,-(sp)        store d5 and d6
  655. .yint_in    move.w    d2,d6            store the first y coord
  656.     add.w    d4,d6            add the second y coordinate onto this
  657.     asr.w    #1,d6            divide this by 2
  658.     move.w    d1,d5            get the x difference into d5
  659.     add.w    d3,d5            add the first x onto this
  660.     asr.w    #1,d5            divide this by 2
  661.     beq.s    .yint_end        if this is 0 we have the intersect
  662.     bgt.s    .yint_loop        greater than 0 so off we go
  663. ;    less than zero
  664.     move.w    d5,d3            the x value goes into d3
  665.     move.w    d6,d4            the y value goes into d4
  666.     bra.s    .yint_in            iterate backwards
  667. .yint_loop:    
  668.     move.w    d5,d1            the x value goes into d1
  669.     move.w    d6,d2            y into d2
  670.     bra.s    .yint_in            iterate backwards
  671. .yint_end:
  672.     move.w    d0,(a1)+            store the x value
  673.     move.w    d6,(a1)+            store the intersect value
  674.     addq.w    #1,(a2)            increment the counter.
  675.     movem    (sp)+,d5/d6        pull the contents off the stack.
  676. .yint_out:
  677.  
  678.     bra.s    xmin_update        update the temp variables.
  679.  
  680. xmin_x2in:
  681. ;    the first point is in so check the second
  682.  
  683.     sub.w    d0,d1            subtract the clip value
  684.     bge.s    xmin_save        the point is in so save
  685.  
  686.     tst.w    d3                check if d3 is 0        
  687.     beq.s    .yint_out        it is so jump off.
  688.  
  689.     movem    d5/d6,-(sp)        store d5 and d6
  690. .yint_in    move.w    d4,d6            store the first y coord
  691.     add.w    d2,d6            add the second y coordinate onto this
  692.     asr.w    #1,d6            divide this by 2
  693.     move    d3,d5            get the x difference into d5
  694.     add.w    d1,d5            add the first x onto this
  695.     asr.w    #1,d5            divide this by 2
  696.     beq.s    .yint_end        if this is 0 we have the intersect
  697.     bgt.s    .yint_loop        greater than 0 so off we go
  698. ;    less than zero
  699.     move    d5,d1            the x value goes into d3
  700.     move    d6,d2            the y value goes into d4
  701.     bra.s    .yint_in            iterate backwards
  702. .yint_loop:
  703.     move    d5,d3            the x value goes into d1
  704.     move    d6,d4            y into d2
  705.     bra.s    .yint_in            iterate backwards
  706. .yint_end:
  707.     move.w    d0,(a1)+            store the x value
  708.     move.w    d6,(a1)+            store the intersect value
  709.     addq.w    #1,(a2)            increment the counter.
  710.     movem    (sp)+,d5/d6        pull the contents off the stack.
  711. .yint_out:
  712.  
  713. xmin_save:
  714.     move.w    d5,(a1)+            store the x coordinate
  715.     move.w    d6,(a1)+            store the y coordinate
  716.     addq.w    #1,(a2)            increment the counter
  717. xmin_update:
  718.     move    d5,d1            move x into the other x
  719.     move    d6,d2            move the y into the other one
  720.     dbf    d7,xmin_next        loop back.
  721.  
  722.     tst.w    (a2)            check if there are no points.
  723.     beq.s    clip_xmax        no points so jump off.
  724.  
  725.     subq.w    #4,a1            check if the first and last
  726.     cmpm.l    (a4)+,(a1)+        points are the same
  727.     beq.s    clip_xmax        if they aren't copy the 
  728.     move.l    -(a4),(a1)        first to the last point and 
  729.     addq.w    #1,(a2)            increment the counter.
  730.  
  731. clip_xmax:
  732.     lea    MP_PointBuffer(a6),a0    source buffer
  733.     lea    MP_PointBuffer2(a6),a1    destination buffer
  734.     move.l    a1,a4
  735.  
  736.     move.w    (a2),d7
  737.     beq    clip_ymin        no points so don't waste time
  738.     subq.w    #1,d7            decrement the counter
  739.  
  740.     clr.w    (a2)            clear the temporary variable
  741.     
  742.     move.w    (a0)+,d5            get the first x point
  743.     move.w    (a0)+,d6            get the first y point
  744.     move.w    MP_Clip_X_Max(a6),d0    get the clip value
  745.     cmp.w    d5,d0            compare the point to the clip value
  746.  
  747.     bge.s     xmax_save        point is in so store it
  748.     bra.s    xmax_update        point is out so update the temp var.
  749.  
  750. xmax_next:
  751.     move.w    (a0)+,d3            get the next x point
  752.     move.w    (a0)+,d4            get the next y point
  753.     move    d3,d5            store these values
  754.     move    d4,d6
  755.  
  756.     sub.w    d0,d3            subtract the clip value
  757.     neg.w    d3            negate the distance
  758.     bge.s    xmax_x2in        the point is in so check the other
  759.  
  760. ;    the point must be outside so check the other point
  761.  
  762.     sub.w    d0,d1            subtract the clip value
  763.       neg.w    d1            negate the distance
  764.     blt.s    xmax_update        do this if both points are outside
  765.  
  766. ;    if we get to here then the first point is outside but the 
  767. ;     second is inside so we have to clip the line
  768.  
  769.     beq.s    .yint_out
  770.  
  771.     movem    d5/d6,-(sp)        store d5 and d6
  772. .yint_in    move.w    d2,d6            store the first y coord
  773.     add.w    d4,d6            add the second y coordinate onto this
  774.     asr.w    #1,d6            divide this by 2
  775.     move    d1,d5            get the x difference into d5
  776.     add.w    d3,d5            add the first x onto this
  777.     asr.w    #1,d5            divide this by 2
  778.     beq.s    .yint_end        if this is 0 we have the intersect
  779.     bgt.s    .yint_loop        greater than 0 so off we go
  780. ;    less than zero
  781.     move    d5,d3            the x value goes into d3
  782.     move    d6,d4            the y value goes into d4
  783.     bra.s    .yint_in            iterate backwards
  784. .yint_loop:    
  785.     move    d5,d1            the x value goes into d1
  786.     move    d6,d2            y into d2
  787.     bra.s    .yint_in            iterate backwards
  788. .yint_end:
  789.     move.w    d0,(a1)+            store the x value
  790.     move.w    d6,(a1)+            store the intersect value
  791.     addq.w    #1,(a2)            increment the counter.
  792.     movem    (sp)+,d5/d6        pull the contents off the stack.
  793. .yint_out:
  794.  
  795.     bra.s    xmax_update        update the temp variables.
  796.  
  797. xmax_x2in:
  798. ;    the first point is in so check the second
  799.  
  800.     sub.w    d0,d1            subtract the clip value
  801.     neg.w    d1            negate the distance        
  802.     bge.s    xmax_save        the point is in so save
  803.  
  804.     tst.w    d3                 check if d3 is 0
  805.     beq.s    .yint_out        it is so jump off.
  806.  
  807.     movem    d5/d6,-(sp)        store d5 and d6
  808. .yint_in    move.w    d4,d6            store the first y coord
  809.     add.w    d2,d6            add the second y coordinate onto this
  810.     asr.w    #1,d6            divide this by 2
  811.     move    d3,d5            get the x difference into d5
  812.     add.w    d1,d5            add the first x onto this
  813.     asr.w    #1,d5            divide this by 2
  814.     beq.s    .yint_end        if this is 0 we have the intersect
  815.     bgt.s    .yint_loop        greater than 0 so off we go
  816. ;    less than zero
  817.     move    d5,d1            the x value goes into d3
  818.     move    d6,d2            the y value goes into d4
  819.     bra.s    .yint_in            iterate backwards
  820. .yint_loop:
  821.     move    d5,d3            the x value goes into d1
  822.     move    d6,d4            y into d2
  823.     bra.s    .yint_in            iterate backwards
  824. .yint_end:
  825.     move.w    d0,(a1)+            store the x value
  826.     move.w    d6,(a1)+            store the intersect value
  827.     addq.w    #1,(a2)            increment the counter.
  828.     movem    (sp)+,d5/d6        pull the contents off the stack.
  829. .yint_out:
  830.  
  831. xmax_save:
  832.     move.w    d5,(a1)+            store the x coordinate
  833.     move.w    d6,(a1)+            store the y coordinate
  834.     addq.w    #1,(a2)            increment the counter
  835. xmax_update:
  836.     move    d5,d1            move x into the other x
  837.     move    d6,d2            move the y into the other one
  838.     dbf    d7,xmax_next        loop back.
  839.  
  840.     tst.w    (a2)            check if there are no points.
  841.     beq.s    clip_ymin        no points so jump off.
  842.  
  843.     subq    #4,a1            check if the first and las
  844.     cmpm.l    (a4)+,(a1)+        points are the same
  845.     beq.s    clip_ymin        if they aren't copy the
  846.     move.l    -(a4),(a1)        first to the last point and
  847.     addq.w    #1,(a2)            increment the counter.
  848.  
  849. clip_ymin:
  850.     lea    MP_PointBuffer2(a6),a0    source buffer
  851.     lea    MP_PointBuffer(a6),a1    destination buffer
  852.     move.l    a1,a4
  853.  
  854.     move.w    (a2),d7            counter into d7
  855.     beq    clip_ymax        no points to do ? so jump off
  856.     subq.w    #1,d7            decrement the counter
  857.  
  858.     clr.w    (a2)            clear the clip out variable
  859.  
  860.     move.w    (a0)+,d5            get the first x point
  861.     move.w    (a0)+,d6            get the first y point
  862.     move.w    MP_Clip_Y_Min(a6),d0    get the clip value    
  863.     cmp.w    d0,d6            compare the point to the clip value
  864.  
  865.     bge.s    ymin_save        point is in so store it
  866.     bra.s      ymin_update        point is out so update the temp var.
  867.  
  868. ymin_next:
  869.     move.w    (a0)+,d3            get the next x point
  870.     move.w    (a0)+,d4            get the next y point
  871.     move    d3,d5            store these values
  872.     move    d4,d6
  873.  
  874.     sub.w    d0,d4            subtract the clip value
  875.     bge.s    ymin_y2in        the point is in so check the other
  876.  
  877. ;    the point must be outside so check the other point
  878.     
  879.     sub.w    d0,d2            subtract the clip value
  880.     blt.s    ymin_update        do this if both points are outside
  881. ;    if we get to here then the first point is outside but the 
  882. ;     second is inside so we have to clip the line
  883.  
  884.     beq.s    .xint_out
  885.  
  886.     movem    d5/d6,-(sp)        store d5 and d6
  887. .xint_in    move.w    d1,d5            store the first x coordinate
  888.     add.w    d3,d5            add on the second x coordinate
  889.     asr.w    #1,d5            divide this by 2
  890.     move.w     d2,d6            get the y difference into d6
  891.     add.w    d4,d6            add the second y coordinate
  892.     asr.w    #1,d6            divide this by 2
  893.     beq.s    .xint_end        if this is 0 we have the intersect
  894.     bgt.s    .xint_loop        greater than 0 so off we go
  895. ;    less than zero
  896.     move.w    d6,d4            the y value goes into d4
  897.     move.w    d5,d3             the x value goes into d3
  898.     bra.s    .xint_in         iterate backwards
  899. .xint_loop:
  900.     move.w    d5,d1            the y value into d1
  901.     move.w    d6,d2            x into d2
  902.     bra.s    .xint_in            iterate backwards
  903.  
  904. .xint_end:    
  905.     move.w    d5,(a1)+            store the intersect value
  906.     move.w    d0,(a1)+            store the clip value
  907.     addq.w    #1,(a2)            increment the counter
  908.     movem    (sp)+,d5/d6        pull the contents off the stack.        
  909. .xint_out
  910.  
  911.     bra.s    ymin_update        update the temp variables.
  912.  
  913. ymin_y2in:
  914. ;    the first point is in so check the second
  915.  
  916.     sub.w    d0,d2            subtract the clip value
  917.     bge.s    ymin_save        the point is in so save
  918.  
  919.     tst.w    d4            check if d3 is 0
  920.     beq.s    .xint_out        it is so jump off.
  921.  
  922.     movem    d5/d6,-(sp)        store d5 and d6
  923. .xint_in    move    d3,d5            store the second x coord
  924.     add.w    d1,d5            add the first x coordinate onto this
  925.     asr.w    #1,d5            divide this by 2
  926.     move     d4,d6            get the y difference
  927.     add.w    d2,d6            add on the first y coordinate
  928.     asr.w    #1,d6            divide this by 2
  929.     beq.s    .xint_end        if this is 0 we have the intersect
  930.     bgt.s    .xint_loop        greater than 0 so off we go
  931. ;    less than zero
  932.     move    d6,d2            the y value into d2
  933.     move    d5,d1             x into d1
  934.     bra.s    .xint_in         iterate backwards
  935. .xint_loop:
  936.     move    d5,d3            x into d3
  937.     move    d6,d4            y into d4
  938.     bra.s    .xint_in            iterate backwards.
  939.  
  940. .xint_end:    
  941.     move.w    d5,(a1)+            store the x value
  942.     move.w    d0,(a1)+            store the intersect value
  943.     addq.w    #1,(a2)            increment the counter.
  944.     movem    (sp)+,d5/d6        pull the contents off the stack.
  945. .xint_out
  946.  
  947. ymin_save:
  948.     move.w    d5,(a1)+            store the x coordinate
  949.     move.w    d6,(a1)+            store the y coordinate
  950.     addq.w    #1,(a2)            increment the counter
  951.  
  952. ymin_update:
  953.     move    d5,d1            move x into the other x
  954.     move    d6,d2            move the y into the other one
  955.     dbf    d7,ymin_next        loop back.
  956.  
  957.     tst.w    (a2)            check if there are no points.
  958.     beq.s    clip_ymax        no points so jump off.
  959.  
  960.     subq    #4,a1            check if the first and last
  961.     cmpm.l    (a4)+,(a1)+        points are the same
  962.     beq.s    clip_ymax        if they aren't copy the
  963.     move.l    -(a4),(a1)        first to the last point and
  964.     addq.w    #1,(a2)            increment the counter.
  965.  
  966. clip_ymax: 
  967.     lea    MP_PointBuffer(a6),a0    source buffer
  968.     lea    MP_PointBuffer2(a6),a1    destination buffer
  969.     move.l    a1,a4
  970.  
  971.     move.w    (a2),d7            no points so don't waste time
  972.     beq    clip_end            
  973.     subq.w    #1,d7            decrement the counter
  974.  
  975.     clr.w    (a2)            clear the temporary variable
  976.  
  977.      move.w    (a0)+,d5            get the first x point
  978.     move.w    (a0)+,d6            get the first y point
  979.     move.w    MP_Clip_Y_Max(a6),d0    get the clip value
  980.     cmp.w    d6,d0            compare the point to the clip value
  981.  
  982.     bge.s    ymax_save        point is in so store it
  983.     bra.s    ymax_update        point is out so update the temp var.
  984.  
  985. ymax_next:
  986.     move.w    (a0)+,d3            get the next x point
  987.     move.w    (a0)+,d4            get the next y point
  988.     move    d3,d5            store these values
  989.     move    d4,d6
  990.  
  991.     sub.w    d0,d4            subtract the clip value
  992.     neg.w    d4            negate the distance
  993.     bge.s    ymax_y2in        the point is in so check the other    
  994.  
  995. ;    the point must be outside so check the other point
  996.  
  997.     sub.w    d0,d2            subtract the clip value
  998.     neg.w    d2            negate the distance
  999.     blt.s    ymax_update        do this if both points are outside
  1000.  
  1001. ;    if we get to here then the first point is outside but the 
  1002. ;     second is inside so we have to clip the line
  1003.  
  1004.     beq.s    .xint_out
  1005.  
  1006.     movem    d5/d6,-(sp)        store d5 and d6
  1007. .xint_in    move    d1,d5            store the first x coordinate
  1008.     add.w    d3,d5            add the second x onto this
  1009.     asr.w    #1,d5            divide this by 2
  1010.     move     d2,d6            get the y distance 
  1011.     add.w    d4,d6            add on the second y coord
  1012.     asr.w    #1,d6            divide this by 2
  1013.     beq.s    .xint_end        if this is 0 we have the intersect
  1014.     bgt.s    .xint_loop        greater than 0 so off we go
  1015. ;    less than zero
  1016.     move    d6,d4            the y value goes into d4
  1017.     move    d5,d3             the x value goes into d3
  1018.     bra.s    .xint_in         iterate backwards
  1019. .xint_loop:
  1020.     move    d5,d1            the x value goes into d1
  1021.     move    d6,d2            y into d2
  1022.     bra.s    .xint_in            iterate backwards
  1023. .xint_end:    
  1024.     move.w    d5,(a1)+            store the x value
  1025.     move.w    d0,(a1)+            store the intersect value
  1026.     addq.w    #1,(a2)            increment the counter.
  1027.     movem    (sp)+,d5/d6        pull the contents off the stack.
  1028. .xint_out
  1029.  
  1030.     bra.s    ymax_update        update the temp variables.
  1031.  
  1032. ymax_y2in:
  1033. ;    the first point is in so check the second
  1034.  
  1035.     sub.w    d0,d2            subtract the clip value
  1036.     neg.w    d2            negate the distance
  1037.     bge.s    ymax_save        the point is in so save
  1038.  
  1039. ;x_intercept:
  1040.     tst.w    d4            check if d3 is 0
  1041.     beq.s    .xint_out        it is so jump off.
  1042.  
  1043.     movem    d5/d6,-(sp)        store d5 and d6
  1044. .xint_in    move    d3,d5            store the second x coord
  1045.     add.w    d1,d5            add the first x coordinate onto this
  1046.     asr.w    #1,d5            divide this by 2
  1047.     move     d4,d6            get the y difference
  1048.     add.w    d2,d6            add on the first y coordinate
  1049.     asr.w    #1,d6            divide this by 2
  1050.     beq.s    .xint_end        if this is 0 we have the intersect
  1051.     bgt.s    .xint_loop        greater than 0 so off we go
  1052. ;    less than zero
  1053.     move    d6,d2            the y value into d2
  1054.     move    d5,d1             x into d1
  1055.     bra.s    .xint_in         iterate backwards
  1056. .xint_loop:
  1057.     move    d5,d3            x into d3
  1058.     move    d6,d4            y into d4
  1059.     bra.s    .xint_in            iterate backwards.
  1060. .xint_end:        
  1061.     move.w    d5,(a1)+            store the x value
  1062.     move.w    d0,(a1)+            store the intersect value
  1063.     addq.w    #1,(a2)            increment the counter.
  1064.     movem    (sp)+,d5/d6        pull the contents off the stack.
  1065. .xint_out
  1066.  
  1067. ymax_save:
  1068.     move.w    d5,(a1)+            store the x coordinate
  1069.     move.w    d6,(a1)+            store the y coordinate
  1070.     addq.w    #1,(a2)            increment the counter
  1071.  
  1072. ymax_update:
  1073.     move    d5,d1            move x into the other x    
  1074.     move    d6,d2            move the y into the other one
  1075.     dbf    d7,ymax_next        loop back.
  1076.     
  1077.     tst.w    (a2)            check if there are no points.
  1078.     beq.s    clip_end            no points so jump off.
  1079.     
  1080.     subq    #4,a1            check if the first and last
  1081.     cmpm.l    (a4)+,(a1)+        points are the same
  1082.     beq.s    clip_end            if they aren't copy the
  1083.     move.l    -(a4),(a1)        first to the last point and
  1084.     addq.w    #1,(a2)            increment the counter.
  1085.  
  1086. clip_end:
  1087.     lea    MP_PointBuffer2(a6),a1    the final resting place of the polygon
  1088.     move.w    (a2),d0            get the number of points
  1089.     cmp.w    #1,d0            only one point ?
  1090.     bne.s    clip_poly        no so jump off
  1091.     move.w    #0,d0            if yes we don't bother drawing it.
  1092. clip_poly
  1093.     PULL    a0/d1            
  1094.  
  1095.     tst.w    d0            check if we have any points
  1096.     beq    Fill_Poly_Done        no then don't bother drawing
  1097.  
  1098.     move.w    SS_Height+2(a0),y_min    this section is used to calculate
  1099.     move.w    #0,y_max            the boundaries of the polygon
  1100.     move.w    SS_Width+2(a0),x_min    
  1101.     move.w    #0,x_max
  1102.  
  1103.     move.b    d1,-(sp)            store the colour value.
  1104.  
  1105.     move.w    d0,d7            number of points.
  1106.     subq.w    #2,d7            subtract 2
  1107.     
  1108.     move.l    a1,a2            store the base address of the points
  1109.     
  1110.     move.w    (a1)+,d2            first x point
  1111.     move.w    (a1)+,d3            first y point
  1112. Fill_Poly_Loop    
  1113.     move.w    d2,d0            move the points into the other pos
  1114.     move.w    d3,d1
  1115.     move.w    (a1)+,d2            get the next x point
  1116.     move.w    (a1)+,d3            get the next y point
  1117.     
  1118.     cmp.w    x_min,d0            this section is used to calculate
  1119.     bgt.s    x_great_x_min        the boundaries of the polygon
  1120.     move.w    d0,x_min            it works by checking the maximum
  1121. x_great_x_min:                 
  1122.     cmp.w    x_max,d0            and minimum x and y values and
  1123.     blt.s    x_check_done        updating the variables accordingly.    
  1124.     move.w    d0,x_max        
  1125. x_check_done
  1126.     cmp.w    y_min,d1
  1127.     bgt.s    y_great_y_min
  1128.     move.w    d1,y_min
  1129. y_great_y_min
  1130.     cmp.w    y_max,d1
  1131.     blt.s    y_check_done    
  1132.     move.w    d1,y_max        
  1133. y_check_done
  1134.  
  1135.     movem.l    d2-d7/a0-a1,-(sp)        store lots of variables on the stack.
  1136.  
  1137. Fill_Line
  1138. ;    Draws a line for filling a polygon
  1139. ;    internal routine DONT CALL!!!!
  1140. ;    d0,d1=x1,y1
  1141. ;    d2,d3=x2,y2
  1142.  
  1143. ;    a0=screen structure
  1144.  
  1145. ; ***     This line drawing routine bashes the hardware quite violently.
  1146. ; ***    It is not my work but is taken from the How To Code 7 manual.
  1147. ; ***     Thank you to those responsible for it!
  1148.  
  1149.     CALLGRAF    OwnBlitter
  1150.     
  1151.     lea    $dff000,a6
  1152.     move.l    SS_Width(a0),d6
  1153.     lsr.w    #3,d6                
  1154.     move.l    SS_MaskPlane(a0),a0
  1155.     move.l    MP_MaskPlane(a0),a0
  1156.     cmp.w       d1,d3
  1157.             beq       noline
  1158.             ble.s       lin1
  1159.             exg         d1,d3
  1160.             exg         d0,d2
  1161. lin1:       sub.w       d2,d0
  1162.             move.w      d2,d5
  1163.             asr.w       #3,d2
  1164.             ext.l       d2
  1165.             sub.w       d3,d1
  1166.             muls        d6,d3           
  1167.             add.l       d2,d3
  1168.             add.l       d3,a0
  1169.             and.w       #$f,d5
  1170.             move.w      d5,d2
  1171.             eor.b       #$f,d5
  1172.             ror.w       #4,d2
  1173.             or.w        #$0b4a,d2
  1174.             swap        d2
  1175.             tst.w       d0
  1176.             bmi.s       lin2
  1177.             cmp.w       d0,d1
  1178.             ble.s       lin3
  1179.             move.w      #$41,d2
  1180.             exg         d1,d0
  1181.             bra.s       lin6
  1182. lin3:       move.w      #$51,d2
  1183.             bra.s       lin6
  1184. lin2:       neg.w       d0
  1185.             cmp.w       d0,d1
  1186.             ble.s       lin4
  1187.             move.w      #$49,d2
  1188.             exg         d1,d0
  1189.             bra.s       lin6
  1190. lin4:       move.w      #$55,d2
  1191. lin6:       asl.w       #1,d1
  1192.             move.w      d1,d4
  1193.             move.w      d1,d3
  1194.             sub.w       d0,d3
  1195.             ble.s       lin5
  1196.             and.w       #$ffbf,d2
  1197. lin5:       move.w      d3,d1
  1198.             sub.w       d0,d3
  1199.             or.w        #2,d2
  1200.             lsl.w       #6,d0
  1201.             add.w       #$42,d0
  1202. bltwt:      btst        #6,2(a6)
  1203.             bne.s       bltwt
  1204.             bchg        d5,(a0)
  1205.             move.l      d2,bltcon0(a6)
  1206.             move.l      #-1,bltafwm(a6)
  1207.             move.l      a0,bltcpt(a6)
  1208.             move.w      d1,bltapt+2(a6)
  1209.             move.l      a0,bltdpt(a6)
  1210.             move.w      d6,bltcmod(a6)   ;width
  1211.             move.w      d4,bltbmod(a6)
  1212.             move.w      d3,bltamod(a6)
  1213.             move.w      d6,bltdmod(a6)   ;width
  1214.             move.l      #-$8000,bltbdat(a6)
  1215.             move.w      d0,bltsize(a6)
  1216. noline:     
  1217.     CALLGRAF    DisownBlitter
  1218.  
  1219.     movem.l    (sp)+,d2-d7/a0-a1        values off the stack
  1220.  
  1221.     dbra    d7,Fill_Poly_Loop        branch back till all lines are done
  1222.  
  1223.     move.l    a0,a4
  1224.  
  1225.     move.w    x_max,d0            calculate the offset into the bitmap
  1226.     lsr.w    #4,d0            of the polygon in terms of the 
  1227.     move.w    d0,d2            calue that the blitter wants
  1228.     add.w    d2,d2
  1229.     move.w    y_max,d1
  1230.     mulu    #40,d1
  1231.     add.w    d2,d1
  1232.     move.w    d1,bltstrt
  1233.  
  1234.     move.l    SS_Width(a0),d6
  1235.     lsr.l    #3,d6            byte width of the screen
  1236.     move.l    SS_MaskPlane(a0),a0
  1237.     move.l    MP_MaskPlane(a0),a0
  1238.  
  1239.     add.w    d1,a0            this is the address of the first word
  1240.                     ;of the polygon
  1241.  
  1242.     move.w    x_min,d1            calculate the width of the polygon
  1243.     lsr.w    #4,d1            in terms of a value that the 
  1244.     sub.w    d1,d0            blitter likes
  1245.     addq.w    #1,d0
  1246.     move.w    d0,bltwidth        
  1247.  
  1248.     move.w    d6,d2            calculate the blit modulo
  1249.     add.w    d0,d0
  1250.     sub.w    d0,d2
  1251.     move.w    d2,blitmod        
  1252.  
  1253.     move.w    y_max,d0            calculate the size of the polygon
  1254.     sub.w    y_min,d0            for the blitter
  1255.     addq.w    #1,d0
  1256.     lsl.w    #6,d0
  1257.     add.w    bltwidth,d0
  1258.     move.w    d0,blitsize
  1259.  
  1260.     CALLGRAF    OwnBlitter        This section fills in the polygon
  1261.                     ;using the blitter fill mode
  1262.     CALLGRAF    WaitBlit
  1263.  
  1264.     move.l    #$dff000,a5
  1265.  
  1266.     move.l    a0,bltapt(a5)
  1267.     move.l    a0,bltdpt(a5)
  1268.  
  1269.     move.w    d2,bltamod(a5)
  1270.     move.w    d2,bltdmod(a5)
  1271.     move.w    #%0000100111110000,bltcon0(a5)
  1272.     move.w    #%0000000000001010,bltcon1(a5)    
  1273.     move.l    #$ffffffff,bltafwm(a5)
  1274.     move.w    blitsize,bltsize(a5)
  1275.  
  1276. pln_copy:
  1277. ;    This section copies the polygon from the maskplane 
  1278. ;    to the desination plane memory using the blitter.
  1279.  
  1280.     move.l    SS_Screen(a4),a0
  1281.     adda.w    bltstrt,a0
  1282.     move.l    SS_Planes(a4),d7        
  1283.     subq.l    #1,d7
  1284.  
  1285.     move.w    blitmod,d0
  1286.  
  1287. ;    Get the colour off the stack into d6
  1288.  
  1289.     move.b    (sp)+,d6
  1290.     extb.l    d6
  1291.  
  1292. ;     Set the initial values for the blitter
  1293.     
  1294.     CALLGRAF    WaitBlit
  1295.     move.w    #$0002,bltcon1(a5)
  1296.     move.w    d0,bltamod(a5)
  1297.     move.w    d0,bltbmod(a5)
  1298.     move.w    d0,bltdmod(a5)
  1299.     move.l    SS_MaskPlane(a4),a1
  1300.     move.l    MP_MaskPlane(a1),a1
  1301.  
  1302.     add.w    bltstrt,a1
  1303.     move.w    blitsize,d2
  1304.  
  1305. nxtplane:
  1306.  
  1307. ;    The loop for the plane copy
  1308.  
  1309.     CALLGRAF    WaitBlit
  1310.     move.l    a1,bltapt(a5)
  1311.     move.l    a0,bltbpt(a5)
  1312.     move.l    a0,bltdpt(a5)
  1313.  
  1314. ;     shift the colour bit right
  1315. ;     if the carry bit is clear we want to clear the destination memory
  1316. ;     else we want to fill it
  1317.  
  1318.  
  1319.     lsr.w    #1,d6 
  1320.     bcc.s    bltclr
  1321.  
  1322.     move.w    #%0000110111111100,bltcon0(a5)    11011111100
  1323.  
  1324.     bra.s    bltcopy
  1325.  
  1326. bltclr:
  1327.     move.w    #%0000110100001100,bltcon0(a5)
  1328.  
  1329. bltcopy:
  1330. ;    do the copy to destination memory
  1331.  
  1332.     move.w    d2,bltsize(a5)
  1333.  
  1334. ;    increment the plane pointer
  1335.  
  1336.     move.l    SS_Width(a4),d0
  1337.     lsr.l    #3,d0
  1338.     muls.l    SS_Height(a4),d0
  1339.     add.l    d0,a0  
  1340.  
  1341. ;     loop back to the number of planes
  1342.  
  1343.     dbf    d7,nxtplane
  1344.  
  1345.     CALLGRAF    DisownBlitter
  1346.  
  1347. ;    clear the section of the maskplane occupied by the polygon
  1348. ;    using the blitter
  1349.  
  1350.     CALLGRAF    OwnBlitter
  1351.     CALLGRAF    WaitBlit
  1352.     move.l    a1,bltdpt(a5)
  1353.     move.w    blitmod,bltdmod(a5)
  1354.     move.w    #$0002,bltcon1(a5)
  1355.     move.w    #$100,bltcon0(a5)
  1356.     move.w    blitsize,bltsize(a5)
  1357.       CALLGRAF    DisownBlitter
  1358. Fill_Poly_Done
  1359.     PULL    d2-d7/a2-a6
  1360.  
  1361.     rts
  1362.     
  1363.  
  1364.  
  1365.  
  1366.  
  1367. _Draw_Polygon
  1368. ;    a0=screen to draw onto
  1369. ;    a1=list of vertices
  1370. ;    d0=npoints
  1371. ;    d1=colour
  1372.  
  1373.     PUSH    d2-d7/a2-a6
  1374.  
  1375.     move.b    d1,-(sp)        colour onto the stack
  1376.  
  1377.     move.w    d0,d7        number of points onto counter
  1378.     subq.w    #2,d7        decrement d7
  1379.     
  1380.     move.l    a1,a2        store vertex list
  1381.     
  1382.     move.w    (a1)+,d2        get first point
  1383.     move.w    (a1)+,d3
  1384. Poly_Loop    
  1385.     move.w    d2,d0        prev point onto first coords
  1386.     move.w    d3,d1
  1387.     move.w    (a1)+,d2        get next point
  1388.     move.w    (a1)+,d3
  1389.     
  1390.     move.b    (sp)+,d4        colour off stack
  1391.     
  1392.     movem.l    d2-d7/a0-a1,-(sp)
  1393.  
  1394.     bsr.s    _Draw_Line    draw the line.
  1395.  
  1396.     movem.l    (sp)+,d2-d7/a0-a1
  1397.  
  1398.     move.b    d4,-(sp)        colour onto stack
  1399.  
  1400.     dbra    d7,Poly_Loop    loop back to all lines
  1401.  
  1402.     move.b    (sp)+,d4        restore stack
  1403. Poly_Done
  1404.  
  1405.     PULL    d2-d7/a2-a6
  1406.  
  1407.     rts
  1408.  
  1409. _Draw_Line
  1410. ;    Draws a line
  1411. ;    d0,d1=x1,y1
  1412. ;    d2,d3=x2,y2
  1413. ;    d4=colour
  1414.  
  1415. ;    a0=screen structure
  1416.  
  1417. ; ***    Unlike the fill_polygon procedure this routine uses the bresenham 
  1418. ; ***     line drawing algorithm.
  1419.     PUSH    d2-d7/a2-a6
  1420.  
  1421.     move.b    d4,-(sp)
  1422.  
  1423.     moveq.w    #1,d6        d6=IC
  1424.     
  1425.     cmp.w    d1,d3        (y2-y1)=dy
  1426.     bgt.s    ascend        branch if slope>0
  1427.     
  1428. ;    the line must be descending so swap the vertices
  1429.  
  1430.     exg    d0,d2        exchange x1 and x2
  1431.     exg    d1,d3        exchange y1 and y2
  1432.  
  1433. ascend    sub.w    d1,d3        dy is now +ve
  1434.  
  1435.     sub.w    d0,d2        (x2-x1)=dx
  1436.     bgt.s    pos_slope    branch if the slope is +ve    
  1437.  
  1438. ;    the slope must be -ve so make ic -ve
  1439.  
  1440.     neg.w    d6
  1441.     neg.w    d2        now dx is +ve
  1442.  
  1443. pos_slope
  1444.     cmp.w    d2,d3        test dy-dx
  1445.     bgt.s    HiSlope        slope is >1        
  1446.     
  1447. ;    the slope is <1 so increment x each time and check y
  1448. ;    d0=xs, d1=ys, d2=dx, d3=dy
  1449.  
  1450.     move.w    d3,d5        dy into d5    
  1451.     add.w    d5,d5        error1
  1452.  
  1453.     move.w    d5,d7        2*dy into d7
  1454.  
  1455.     move.w    d2,d4        dx into d4
  1456.     add.w    d4,d4        2*dx
  1457.     
  1458.     sub.w    d4,d7        2*dy-2*dx
  1459.     
  1460.     move.w    d7,d4        error2
  1461.  
  1462.     move.w    d2,d7        dx as the counter
  1463.     subq.w    #1,d7        dx-1
  1464.         
  1465.     add.w    d3,d3        2*dy
  1466.     sub.w    d2,d3        (2*dy)-dx:-initial value of D
  1467.     
  1468.     move.b    (sp)+,d2
  1469.     
  1470. line_loop1
  1471.     tst.w    d3        test error        
  1472.     bpl.s    inc_y_and_x
  1473.     add.w    d6,d0        add ic onto xs
  1474.     add.w    d5,d3        increment error
  1475.     bra.s    point_1
  1476. inc_y_and_x    
  1477.     add.w    d6,d0        add ic onto xs
  1478.     addq.w    #1,d1        increment ys
  1479.     add.w    d4,d3        increment error
  1480. point_1 
  1481.     PUSHALL
  1482.     cmp.w    #0,d0        check x minimum
  1483.     bmi.s    no_line_point_1
  1484.  
  1485.     cmp.w    SS_Width+2(a0),d0
  1486.     bpl.s    no_line_point_1
  1487.  
  1488.     cmp.w    #0,d1
  1489.     bmi.s    no_line_point_1
  1490.     
  1491.     cmp.w    SS_Height+2(a0),d1
  1492.     bpl.s    no_line_point_1
  1493.     
  1494.     move.l    a0,a1
  1495.     bsr.s    _Write_Pixel
  1496. no_line_point_1
  1497.     PULLALL    
  1498.  
  1499.     dbra    d7,line_loop1
  1500.     rts
  1501. HiSlope
  1502. ;    the line slope>1 so increment y and check for x
  1503. ;    d0=xs, d1=ys, d2=dx, d3=dy
  1504.  
  1505.     move.w    d2,d5        dx into d5    
  1506.     add.w    d5,d5        error1
  1507.  
  1508.     move.w    d5,d7        2*dx into d7
  1509.  
  1510.     move.w    d3,d4        dy into d4
  1511.     add.w    d4,d4        2*dy
  1512.     
  1513.     sub.w    d4,d7        2*dx-2*dy
  1514.     
  1515.     move.w    d7,d4        error2
  1516.  
  1517.     move.w    d3,d7        dy as the counter
  1518.     subq.w    #1,d7        dy-1
  1519.         
  1520.     add.w    d2,d2        2*dx
  1521.     sub.w    d3,d2        (2*dx)-dy:-initial value of D
  1522.     
  1523.     move.b    (sp)+,d3
  1524.     
  1525. line_loop2
  1526.     tst.w    d2        test error        
  1527.     bpl.s    inc_y
  1528.     addq.w    #1,d1        add ic onto xs
  1529.     add.w    d5,d2        increment error
  1530.     bra.s    point_2
  1531. inc_y    
  1532.     add.w    d6,d0        add ic onto xs
  1533.     addq.w    #1,d1        increment ys
  1534.     add.w    d4,d2        increment error
  1535. point_2
  1536.         
  1537.     PUSHALL
  1538.     cmp.w    #0,d0        check x minimum
  1539.     bmi.s    no_line_point_2
  1540.  
  1541.     cmp.w    SS_Width+2(a0),d0
  1542.     bpl.s    no_line_point_2
  1543.  
  1544.     cmp.w    #0,d1
  1545.     bmi.s    no_line_point_2
  1546.     
  1547.     cmp.w    SS_Height+2(a0),d1
  1548.     bpl.s    no_line_point_2
  1549.  
  1550.     move.b    d3,d2
  1551.     move.l    a0,a1
  1552.     bsr.s    _Write_Pixel
  1553. no_line_point_2
  1554.     PULLALL    
  1555.  
  1556.     dbra    d7,line_loop2    
  1557.  
  1558.     PULL    d2-d7/a2-a6
  1559.  
  1560.     rts
  1561.     
  1562.  
  1563. _Write_Pixel:
  1564. ;    Duuuuuuuhhhhhhhhhhn
  1565. ;    
  1566. ;    input:-    d0=x,d1=y
  1567. ;        d2=colour
  1568. ;        a0=destination screen struct
  1569.  
  1570. ;    probably not as tidy as other write pixels but it has
  1571. ;    to be like this for clipping
  1572.  
  1573.     PUSHALL
  1574.  
  1575.     move.l    a0,a5
  1576.  
  1577.     move.l    SS_Screen(a5),a0
  1578.  
  1579.     move.l    SS_Width(a5),d3
  1580.     lsr.l    #3,d3        byte width of a screen
  1581.  
  1582.     muls.l    d3,d1
  1583.  
  1584.     move.w    d0,d3
  1585.     lsr.w    #3,d0        byte offset into the bitplane
  1586.     add.w    d1,d0
  1587.         
  1588.     andi.w    #%0000000000000111,d3    
  1589.     subq.w    #7,d3
  1590.     neg.w    d3        bit offset of pixel
  1591.  
  1592.     move.l    SS_Planes(a5),d6
  1593.     subq.l    #1,d6
  1594.     add.w    d0,a0        the destination byte in the bitmap
  1595. pcol
  1596.     lsr.w    d2        rotate the colour right
  1597.     bcc.s    clrpoint        carry clear = clear point
  1598.             
  1599.     bset    d3,(a0)
  1600.     bra.s    ploop
  1601. clrpoint
  1602.     bclr    d3,(a0)
  1603. ploop
  1604.     move.l    SS_Width(a5),d0
  1605.     lsr.l    #3,d0
  1606.     muls.l    SS_Height(a5),d0
  1607.     add.l    d0,a0        increment onto next plane
  1608.  
  1609.     dbra    d6,pcol        loop back
  1610.  
  1611.     PULLALL
  1612.  
  1613.     rts
  1614.  
  1615. _Screen_Clear
  1616. ;    clears a screen using the Blit Clear routine
  1617. ;    Should be self explanatory
  1618.  
  1619. ;    a0=screen structure
  1620.  
  1621.     PUSH    d2-d7/a2-a6
  1622.  
  1623.     move.l    a0,a5
  1624.     move.l    SS_Screen(a5),a1
  1625.     move.l    SS_Width(a5),d0
  1626.     lsr.l    #3,d0
  1627.     muls.l    SS_Height(a5),d0
  1628.     muls.l    SS_Planes(a5),d0
  1629.     move.l    #1,d1
  1630.     CALLGRAF    BltClear
  1631.  
  1632.     PULL    d2-d7/a2-a6
  1633.  
  1634.     rts
  1635.  
  1636. _Show
  1637. ; Performs the same job as the show macro in asm
  1638. ; that is it shows the supplied screen
  1639.  
  1640.     PUSH    d2-d7/a2-a6
  1641.     
  1642.     move.l    View(a0),a1
  1643.     CALLGRAF    LoadView
  1644.     
  1645.     PULL    d2-d7/a2-a6
  1646.     
  1647.     rts
  1648.  
  1649.  
  1650. ;---------------------------------------------------------------------
  1651.  
  1652.  
  1653. ;-------- Fade Routines------------------------------------------------
  1654. ;    Fade_To_White(a0,a1)    source screen,source colourmap
  1655. ;    Fade_To_Black(a0,a1)    source screen,source colourmap
  1656. ;    Fade(a0,a1,a2)        screen,source,destination
  1657.  
  1658. _Fade_To_White
  1659. ;    Fades the screen to White and sets the colormap
  1660. ;    a0=screen
  1661. ;    a1=colortable
  1662.  
  1663.     PUSH    d2-d7/a2-a6
  1664.  
  1665.     move.l    a0,a5        store the screen
  1666.     move.l    a1,a2        store the colortable
  1667. White_Main_Loop
  1668.     move.l    a2,a0        get the colortable
  1669.     sf    fade_flag    set the fade flag to false
  1670.     move.w    (a0),d7        get the number of colurs
  1671.     ext.l    d7        extend to longword
  1672.     subq.l    #1,d7        -1 for dbra
  1673.     addq.l    #4,a0        point to first colour value
  1674. White_Fader_Loop
  1675.     move.l    (a0),d0        colour red component
  1676.     cmp.l    #$ffffffff,d0    full on ?
  1677.     beq.s    White_red_done    yes, so don't increment value
  1678.     add.l    #$01010101,d0    else increment red component
  1679.     move.l    d0,(a0)        store the new value
  1680.     st    fade_flag    signal that we have made changes
  1681. White_red_done
  1682.     addq.l    #4,a0        offset to blue value
  1683.     move.l    (a0),d0        get the blue component 
  1684.     cmp.l    #$ffffffff,d0    full on ?
  1685.     beq.s    White_blue_done    yes so don't change
  1686.     add.l    #$01010101,d0    else increment value
  1687.     move.l    d0,(a0)        store the new value
  1688.     st    fade_flag    signal change
  1689. White_blue_done
  1690.     addq.l    #4,a0        same here as above but for green
  1691.     move.l    (a0),d0        components
  1692.     cmp.l    #$ffffffff,d0
  1693.     beq.s    White_green_done
  1694.     add.l    #$01010101,d0
  1695.     move.l    d0,(a0)
  1696.     st    fade_flag        
  1697. White_green_done
  1698.     addq.l    #4,a0        point to next full colour
  1699.  
  1700. ;    loop for all colours
  1701.  
  1702.     dbra    d7,White_Fader_Loop
  1703.  
  1704. ;     If this flag isn't set we are all done so exit out
  1705.  
  1706.     tst.b    fade_flag
  1707.     beq.s    White_fade_done
  1708.  
  1709. ;    else load the new values into the viewport
  1710.  
  1711.     move.l    SS_ViewPort(a5),a0
  1712.     move.l    a2,a1
  1713.     CALLGRAF    LoadRGB32
  1714.  
  1715.     CALLGRAF    WaitTOF
  1716.  
  1717.     bra    White_Main_Loop
  1718.  
  1719. White_fade_done    
  1720.     PULL    d2-d7/a2-a6
  1721.     rts
  1722.  
  1723.  
  1724. _Fade_To_Black
  1725. ;    Fades the screen to black and clears the colormap
  1726. ;    operates in a similar way to the above procedure
  1727. ;    but instead of incrementing the colour values we decrement them.
  1728.  
  1729. ;    a0=screen
  1730. ;    a1=source colourmap
  1731.  
  1732.     PUSH    d2-d7/a2-a6
  1733.  
  1734.     move.l    a1,a2
  1735.     move.l    a0,a5
  1736.     
  1737. Black_Main_Loop
  1738.     move.l    a2,a0
  1739.     sf    fade_flag
  1740.     move.w    (a0),d7
  1741.     ext.l    d7
  1742.     subq.l    #1,d7
  1743.     addq.l    #4,a0
  1744. Black_Fader_Loop
  1745.     move.l    (a0),d0
  1746.     beq.s    black_red_done
  1747.     sub.l    #$01010101,d0
  1748.     move.l    d0,(a0)
  1749.     st    fade_flag
  1750. black_red_done
  1751.     addq.l    #4,a0
  1752.     move.l    (a0),d0
  1753.     beq.s    black_blue_done
  1754.     sub.l    #$01010101,d0    
  1755.     move.l    d0,(a0)
  1756.     st    fade_flag
  1757. black_blue_done
  1758.     addq.l    #4,a0
  1759.     move.l    (a0),d0
  1760.     beq.s    black_green_done
  1761.     sub.l    #$01010101,d0
  1762.     move.l    d0,(a0)
  1763.     st    fade_flag        
  1764. black_green_done
  1765.     addq.l    #4,a0
  1766.     dbra    d7,Black_Fader_Loop
  1767.  
  1768.     tst.b    fade_flag
  1769.     beq.s    black_fade_done
  1770.     
  1771.     move.l    SS_ViewPort(a5),a0
  1772.     move.l    a2,a1
  1773.     CALLGRAF    LoadRGB32
  1774.  
  1775.     CALLGRAF    WaitTOF
  1776.  
  1777.     bra    Black_Main_Loop
  1778.  
  1779. black_fade_done    
  1780.  
  1781.     PULL    d2-d7/a2-a6    
  1782.  
  1783.     rts
  1784.  
  1785. _Fade
  1786. ;    fades between 2 colourmaps
  1787. ;    a0=screen
  1788. ;    a1=source cmap
  1789. ;    a2=destination cmap
  1790.  
  1791.     PUSH    d2-d7/a2-a6
  1792.  
  1793.     move.l    a0,a5
  1794.  
  1795.     move.l    a2,a3
  1796.     move.l    a1,a2
  1797.  
  1798.     move.l    SS_Planes(a5),d1    allocate a temporary colourmap
  1799.     move.l    #0,d0        for the fading
  1800.     bset    d1,d0
  1801.     muls    #12,d0
  1802.     add.l    #8,d0
  1803.     move.l    d0,d3    
  1804.     move.l    #MEMF_ANY,d1
  1805.     CALLEXEC    AllocMem
  1806.     move.l    d0,a4        storage for temporary cmap
  1807.  
  1808.     move.l    a2,a0        copy the initial colourmap to the
  1809.     move.l    a4,a1        temporary one
  1810.     move.l    d3,d0
  1811.     CALLEXEC    CopyMem
  1812.  
  1813.  
  1814. Fader_Main_Loop
  1815.  
  1816.     move.l    a5,-(sp)        store the screen structure
  1817.  
  1818.     move.l    a4,a5        temporary cmap into a5
  1819.     
  1820.     move.l    a2,a0        both cmaps to temporary areas
  1821.     move.l    a3,a1
  1822.  
  1823.     sf    fade_flag    clear the fade flag
  1824.  
  1825.     move.w    (a0),d7        number of colours
  1826.     ext.l    d7        extend to longword
  1827.     subq.l    #1,d7
  1828.     addq.l    #4,a5        update the cmaps to first colour
  1829.     addq.l    #4,a1
  1830. Fader_Loop
  1831.     move.l    (a5),d0        source colour
  1832.     move.l    (a1),d1        destination colour
  1833.     cmp.l    d0,d1        compare the 2
  1834.     beq.s    red_done        if they are equal we are done
  1835.     bcs.s    decrement_red    less so decrement the value
  1836. increment_red
  1837. ;    if we get to here we want to increment the value
  1838.     add.l    #$01010101,d0
  1839.     bra.s    put_red    
  1840. decrement_red
  1841.     sub.l    #$01010101,d0    decrement the value
  1842. put_red
  1843.     move.l    d0,(a5)        store the flag
  1844.     st    fade_flag    set the status flag
  1845. red_done
  1846.     addq.l    #4,a5        next component
  1847.     addq.l    #4,a1
  1848.  
  1849.     move.l    (a5),d0        does the same as above but for the
  1850.     move.l    (a1),d1        blue components
  1851.     cmp.l    d0,d1
  1852.     beq.s    blue_done
  1853.     bcs.s    decrement_blue
  1854. increment_blue
  1855.     add.l    #$01010101,d0
  1856.     bra.s    put_blue
  1857. decrement_blue
  1858.     sub.l    #$01010101,d0    
  1859. put_blue
  1860.     move.l    d0,(a5)
  1861.     st    fade_flag
  1862. blue_done
  1863.     addq.l    #4,a5
  1864.     addq.l    #4,a1
  1865.  
  1866.     move.l    (a5),d0        does the same but for green components
  1867.     move.l    (a1),d1
  1868.     cmp.l    d0,d1
  1869.     beq.s    green_done
  1870.     bcs.s    decrement_green
  1871. increment_green
  1872.     add.l    #$01010101,d0
  1873.     bra.s    put_green
  1874. decrement_green
  1875.     sub.l    #$01010101,d0
  1876. put_green
  1877.     move.l    d0,(a5)
  1878.     st    fade_flag        
  1879. green_done
  1880.     addq.l    #4,a5
  1881.     addq.l    #4,a1
  1882.     dbra    d7,Fader_Loop
  1883.  
  1884.     move.l    (sp)+,a5
  1885.  
  1886.     tst.b    fade_flag
  1887.     beq.s    fade_done
  1888.  
  1889.     move.l    SS_ViewPort(a5),a0
  1890.     move.l    a4,a1
  1891.     CALLGRAF    LoadRGB32
  1892.  
  1893.     CALLGRAF    WaitTOF
  1894.     bra    Fader_Main_Loop
  1895.  
  1896. fade_done    
  1897.  
  1898.     move.l    SS_Planes(a5),d1
  1899.     move.l    #0,d0
  1900.     bset    d1,d0
  1901.     muls    #12,d0
  1902.     add.l    #8,d0
  1903.     move.l    d0,d3
  1904.     move.l    a4,a1
  1905.     CALLEXEC    FreeMem            free the temporary map
  1906.  
  1907.     PULL    d2-d7/a2-a6
  1908.  
  1909.     rts
  1910.  
  1911. ;---------------------------------------------------------------------
  1912.  
  1913. ;-------- IFF Handling routines reading and writing of bitmaps ---------
  1914. ;    Save_IFF(a0,a1)=filename APTR, screen ADDR
  1915. ;    Load_IFF(a0,a1)=filename APTR, screen ADDR
  1916.  
  1917. ;    These procedures use the IFF_Library v23.2 by CHRISTIAN A. WEBE
  1918. ;    For more information please see the distribution along
  1919. ;    with this file
  1920.  
  1921. _Load_IFF
  1922. ;    loads an iff into one a screen
  1923. ;    a0=filename
  1924. ;    a1=destination screen structure
  1925. ;        
  1926.  
  1927.     PUSH    d2-d7/a2-a6
  1928.  
  1929.     movem.l    a0-a1,-(sp)
  1930.  
  1931.     OPENLIB    _IFFLib,0,_IFFBase    open the library
  1932.     
  1933.     movem.l    (sp)+,a0-a1
  1934.  
  1935.     move.l    a1,-(sp)            store the screen structure
  1936.  
  1937.     moveq.l    #IFFL_MODE_READ,d0
  1938.     CALLIFF    IFFL_OpenIFF        open the IFF file
  1939.  
  1940.     move.l    d0,a4            iff_handle
  1941.  
  1942.     move.l    (sp)+,a5            screen structure into a5
  1943.  
  1944.     move.l    SS_BitMap(a5),a0        destination bitmap into a0
  1945.  
  1946.     move.l    a4,a1            
  1947.     CALLIFF    IFFL_DecodePic        decode the iff picture data
  1948.  
  1949.     move.l    a4,a0
  1950.     move.l    SS_ColorTable(a5),a1
  1951.     bsr    Full_Palette        get the full 24 bit palette data
  1952.  
  1953.     move.l    SS_ViewPort(a5),a0
  1954.     move.l    SS_ColorTable(a5),a1
  1955.     CALLGRAF    LoadRGB32        load the colour data
  1956.  
  1957.     move.l    a4,a1
  1958.     CALLIFF    IFFL_CloseIFF        close the file
  1959.     
  1960.     CLOSELIB    _IFFBase            close the library
  1961.  
  1962.     PULL    d2-d7/a2-a6
  1963.  
  1964.     rts
  1965.  
  1966.  
  1967. _Save_IFF:
  1968. ;    save a screen as an iff
  1969. ;    a0=filename
  1970. ;    a1=screen to save
  1971.  
  1972.     PUSH    d2-d7/a2-a6
  1973.  
  1974.     movem.l    a0-a1,-(sp)
  1975.  
  1976.     OPENLIB    _IFFLib,0,_IFFBase    open the library
  1977.  
  1978.     movem.l    (sp)+,a0-a1
  1979.  
  1980.     move.l    a1,a5
  1981.  
  1982.     move.l    #IFFL_MODE_WRITE,d0
  1983.     CALLIFF    IFFL_OpenIFF        open a new iff file
  1984.     move.l    d0,a4
  1985.     
  1986. ;-------  Write the BMHD chunk to the IFF file
  1987.     
  1988.     move.l    a4,a0
  1989.     move.l    #ID_ILBM,d0
  1990.     move.l    #ID_BMHD,d1
  1991.     CALLIFF    IFFL_PushChunk        make a new chunk
  1992.     
  1993.     move.l    #20,d0
  1994.     move.l    #MEMF_ANY,d1
  1995.     CALLEXEC    AllocMem            allocate temporary memory
  1996.     
  1997.     move.l    d0,a3
  1998.  
  1999.     move.l    a3,a0
  2000.     move.w    SS_Width+2(a5),(a0)+    width in pixels
  2001.     move.w    SS_Height+2(a5),(a0)+    height in pixels
  2002.     move.w    #0,(a0)+            x offset
  2003.     move.w    #0,(a0)+            y offset
  2004.     move.b    SS_Planes+3(a5),(a0)+    number of bitplanes
  2005.     move.b    #0,(a0)+            masking bit
  2006.     move.b    #1,(a0)+            compression y/n
  2007.     move.b    #0,(a0)+            pad bit    
  2008.     move.w    #0,(a0)+            transparent
  2009.     move.b    #$2c,(a0)+        x aspect assume lowres
  2010.     move.b    #$2c,(a0)+        y aspect assume lowres
  2011.     move.w    SS_Width+2(a5),(a0)+    page width
  2012.     move.w    SS_Height+2(a5),(a0)+    page height    
  2013.  
  2014.     move.l    a4,a0
  2015.     move.l    a3,a1
  2016.     move.l    #20,d0
  2017.     CALLIFF    IFFL_WriteChunkBytes    write the chunk to the file
  2018.  
  2019.     move.l    a3,a1
  2020.     move.l    #20,d0
  2021.     CALLEXEC    FreeMem            free the temp memory
  2022.  
  2023.     move.l    a4,a0
  2024.     CALLIFF    IFFL_PopChunk        finished with this chunk
  2025.  
  2026. ;-------- Done writing the BMHD chunk
  2027.  
  2028. ;-------- Write the CMAP chunk
  2029.  
  2030.     move.l    a4,a0
  2031.     move.l    #ID_ILBM,d0
  2032.     move.l    #ID_CMAP,d1
  2033.     CALLIFF    IFFL_PushChunk        set up a new chunk
  2034.     
  2035.     move.l    #0,d0            clear d0
  2036.     move.l    SS_Planes(a5),d1        nplanes into d1
  2037.     bset    d1,d0            ncol
  2038.     muls    #3,d0            *3
  2039.     move.l    d0,d3
  2040.     move.l    #MEMF_ANY,d1
  2041.     CALLEXEC    AllocMem            allocate some temp memory
  2042.     
  2043.     move.l    d0,a3
  2044.  
  2045. ;    Here we want to copy the colourtable data into our temporary
  2046. ;    storage and pop it out onto our IFF file
  2047.  
  2048.     move.l    a3,a0
  2049.     move.l    SS_ColorTable(a5),a1
  2050.     move.l    d3,d7
  2051.     subq.l    #1,d7
  2052.     add.l    #4,a1
  2053. CMAP_loop
  2054.     move.l    (a1)+,d0
  2055.     move.b    d0,(a0)+
  2056.     dbra    d7,CMAP_loop                
  2057.  
  2058.     move.l    a4,a0
  2059.     move.l    a3,a1
  2060.     move.l    d3,d0
  2061.     CALLIFF    IFFL_WriteChunkBytes    write the new chunk data
  2062.  
  2063.     move.l    a3,a1
  2064.     move.l    d3,d0
  2065.     CALLEXEC    FreeMem            free the temporary memory
  2066.  
  2067.     move.l    a4,a0
  2068.     CALLIFF    IFFL_PopChunk        done with this chunk
  2069.  
  2070. ;-------- Done writing the CMAP chunk to the file
  2071.  
  2072. ;-------- Write the BODY data of the file
  2073.  
  2074.     move.l    a4,a0
  2075.     move.l    #ID_ILBM,d0
  2076.     move.l    #ID_BODY,d1
  2077.     CALLIFF    IFFL_PushChunk        make a new chunk
  2078.  
  2079.     move.l    SS_Width(a5),d0        WIDTH
  2080.     lsr.l    #3,d0            /8
  2081.     muls.l    SS_Height(a5),d0        *HEIGHT
  2082.     muls.l    SS_Planes(a5),d0        *NPLANES
  2083.     
  2084.     move.l    #MEMF_ANY,d1
  2085.     CALLEXEC    AllocMem            allocate some temp memory
  2086.     
  2087.     move.l    d0,a3
  2088.  
  2089.     move.l    #0,d5            compressed size
  2090.  
  2091.     move.l    a3,a1            temporary memory
  2092.  
  2093.     move.l    #0,d6            y counter
  2094. Comp_Height_Loop
  2095.     move.l    SS_Screen(a5),a0
  2096.     move.l    d6,d0
  2097.     move.l    SS_Width(a5),d1
  2098.     lsr.l    #3,d1
  2099.     muls    d1,d0
  2100.     add.l    d0,a0            
  2101.  
  2102. ;    set up for the compression loop
  2103. ;    compressed image data has to be interleaved
  2104.  
  2105.     move.l    SS_Planes(a5),d7
  2106.     subq.l    #1,d7
  2107.     
  2108. Comp_Plane_Loop
  2109.     move.l    a0,-(sp)
  2110.     move.l    SS_Width(a5),d0
  2111.     lsr.l    #3,d0
  2112.     move.l    #IFFL_COMPR_BYTERUN1,d1    compress the current scan line
  2113.     
  2114.     CALLIFF    IFFL_CompressBlock
  2115.  
  2116.     move.l    (sp)+,a0
  2117.  
  2118.     add.l    d0,d5
  2119.  
  2120.     move.l    SS_Width(a5),d0
  2121.     lsr.l    #3,d0
  2122.     muls.l    SS_Height(a5),d0        
  2123.     
  2124.     add.l    d0,a0
  2125.     dbra    d7,Comp_Plane_Loop    onto the next plane
  2126.  
  2127.     move.l    SS_Height(a5),d0
  2128.     subq.l    #1,d0
  2129.     cmp.l    d0,d6
  2130.     bge.s    comp_done
  2131.     addq.l    #1,d6
  2132.     bra.s    Comp_Height_Loop        onto the next scan line
  2133. comp_done
  2134.     move.l    a4,a0
  2135.     move.l    a3,a1
  2136.     move.l    d5,d0
  2137.     CALLIFF    IFFL_WriteChunkBytes    write the data
  2138.  
  2139.     move.l    a3,a1
  2140.     move.l    SS_Width(a5),d0        WIDTH
  2141.     lsr.l    #3,d0            /8
  2142.     muls.l    SS_Height(a5),d0        *HEIGHT
  2143.     muls.l    SS_Planes(a5),d0        *NPLANES
  2144.  
  2145.     CALLEXEC    FreeMem            free our temporary memory
  2146.  
  2147.     move.l    a4,a0
  2148.     CALLIFF    IFFL_PopChunk        pop this chunk off
  2149.  
  2150. ;-------- Done writing the BODY data
  2151.  
  2152.     move.l    a4,a1
  2153.     CALLIFF    IFFL_CloseIFF        finished with the file
  2154.  
  2155.     CLOSELIB    _IFFBase            close the library
  2156.  
  2157.     PULL    d2-d7/a2-a6
  2158.  
  2159.     rts
  2160.  
  2161. Full_Palette
  2162. ;    Gets the 24 bit colour information from an iff file
  2163. ;    needs IFF Library
  2164. ;    Internal IFF Routine used by load iff
  2165.  
  2166. ;    in:- a0=handle
  2167. ;         a1=destination colourmap
  2168.     
  2169.     PUSH    a0-a1
  2170.  
  2171.     move.l    a0,a1
  2172.     move.l    #ID_CMAP,d0
  2173.     CALLIFF    IFFL_FindChunk        find the CMAP Chunk
  2174.     
  2175.     move.l    d0,a2            store this memory
  2176.  
  2177.     PULL    a0-a1
  2178.  
  2179.     addq.w    #4,a2
  2180.  
  2181.     move.l    (a2)+,d7            number of colours to 
  2182.     move.l    d7,d0            amount of data to strip out
  2183.     divs    #3,d0
  2184.     move.w    d0,(a1)+            number of colours into colormap
  2185.     addq.w    #2,a1            onto first location
  2186.  
  2187.     subq.l    #1,d7
  2188. _col_loop
  2189.     moveq.l    #0,d0            
  2190.     move.b    (a2),d0            first value
  2191.     lsl.l    #8,d0            shift up
  2192.     move.b    (a2),d0            get value again
  2193.     lsl.l    #8,d0            shift up
  2194.     move.b    (a2),d0            get value again
  2195.     lsl.l    #8,d0            shift up
  2196.     move.b    (a2)+,d0            get value again        
  2197.     
  2198.     move.l    d0,(a1)+            write colour data
  2199.     dbra    d7,_col_loop
  2200.  
  2201.     rts    
  2202.  
  2203. ;-------- End of IFF Routines -----------------------------------------------
  2204.  
  2205. ;-------- File handling Routines ----------------------------------------
  2206. ;    Load_Data(a0,d0,a1)        filename, buffer length, destination
  2207. ;    Save_Data(a0,d0,d1)        filename, buffer length, source
  2208.  
  2209. _Load_Data
  2210. ;    Loads data from a file
  2211.  
  2212. ;    input    a0=filename
  2213. ;        d0=byte size of data to read
  2214. ;        a1=destination buffer
  2215.  
  2216.     PUSH    d2-d7/a2-a6
  2217.  
  2218.     move.l    d0,-(sp)
  2219.  
  2220.     PUSHALL
  2221.  
  2222.     OPENLIB    _DosLib,0,_DOSBase
  2223.     
  2224.     PULLALL
  2225.     
  2226.     move.l    a0,d1            filename into d1
  2227.     move.l    #MODE_OLDFILE,d2        type of file
  2228.     PUSH    d0-d3/a0-a1        store registers
  2229.     CALLDOS    Open            open the file
  2230.     tst.l    d0
  2231.     beq.s    Open_Failed
  2232.     move.l    d0,d5            store the filehandle
  2233.     PULL    d0-d3/a0-a1        restore registers
  2234.  
  2235.     move.l    d5,d1            filehandle into d1
  2236.     move.l    a1,d2            desination for the data
  2237.     move.l    (sp)+,d3            size of the data
  2238.     
  2239.     CALLDOS    Read            read the data
  2240.     
  2241.     move.l    d5,d1            filehandle into d1
  2242.     CALLDOS    Close            close the file
  2243.     
  2244. Open_Failed        
  2245.     
  2246.     CLOSELIB    _DOSBase
  2247.  
  2248.     PULL    d2-d7/a2-a6
  2249.  
  2250.     rts
  2251.  
  2252. _Save_Data
  2253. ;    saves data from a file
  2254.  
  2255. ;    input    a0=filename
  2256. ;        d0=byte size of data to write
  2257. ;        a1=source buffer
  2258.  
  2259.     PUSH    d2-d7/a2-a6
  2260.  
  2261.     move.l    d0,-(sp)
  2262.  
  2263.     PUSHALL
  2264.  
  2265.     OPENLIB    _DosLib,0,_DOSBase
  2266.     
  2267.     PULLALL
  2268.     
  2269.     move.l    a0,d1            filename into d1
  2270.     move.l    #MODE_NEWFILE,d2        type of file
  2271.     PUSH    d0-d3/a0-a1        store registers
  2272.     CALLDOS    Open            open the file
  2273.     tst.l    d0
  2274.     beq.s    Save_Open_Failed
  2275.     move.l    d0,d5            store the filehandle
  2276.     PULL    d0-d3/a0-a1        restore registers
  2277.  
  2278.     move.l    d5,d1            filehandle into d1
  2279.     move.l    a1,d2            source for the data
  2280.     move.l    (sp)+,d3            size of the data
  2281.     
  2282.     CALLDOS    Write            read the data
  2283.     
  2284.     move.l    d5,d1            filehandle into d1
  2285.     CALLDOS    Close            close the file
  2286.     
  2287. Save_Open_Failed        
  2288.     
  2289.     CLOSELIB    _DOSBase
  2290.  
  2291.     PULL    d2-d7/a2-a6
  2292.  
  2293.     rts
  2294. ;------------------------------------------------------------------------
  2295.  
  2296.  
  2297. ;-------- Text handling routines -------------------------------------------
  2298. ;    Write_Text(a0,a1,d0,d1,d2,d3)    screen, text, x, y, colour, length
  2299. ;    Num_To_String(d0)            word
  2300.  
  2301. _Write_Text
  2302. ;    writes the text to the screen using the current font
  2303. ;    a0=screen
  2304. ;    a1=text
  2305. ;    d0=x
  2306. ;    d1=y
  2307. ;    d2=colour
  2308. ;    d3=string length
  2309.  
  2310.     PUSH    d2-d7/a2-a6
  2311.  
  2312.     exg.l    a1,a0            get the screen and text into the right reg
  2313.  
  2314.     move.l    SS_RastPort(a1),a1    rastport into a1    
  2315.  
  2316.     movem.l    a0-a1/d0-d3,-(sp)
  2317.     CALLGRAF    Move            move to the text position
  2318.     movem.l    (sp)+,a0-a1/d0-d3
  2319.  
  2320.     movem.l    a0-a1/d0-d3,-(sp)
  2321.     move.l    d2,d0
  2322.     CALLGRAF    SetAPen            set the colour
  2323.     movem.l    (sp)+,a0-a1/d0-d3
  2324.  
  2325.     move.l    d3,d0            text length into d0
  2326.  
  2327.     CALLGRAF    Text            write the text
  2328.  
  2329.     PULL    d2-d7/a2-a6
  2330.  
  2331.     rts
  2332.  
  2333. _Num_To_String:
  2334. ;    converts a word value into a hex string
  2335. ;    string returned in a1
  2336.  
  2337. ;    d0=word
  2338.  
  2339.     PUSH    d2-d7/a2-a6
  2340.  
  2341.     move.w    d0,d1
  2342.     move.w    d1,d2
  2343.     move.w    d2,d3
  2344.  
  2345.     and.w    #%0000000000001111,d0    get the lower byte value
  2346.     and.w    #%0000000011110000,d1    get the successive bytes
  2347.     and.w    #%0000111100000000,d2
  2348.     and.w    #%1111000000000000,d3
  2349.     
  2350.     lsr.w    #4,d1            get these values to the lowest
  2351.     lsr.w    #8,d2            position by shifting
  2352.     lsr.w    #6,d3
  2353.     lsr.w    #6,d3
  2354.  
  2355.     cmp.b    #9,d0            if we have a number
  2356.     bgt.s    do_char_d0
  2357.     add.b    #$30,d0            add the '0' onto it
  2358.     bra.s    done_d0            all done
  2359. do_char_d0
  2360.     sub.b    #10,d0            else subtract 10
  2361.     add.b    #$41,d0            add the 'A' onto it
  2362. done_d0
  2363.     cmp.b    #9,d1            do the same for the four other
  2364.     bgt.s    do_char_d1        registers
  2365.     add.b    #$30,d1
  2366.     bra.s    done_d1
  2367. do_char_d1
  2368.     sub.b    #10,d1
  2369.     add.b    #$41,d1
  2370. done_d1
  2371.     cmp.b    #9,d2
  2372.     bgt.s    do_char_d2
  2373.     add.b    #$30,d2
  2374.     bra.s    done_d2
  2375. do_char_d2
  2376.     sub.b    #10,d2
  2377.     add.b    #$41,d2
  2378. done_d2
  2379.     cmp.b    #9,d3
  2380.     bgt.s    do_char_d3
  2381.     add.b    #$30,d3
  2382.     bra.s    done_d3
  2383. do_char_d3
  2384.     sub.b    #10,d3
  2385.     add.b    #$41,d3
  2386. done_d3
  2387.  
  2388.     lea    num_string,a0
  2389.     move.b    d3,(a0)+            write the data to the number string
  2390.     move.b    d2,(a0)+
  2391.     move.b    d1,(a0)+
  2392.     move.b    d0,(a0)+
  2393.     move.b    #0,(a0)+
  2394.     
  2395.     lea    num_string,a1
  2396.  
  2397.     move.l    a1,d0
  2398.  
  2399.     PULL    d2-d7/a2-a6
  2400.  
  2401.     rts    
  2402.  
  2403.  
  2404. ;------------------------------------------------------------------------
  2405.  
  2406. ;-------- Copper  handling routines -------------------------------------
  2407. ;    Add_Copper(a0,a1)        screen,copper list
  2408.  
  2409. _Add_Copper
  2410. ;    Adds a copper list stream to the specified screen
  2411. ;    a0=screen
  2412. ;    a1=copper instructions
  2413.  
  2414.     PUSH    d2-d7/a2-a6
  2415.     
  2416.     move.l    a0,a5
  2417.     move.l    a1,a2
  2418.  
  2419.     move.l    #12,d0            enough space for a user copper struc
  2420.     move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  2421.     CALLEXEC    AllocMem            allocate memory for a user copper structure
  2422.     
  2423.     move.l    d0,SS_UserCopperList(a5)
  2424.  
  2425.     move.l    SS_UserCopperList(a5),a0
  2426.     move.l    #5000,d0            allocate enough space for 5000 entries
  2427.     CALLGRAF    UCopperListInit    
  2428.  
  2429. .Copper_Loop    
  2430.     move.l    (a2),d0
  2431.     cmp.l    #$fffffffe,d0        check if we have a copper end instruction
  2432.     beq.s    .Copper_Done
  2433.     move.w    2(a2),d0            
  2434.     cmp.w    #$fffe,d0        else check if it is a copper move
  2435.     bne.s    .Copper_Move
  2436. .Copper_Wait
  2437.     move.w    (a2),d0            we want to feed a copper wait
  2438.     move.w    #0,d1            into the copper stream
  2439.     move.b    d0,d1            so decode and write it
  2440.     lsr.w    #8,d0
  2441.     move.l    SS_UserCopperList(a5),a1
  2442.     CALLGRAF    CWait
  2443.     move.l    SS_UserCopperList(a5),a1
  2444.     CALLGRAF    CBump
  2445.     add.w    #4,a2
  2446.     bra.s    .Copper_Loop
  2447. .Copper_Move
  2448.     move.w    (a2)+,d0            decode the move instruction
  2449.     move.w    (a2)+,d1            and feed it into the copper
  2450.     move.l    SS_UserCopperList(a5),a1    stream
  2451.     CALLGRAF    CMove
  2452.     move.l    SS_UserCopperList(a5),a1
  2453.     CALLGRAF    CBump
  2454.     bra.s    .Copper_Loop
  2455. .Copper_Done
  2456.  
  2457.     move.l    SS_UserCopperList(a5),a1    all done so write the copper
  2458.     move.w    #10000,d0        end instruction to the stream
  2459.     move.w    #255,d1
  2460.     CALLGRAF    CWait
  2461.     move.l    SS_UserCopperList(a5),a1
  2462.     CALLGRAF    CBump 
  2463.  
  2464.     CALLEXEC    Forbid            latch the copper list onto
  2465.     move.l    SS_ViewPort(a5),a0    the viewport
  2466.     move.l    SS_UserCopperList(a5),vp_UCopIns(a0)
  2467.     
  2468.     move.l    SS_View(a5),a0    
  2469.     move.l    SS_ViewPort(a5),a1
  2470.     CALLGRAF    MakeVPort        remake the viewport
  2471.     
  2472.     move.l    SS_View(a5),a1
  2473.     CALLGRAF    MrgCop            merge the copperlist
  2474.     
  2475.     SHOW    a5            show the screen
  2476.  
  2477.     CALLEXEC    Permit
  2478.  
  2479.     PULL    d2-d7/a2-a6
  2480.  
  2481.     rts
  2482.  
  2483. ;------------------------------------------------------------------------
  2484.  
  2485. ;-------- Input Handling Routines ---------------------------------------
  2486. ;    GetKey()
  2487.  
  2488.  
  2489. _GetKey 
  2490.  
  2491.     PUSH    d2-d7/a2-a6
  2492.  
  2493.     moveq.l         #0,d0           clear the register
  2494.          move.b          $BFEC01,d0      get value from CIA chip
  2495.          not.b           d0              manipulate it to form raw
  2496.          ror.b           #1,d0           key code
  2497.  
  2498.     PULL    d2-d7/a2-a6
  2499.  
  2500.          rts
  2501.  
  2502. ;------------------------------------------------------------------------
  2503.  
  2504.  
  2505.     Section    System_Data,DATA_F
  2506. ;    Data required by the above routines
  2507.  
  2508. _DosLib
  2509.     DOSNAME
  2510.     even
  2511. _graphics_lib
  2512.     GRAFNAME    
  2513.     even
  2514. _IFFLib
  2515.     IFFNAME
  2516.     even
  2517.     
  2518. *TagItem structure
  2519. vctags:
  2520.     dc.l    VTAG_ATTACH_CM_SET,0
  2521.     dc.l    VTAG_VIEWPORTEXTRA_SET,0
  2522.     dc.l    VTAG_NORMAL_DISP_SET,0
  2523.     dc.l    VTAG_END_CM,0
  2524.  
  2525.     Section    System_BSS,BSS_F
  2526. ;    storage required by the above routines
  2527. _IntuitionBase:
  2528.     ds.l    1
  2529. _GfxBase
  2530.     ds.l    1
  2531. _IFFBase
  2532.     ds.l    1
  2533. _DOSBase
  2534.     ds.l    1
  2535. _oldview
  2536.     ds.l    1
  2537. clip_out
  2538.     ds.l    1
  2539. line_flag
  2540.     ds.l    1
  2541. fade_flag
  2542.     ds.l    1
  2543. x_min
  2544.     ds.w    1
  2545. x_max
  2546.     ds.w    1
  2547. y_min
  2548.     ds.w    1
  2549. y_max
  2550.     ds.w    1
  2551. blitmod
  2552.     ds.w    1
  2553. bltwidth
  2554.     ds.w    1
  2555. blitsize
  2556.     ds.w    1
  2557. bltstrt
  2558.     ds.w    1
  2559. num_string
  2560.     ds.b    5
  2561.  
  2562.