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