home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / PART_F / VIEWMAN / MOVE.S < prev    next >
Encoding:
Text File  |  2001-02-10  |  56.9 KB  |  2,931 lines

  1. *
  2. *    MOVE.S
  3. *
  4.     .include    "equates.s"
  5. *
  6.     .text
  7. *
  8. *
  9. ***********************************************
  10. ;
  11. ; d0 - x mouse position
  12. ; d1 - y mouse position
  13. *
  14. DaveButton:
  15. *
  16.     bclr.b    #1,BUT_STATE+1
  17.     bne    lib_sel
  18.     bclr.b    #0,BUT_STATE+1
  19.     bne    wor_sel
  20. nolfbut:
  21.     rts
  22. *
  23. *
  24. *
  25. *   We call this every time we start with a down mouse button..
  26. *
  27. butninit:
  28.     clr.w    keyz
  29.     clr.w    grid        ;start out of grid mode
  30. *
  31.     move.w    #MouseOff,d0
  32.     bsr    Graf_Mouse        ;turn off the mouse
  33. *
  34.     move.l    mouseptr,a0        ;get mouse ptr
  35.     movem.w    (a0),d0-d1        ;d0 = xpos, d1 = ypos
  36.     movem.w    d0-d1,mousex        ;save when we restore
  37. clipinit:
  38.     lea    wstruct+xoffset,a5
  39.     movem.w    wx(a5),d0-d1
  40.     move.w    d0,d2
  41.     move.w    d1,d3
  42. *
  43.     add.w    wwidth(a5),d2
  44.     subq.w    #1,d2        ;check window right-edge beyond screen
  45.     cmp.w    form_width,d2
  46.     ble    butixok
  47.     move.w    form_width,d2
  48. butixok:
  49.     addq.w    #1,d2
  50. *
  51.     add.w    wheight(a5),d3
  52.     subq.w    #1,d3        ;check window bottom-edge beyond screen
  53.     cmp.w    form_height,d3
  54.     ble    butiyok
  55.     move.w    form_height,d3
  56. butiyok:
  57.     addq.w    #1,d3
  58.     movem.w    d0-d3,xmin_clp
  59.     movem.w    d0-d3,Mclpxmn    ;init motion clip variables to window
  60. *
  61.     movem.w    wwidth(a5),d0-d1
  62.     lsr.w    #1,d0
  63.     lsr.w    #1,d1
  64.     add.w    wx(a5),d0    ;mouse relative positioning
  65.     add.w    wy(a5),d1    ;needs a safe place--
  66.     movem.w    d0-d1,relcentx    ;put it smack in the center of window
  67.     move.l    mouseptr,a0
  68.     move.l    relcentx,(a0)    ;put rel mouse at a nice place
  69. *    
  70.     movem.w    mousex,d0-d1
  71. *
  72.     rts
  73. *
  74. *
  75. *
  76. *  Left button has gone down--select an existing item from the world
  77. *
  78. wor_sel:
  79.     movem.l    a0-a6/d0-d7,-(sp)
  80. *
  81.     bsr    butninit
  82. *
  83. *  d0 = mousex, d1 = mousey on screen..
  84. *
  85.     sub.w    wx(a5),d0
  86.     add.w    xoffset(a5),d0    ;adjust for world co-ords
  87.     sub.w    wy(a5),d1
  88.     add.w    yoffset(a5),d1
  89. *
  90. *  Search the worldblk for the highest priority object
  91. *   whose rectangle falls within the mouse position
  92. *
  93.     cmp.w    w_wid(a5),d0    ;are we right of the world
  94.     bge    wor_selx    ;br if so
  95.     cmp.w    w_hite(a5),d1
  96.     bge    wor_selx    ;br if below world
  97. *
  98.     move.l    wblkptr,a0        ;get pointer to end +1
  99.     move.l    #worldblk,a1        ; & ptr to beginning
  100.     lea    bshblock,a2
  101.     bra    findreci
  102. findlp:
  103.     move.w    -(a0),d3    ;get vpos
  104.     move.w    -(a0),d2    ;hpos
  105.     subq.l    #2,a0        ;skip special effects
  106.     move.w    -(a0),d4    ;brush #
  107. *
  108.     cmp.w    d0,d2        ;are we entirely to left?
  109.     bgt    findreci    ;br if so
  110. *
  111.     cmp.w    d1,d3        ;are we entirely above?
  112.     bgt    findreci    ;br if yes
  113. *
  114. *  we may have found our boy--check width & height
  115. *
  116.     move.w    d4,d5
  117.     swap    d5        ;save possible curbrush in upper word
  118. *
  119.     lsl.w    #4,d4        ;get offset into bshblock
  120.     move.w    (a2,d4.w),d5    ;get width
  121.     move.w    2(a2,d4.w),d6    ; & height
  122.     add.w    d2,d5
  123.     add.w    d3,d6
  124. *
  125.     cmp.w    d0,d5
  126.     ble    findreci
  127. *
  128.     cmp.w    d1,d6
  129.     ble    findreci    ;br if outside rect
  130. *
  131. *  we're inside a rectangle--check mask for pixel level match
  132. *
  133.     move.l    4(a2,d4.w),a3    ;get graphics s_form
  134.     move.l    a3,a5
  135.     adda.w    12(a2,d4.w),a5    ;get mono mask s_form
  136.     move.l    a5,a6
  137.     move.w    14(a2,d4.w),d5    ;get bytes/line
  138.     beq    hitnail        ;br if filled rect
  139.     lsr.w    #2,d5
  140.     move.w    d0,d6
  141.     sub.w    d2,d6        ;d6 = horz offset into mask form
  142.     move.w    d1,d7
  143.     sub.w    d3,d7        ;d7 = # rows down the form
  144.     mulu    d5,d7
  145.     add.l    d7,a5
  146.     move.w    d6,d7
  147.     asr.w    #3,d7
  148.     adda.w    d7,a5
  149.     not.w    d6
  150.     andi.w    #7,d6        ;d6 = dot address    
  151.     btst.b    d6,(a5)        ;do we have a hit, or miss
  152.     beq    findreci
  153. *
  154. *
  155. *  we have hit the nail on the head
  156. *
  157. hitnail:
  158.     swap    d5
  159.     move.w    d5,curbrush
  160.     swap    d5
  161. *
  162. *   convert world co-ords to screen ones
  163. *
  164.     lea    wstruct+xoffset,a5    ;restore structure ptr
  165. *
  166.     sub.w    xoffset(a5),d2
  167.     add.w    wx(a5),d2
  168.     sub.w    yoffset(a5),d3
  169.     add.w    wy(a5),d3
  170. *
  171.     movem.w    d2-d3,bsh_x    ;select this brush
  172.     move.w    d5,bsh_monoln    ;save bytes/line in form
  173.     lea    (a2,d4.w),a2
  174.     movem.w    (a2),d5-d6    ;get width & height
  175.     movem.w    d5-d6,bsh_wid
  176. *
  177. *   Delete it from worldblk
  178. *
  179.     movem.l    a3/a5-a6,-(sp)
  180. *
  181.     move.l    a0,wblkcur    ;save in current
  182.     lea    8(a0),a3
  183.     move.l    wblkptr,a4    ;get end +1
  184.     bra    delei
  185. dele:
  186.     move.l    (a3)+,(a0)+
  187.     move.l    (a3)+,(a0)+
  188. delei:
  189.     cmp.l    a4,a3
  190.     bcs    dele
  191. *
  192.     subq.l    #8,a4
  193.     move.l    a4,wblkptr
  194.     bsr    makewld        ;rebuild the world
  195.     bsr    makemsk        ;  & the mask
  196. *
  197. *  Blit a patch of the world buffer to the screen
  198. *
  199.     bsr    brushpat
  200. *
  201.     movem.l    (sp)+,a3/a5-a6
  202.     move.l    a6,a0
  203. *
  204. *  enter here from cluster code to put up a unit
  205. *
  206. bckdoorm:
  207.     movem.w    bsh_x,d0-d4
  208.     bsr    bdisplay
  209. *
  210.     movem.l    a0/d0,-(sp)
  211.     lea    bshblock,a0
  212.     move.w    curbrush,d0
  213.     bsr    upname            ;put up the name
  214.     movem.l    (sp)+,a0/d0
  215. *
  216.     bra    lib_m            ;make her animate!
  217. *
  218. findreci:
  219.     cmp.l    a0,a1            ;any more items left
  220.     bcs    findlp            ;br if so
  221. *
  222. wor_selx:
  223.     movem.l    mousex,d0
  224.     moveq    #0,d1
  225.     movem.l    d0-d1,bsh_x
  226.     bra    but_xit            ;exit thru right button stuff
  227. *
  228. *
  229. *
  230. *  Select a stamp from the library
  231. *
  232. lib_sel:
  233.     movem.l    a0-a6/d0-d7,-(sp)
  234. *
  235.     bsr    butninit
  236. *
  237. *
  238. newstamp:
  239. *
  240.     movem.w    mousex,d0-d1        ;get xpos, ypos
  241. *
  242.     lea    bshblock,a1        ;get brush data block base
  243.     move.w    curbrush,d2        ;get desired brush #
  244.     lsl.w    #4,d2
  245. *
  246.     adda.w    d2,a1
  247.     move.w    (a1)+,d2        ;get block width
  248.     move.w    d2,bsh_wid        ;save for use by move
  249.     beq    lib_sel1        ;br if null entry
  250. *
  251. *
  252.     move.w    d2,d5            ;copy width
  253.     lsr.w    #1,d5
  254.     sub.w    d5,d0            ;adjust xpos by 1/2 width
  255. *
  256.     move.w    d0,bsh_x        ;we allow bsh_x < 0
  257. *
  258. *
  259.     move.w    (a1)+,d3        ;get block height
  260.     move.w    d3,bsh_hite        ;save for use by move
  261. *
  262.     move.w    d3,d6
  263.     lsr.w    #1,d6
  264.     sub.w    d6,d1
  265. *
  266.     move.w    d1,bsh_y
  267. *
  268.     move.l    (a1)+,a3    ;a3 -> s_form
  269.     move.l    (a1)+,a2    ;object name string
  270. *
  271. *  is this an intrinsic object?
  272. *
  273.     move.w    curbrush,d6
  274.     cmp.w    maxintrins,d6
  275.     bls    strcpyx        ;br if intrinsic
  276.     move.l    (a2),a2        ;else, derived
  277. strcpyx:
  278. *
  279.     lea    brshfile,a0    ;use this to copy brush name
  280.     move.l    a0,-(sp)
  281. strcopy:
  282.     move.b    (a2)+,d6
  283.     move.b    d6,(a0)+
  284.     cmpi.b    #" ",d6
  285.     bhi    strcopy
  286.     clr.b    -(a0)
  287. *
  288.     move.l    (sp)+,a0
  289.     movem.l    a1-a3/d0-d3,-(sp)    
  290.     move.w    #LIBRARY,d0
  291.     bsr    DaveInfo    ;put brush name on the info bar
  292.     movem.l    (sp)+,a1-a3/d0-d3
  293. *
  294.     move.w    (a1)+,d4    ;get mask_offset
  295.     lea    (a3,d4.w),a0    ;get mono mask src_form
  296. *
  297.     move.w    (a1)+,d4    ;s_nxln for 4-plane brush
  298.     lsr.w    #2,d4        ;d4 = mono scr_nxln
  299.     move.w    d4,bsh_monoln
  300. *
  301. *
  302. *    d0 = DST x
  303. *    d1 = DST y
  304. *    d2 = width
  305. *    d3 = height
  306. *    d4 = mono mask scr_nxln
  307. *
  308. *    a0 -> mono mask s_form
  309. *    a3 -> 4-plane graphics s_form
  310. *
  311. *
  312.     bsr    bdisplay    ;display brush, clipped to screen
  313. *
  314. *    This loop is entered when a right button is down--
  315. *        exit loop when button released
  316. *
  317. lib_sel1:
  318.     bsr    getmouse
  319. *
  320.     bsr    CaryKey        ;check for user ctrl-keys
  321. *
  322. *  the following code allows function keys to be programmed
  323. *   during right-mouse button brush select mode
  324. *
  325.     tst.w    d4        ;any keyboard input?
  326.     beq    lib_sel0    ;br if not
  327.  
  328.     ror.w    #8,d4
  329.     cmpi.b    #FUNC_1,d4
  330.     bcs    lib_sel0
  331.     cmpi.b    #FUNC_10+1,d4
  332.     bcc    lib_sel0x
  333. *
  334. *  we want the brush from the function key
  335. *
  336.     moveq    #0,d0
  337.     move.b    d4,d0
  338.     subi.b    #FUNC_1,d0
  339.     lsl.w    #8,d0
  340.     bsr    Func_Key
  341.     move.w    curbrush,d1
  342.     bra    lib_sel4
  343. lib_sel0x:
  344.     cmpi.b    #SH_FUNC_1,d4
  345.     bcs    lib_sel0
  346.     cmpi.b    #SH_FUNC_10+1,d4
  347.     bcc    lib_sel0
  348. *
  349.     moveq    #0,d0
  350.     move.b    d4,d0
  351.     subi.b    #SH_FUNC_1,d0
  352.     lsl.w    #8,d0
  353.     bsr    Shift_Func_Key
  354. *
  355. lib_sel0:
  356.     move.l    mouseptr,a1
  357.     movem.w    (a1),d0-d1
  358.     and    #1,d3
  359.     bne    lib_sel1x
  360.     tst.w    bsh_wid        ;if null brush is selected, exit
  361.     beq    lib_xit
  362.     bra    lib_move    ;else, move this guy
  363. lib_sel1x:
  364.     sub.w    relcentx,d0    ;how far did mouse travel x-wise?
  365.     move.w    d0,d3
  366.     bpl    lib_sel2
  367.     neg.w    d3
  368. lib_sel2:
  369.     cmpi.w    #4,d3
  370.     bcs    lib_sel1
  371.     move.l    relcentx,(a1)    ;restore fake mouse to center position
  372. *
  373. *  We assume there exists at least one good brush..
  374. *
  375. nxt_bsh:
  376.     move.w    curbrush,d1
  377.     tst.w    d0        ;check sign
  378.     bmi    lib_sel3
  379.     addq.w    #1,d1
  380.     cmp.w    maxderivd,d1
  381. *
  382.     bls    lib_sel4
  383.     moveq    #0,d1
  384.     bra    lib_sel4    
  385. lib_sel3:
  386.     subq.w    #1,d1
  387.     bpl    lib_sel4
  388.     move.w    maxderivd,d1
  389. lib_sel4:
  390.     move.w    d1,curbrush
  391. *
  392.     lea    bshblock,a1
  393.     lsl.w    #4,d1
  394.     tst.w    (a1,d1.w)    ;are we a real brush?
  395.     beq    nxt_bsh        ;loop until we get a real one
  396. *
  397. *  the following screens out H & V flipped cache images
  398. *
  399.     move.l    8(a1,d1.w),a1    ;get ptr to derived entry
  400.     lsr.w    #4,d1
  401.     cmp.w    maxintrins,d1    ;are we intrinsic?
  402.     bls    lib_sel5    ;br if so--we'll take it
  403.     tst.w    4(a1)        ;are we a primary cluster?
  404.     bne    lib_sel5    ;br if so
  405.     move.w    8(a1),d1    ;get effects
  406.     andi.w    #Hflip+Vflip,d1    ;any flips?
  407.     bne    nxt_bsh        ;if so, skip display
  408. lib_sel5:
  409. *
  410.     bsr    pastund
  411.     bra    newstamp
  412. *
  413. lib_move:
  414.     move.l    relcentx,(a1)
  415. *
  416. lib_m:
  417.     clr.w    forceupd
  418.  
  419.     bsr    fat
  420. *
  421.     bsr    getmouse
  422. *
  423.     bsr    CaryKey
  424. *
  425.     bsr    ctrlkey        ;process cntrl keys
  426. *
  427.     tst.w    d4        ;any keyboard input?
  428.     beq    lib_m0
  429.     bsr    checkpri    ;check keyboard for re-prioritization
  430. lib_m0:
  431.     and.w    #1,d3        ;check for no buttons down
  432.     beq    lib_mx
  433. *
  434.     bclr.b    #1,BUT_STATE+1
  435.     bne    lib_xita    ;exit if right button down
  436. *
  437.     bclr.b    #0,BUT_STATE+1    ;check for left down
  438.     beq    lib_mx        ;br if left not down
  439. *
  440. *   A brush is stamped into the world..
  441. *
  442.     bsr    pastund        ;erase display brush
  443.     movem.w    xmin_clp,d4-d7    ;get window clipping rectangle
  444.     movem.w    d4-d7,-(sp)    ;save
  445. *
  446.     lea    wstruct+xoffset,a5
  447.     move.w    d4,d0
  448.     sub.w    xoffset(a5),d0
  449.     add.w    w_wid(a5),d0    ;comput world clip rectangle
  450.     cmp.w    d0,d6        ;take the smaller of world/window
  451.     ble    xclpok
  452.     move.w    d0,d6
  453. xclpok:
  454.     move.w    d5,d0
  455.     sub.w    yoffset(a5),d0
  456.     add.w    w_hite(a5),d0
  457.     cmp    d0,d7
  458.     ble    yclpok
  459.     move.w    d0,d7
  460. yclpok:
  461.     movem.w    d4-d7,xmin_clp    ;save new clip rect
  462. *
  463.     movem.w    bsh_x,d0-d4
  464.  
  465.     cmp.w    d6,d0        ;are we totally right of clip?
  466.     bge    skipstmp
  467. *
  468.     cmp.w    d7,d1
  469.     bge    skipstmp
  470. *
  471.     bsr    bdisplay    ;put up a world-clipped brush
  472. *
  473. *  now blit to world buffer as well
  474. *
  475.     movem.l    a0/a3/a5,-(sp)    ;save s_forms ptrs
  476.     movem.w    bsh_x,d0-d4    ;get screen brush position
  477. *
  478. *  put entry into world object list
  479. *
  480.     move.l    wblkptr,a0    ;open up a hole in world object list
  481.     lea    8(a0),a3    ;open up a hole in world object list
  482.     move.l    a3,wblkptr
  483.     move.l    wblkcur,a2
  484.     bra    holelpi
  485. holelp:
  486.     move.l    -(a0),-(a3)
  487.     move.l    -(a0),-(a3)
  488. holelpi:
  489.     cmp.l    a0,a2
  490.     bcs    holelp
  491. *
  492.     move.w    curbrush,(a2)+    ;save brush #
  493.     clr.w    (a2)+        ;special effect (not used yet)
  494. *
  495.     sub.w    wx(a5),d0
  496.     add.w    xoffset(a5),d0    ;d0 = world relative x_min
  497.     move.w    d0,(a2)+    ;
  498. *    
  499.     sub.w    wy(a5),d1
  500.     add.w    yoffset(a5),d1    ;d1 = world relative y_min
  501.     move.w    d1,(a2)+    ;
  502.     move.l    a2,wblkcur    ;adjust priority ptr
  503. *    
  504.     lea    grafbsh,a3
  505.     lea    grafmsk,a0
  506.     bsr    wldblit        ;blit to world buffer too
  507.     movem.l    (sp)+,a0/a3/a5    ;restore old brush s_forms    
  508.  
  509. *
  510. skipstmp:
  511.     lea    bitblock,a6
  512.     bsr    copyund
  513. *
  514. *
  515.     movem.w    (sp)+,d0-d3
  516.     movem.w    d0-d3,xmin_clp    ;put back world clip
  517. *  fake a move
  518. *    movem.w    bsh_x,d2-d3
  519. *    addq.w    #1,d2
  520. *    move.w    #$7f,d0
  521. *    move.w    #$80,d1
  522.     moveq    #1,d4
  523.     bra    lib_cheat
  524. *
  525. *
  526. lib_mx:
  527.     move.w    grid,d4
  528. lib_cheat:
  529.     movem.w    bsh_x,d2-d3    ;pick up current positions
  530.     move.l    mouseptr,a1
  531.     movem.w    (a1),d0-d1
  532.     move.l    relcentx,(a1)
  533. *
  534.     sub.w    relcentx,d0    ;check x move
  535.     beq    lib_mov1    ;br if no x move
  536.     moveq    #-1,d4        ;indicate a move
  537.     add.w    d2,d0        ;get proposed new x position
  538.     cmp.w    Mclpxmx,d0    ;does it go beyond our clip?
  539.     blt    clp_mov1    ;br if ok on right
  540.     move.w    Mclpxmx,d0
  541.     subq.w    #1,d0        ;anchor at right maximum
  542. clp_mov1:
  543.     move.w    d0,d5
  544.     add.w    bsh_wid,d5
  545.     subq.w    #1,d5
  546.     cmp.w    Mclpxmn,d5
  547.     bge    clp_mov2
  548.     move.w    Mclpxmn,d0
  549.     sub.w    bsh_wid,d0
  550.     addq.w    #1,d0
  551. clp_mov2:
  552.     move.w    d0,d2
  553. *
  554. *  Check on vert movement
  555. *
  556. lib_mov1:
  557.     sub.w    relcenty,d1    ;check y move
  558.     beq    lib_mov2    ;br if no y move
  559.     moveq    #-1,d4        ;indicate a move
  560.     add.w    d3,d1        ;get proposed new y position
  561.     cmp.w    Mclpymx,d1    ;does it go beyond our clip?
  562.     blt    clp_mov3    ;br if ok on bottom
  563.     move.w    Mclpymx,d1
  564.     subq.w    #1,d1        ;anchor at bottom maximum
  565. clp_mov3:
  566.     move.w    d1,d5
  567.     add.w    bsh_hite,d5
  568.     subq.w    #1,d5
  569.     cmp.w    Mclpymn,d5
  570.     bge    clp_mov4
  571.     move.w    Mclpymn,d1
  572.     sub.w    bsh_hite,d1
  573.     addq.w    #1,d1
  574. clp_mov4:
  575.     move.w    d1,d3
  576. lib_mov2:
  577.     movem.w    bsh_x,d0-d1    ;check old position
  578.  
  579.     cmpi.w    #1,d4
  580.     beq    do_mov        ;br if this a grid init
  581. *
  582.     tst.w    forceupd    ;is this a forced update?
  583.     bne    lib_mov5    ;br if so
  584. *    
  585.     tst.w    d4
  586.     beq    lib_m        ;br if no move
  587. *
  588. *
  589.     cmp.w    d2,d0
  590.     bne    do_movx
  591.     cmp.w    d3,d1
  592.     beq    lib_m        ;br if new position same as old
  593. lib_mov5:
  594. *
  595. *   Here's some constrain stuff
  596. *
  597. do_movx:
  598.     move.w    constrain,d6    ;check contrain status
  599.     beq    do_mov        ;0=none,1=horz,2=vert,-1=init
  600.     cmpi.w    #-1,d6        ;is it init?
  601.     bne    cstrain4    ;br if not
  602.     move.w    d0,d4
  603.     sub.w    d2,d4
  604.     bpl    cstrain1
  605.     neg.w    d4
  606. cstrain1:
  607.     move.w    d1,d5
  608.     sub.w    d3,d5
  609.     bpl    cstrain2
  610.     neg.w    d5
  611. cstrain2:
  612.     moveq    #1,d6
  613.     cmp.w    d4,d5
  614.     beq    lib_m        ;no move if both the same
  615.     bls    cstrain3
  616.     moveq    #2,d6
  617. cstrain3:
  618.     move.w    d6,constrain
  619. cstrain4:
  620.     cmp.w    #1,d6        ;horz constrain?
  621.     bne    cstrain5
  622.     move.w    d1,d3
  623.     bra    do_mov
  624. cstrain5:
  625.     move.w    d0,d2
  626. *
  627. *    
  628. do_mov:
  629. *
  630. *   check grid
  631. *
  632.     move.w    grid,d4
  633.     beq    nogrid        ;skip if grid isn't on
  634. *
  635.     bmi    do_grid        ;br if grid-continue
  636. *
  637. *  grid init
  638. *
  639.     movem.w    d2-d3,bsh_x
  640. *
  641.     move.w    #-1,grid
  642. *
  643.     movem.w    bsh_x,d0-d1    ;get current brush position
  644. *
  645.     lea    wstruct+xoffset,a5
  646.     sub.w    wx(a5),d0
  647.     add.w    xoffset(a5),d0    ;d0= world xpos
  648. *
  649.     sub    wy(a5),d1
  650.     add.w    yoffset(a5),d1
  651. *
  652. *  We're in world co-ords now
  653. *  enforce grid position NOW!
  654. *
  655.     movem.w    d0-d1,-(sp)
  656.     movem.w    Grid,d2-d5    ;get grid co-ords
  657. *
  658.     tst.w    d4        ;convert 0's to 1's
  659.     bne    grid0
  660.     moveq    #1,d4
  661. grid0:
  662.     tst.w    d5
  663.     bne    grid1
  664.     moveq    #1,d5
  665. grid1:
  666.     sub.w    d2,d0
  667.     sub.w    d3,d1
  668.     ext.l    d0
  669.     ext.l    d1
  670.     divs    d4,d0
  671.     divs    d5,d1
  672.     swap    d0    ;get signed remainder for x (dividend has same sign) 
  673.     tst.w    d0
  674.     bpl    grid2
  675.     add.w    d4,d0    ;make positive
  676. grid2:
  677.     swap    d1        ; & for y
  678.     tst.w    d1
  679.     bpl    grid3
  680.     add.w    d5,d1
  681. grid3:
  682.     movem.w    (sp)+,d2-d3    ;get original world x & y
  683. *
  684.     move.w    d4,d6
  685.     lsl.w    #1,d0        ;x remainder *2
  686.     cmp.w    d0,d4        ;less than 1/2 way to next grid point?
  687.     bhi    grid4        ;br if so
  688. *
  689. *  more than 1/2 way--compute amount to add
  690. *
  691.     lsr.w    #1,d0
  692.     sub.w    d0,d6
  693.     add.w    d6,d2
  694.     neg.w    d6        ;d6 = offset
  695.     bra    grid5
  696. *
  697. *  less than 1/2 way--use d0 to subtract
  698. *
  699. grid4:    
  700.     lsr.w    #1,d0
  701.     sub.w    d0,d2
  702.     move.w    d0,d6
  703. grid5:
  704.     move.w    d6,xgridoff
  705. *
  706. *
  707.     move.w    d5,d7
  708.     lsl.w    #1,d1        ;y remainder *2
  709.     cmp.w    d1,d5        ;less than 1/2 way to next grid point?
  710.     bhi    grid6        ;br if so
  711. *
  712. *  more than 1/2 way--compute amount to add
  713. *
  714.     lsr.w    #1,d1
  715.     sub.w    d1,d7
  716.     add.w    d7,d3
  717.     neg.w    d7        ;d7 = offset
  718.     bra    grid7
  719. *
  720. *  less than 1/2 way--use d1 to subtract
  721. *
  722. grid6:    
  723.     lsr.w    #1,d1
  724.     sub.w    d1,d3
  725.     move.w    d1,d7
  726. grid7:
  727.     move.w    d7,ygridoff
  728. *
  729. *  Restore to screen co-ords..
  730. *
  731.     add.w    wx(a5),d2
  732.     sub.w    xoffset(a5),d2
  733.     add.w    wy(a5),d3
  734.     sub.w    yoffset(a5),d3
  735. *
  736. *  Make sure new position is on window..
  737. *
  738.     moveq    #0,d7
  739.     movem.w    bsh_wid,d0-d1
  740.     add.w    d2,d0        ;get brush right edge
  741.     move.w    wx(a5),d6
  742.     cmp.w    d0,d6        ;is new brush position too far left?
  743.     blt    ritechk        ;br if not
  744.     add.w    d4,d2        ;else, just position one notch to right
  745.     addq.w    #1,d7
  746. ritechk:
  747.     add.w    wwidth(a5),d6    ;get window xmax (+1)
  748. *
  749.     subq.w    #1,d6
  750.     cmp.w    form_width,d6    ;window exceeds screen?
  751.     ble    notxscre
  752.     move.w    form_width,d6
  753. notxscre:
  754.     addq.w    #1,d6
  755. *
  756.     cmp.w    d2,d6
  757.     bgt    topchk
  758.     sub.w    d4,d2
  759.     addq.w    #1,d7
  760. topchk:
  761.     cmpi.w    #2,d7
  762.     beq    cantwind    ;br if can't find any anchor point on window
  763. *
  764.     moveq    #0,d6
  765.     add.w    d3,d1        ;get brush bottom edge
  766.     move.w    wy(a5),d7
  767.     cmp.w    d1,d7
  768.     blt    botchk
  769.     add.w    d5,d3
  770.     addq.w    #1,d6
  771. botchk:
  772.     add.w    wheight(a5),d7    ;get window ymax +1
  773. *
  774.     subq.w    #1,d7
  775.     cmp.w    form_height,d7    ;window exceeds screen?
  776.     ble    notyscre
  777.     move.w    form_height,d7
  778. notyscre:
  779.     addq.w    #1,d7
  780. *
  781.     cmp.w    d3,d7
  782.     bgt    owind
  783.     sub.w    d5,d3
  784.     add.w    #1,d6
  785. owind:
  786.     cmpi.w    #2,d6
  787.     bne    goodwin
  788. cantwind:
  789.     movem.w    bsh_x,d2-d3    ;just got to use the old values
  790. *
  791. goodwin:
  792.     movem.w    d2-d3,bsh_x
  793. *
  794. offworld:
  795.     bra    nogrid        ;skip this grid thang if just entered
  796. *
  797. *  we're griddin'
  798. *
  799. do_grid:
  800.     moveq    #0,d7        ;indicate no move
  801. *
  802. *    movem.w    gridw,d4-d5    ;get grid width & height
  803.     movem.w    Grid+4,d4-d5
  804. *
  805.     tst.w    d4
  806.     bne    grdx
  807.     moveq    #1,d4
  808. grdx:
  809.     tst.w    d5
  810.     bne    grdy
  811.     moveq    #1,d5
  812. grdy:
  813.     sub.w    d2,d0
  814.     sub.w    d3,d1
  815. *
  816.     neg.w    d0
  817.     neg.w    d1
  818. *
  819.     sub.w    d0,d2        ;undo the move for now
  820. *
  821.     add.w    xgridoff,d0    ;add xaccum to delta
  822.     move.w    d0,d6
  823.     bpl    grd0
  824.     neg.w    d6
  825.     add.w    d6,d6
  826.     cmp.w    d4,d6        ;more than 1/2 way to the goal line?
  827.     bcs    grd1        ;br if no grid jump yet
  828. grd0a:
  829.     sub.w    d4,d2        ;adjust xpos
  830.     add.w    d4,d0        ;adjust new xgridoff till it goes positive
  831.     bmi    grd0a
  832. *
  833.     bra    grd1a
  834. grd0:
  835.     add.w    d6,d6
  836.     cmp.w    d4,d6
  837.     bcs    grd1        ;br if no grid jump yet
  838. grd0b:
  839.     add.w    d4,d2        ;adjust xpos
  840.     sub.w    d4,d0
  841.     bpl    grd0b        ;adjust new xgridoff till it goes negative
  842. grd1a:
  843.     moveq    #-1,d7
  844. grd1:
  845.     move.w    d0,xgridoff
  846. *
  847. *  Now do y
  848. *
  849.     sub.w    d1,d3        ;undo the move for now
  850.     add.w    ygridoff,d1    ;add yaccum to delta
  851.     move.w    d1,d6
  852.     bpl    grd2
  853.     neg.w    d6
  854.     add.w    d6,d6
  855.     cmp.w    d5,d6        ;more than 1/2 way to the goal line?
  856.     bcs    grd3        ;br if no grid jump yet
  857. grd2a:
  858.     sub.w    d5,d3        ;adjust ypos
  859.     add.w    d5,d1        ;adjust new ygridoff till it goes positive
  860.     bmi    grd2a
  861.     bra    grd3a
  862. grd2:
  863.     add.w    d6,d6
  864.     cmp.w    d5,d6
  865.     bcs    grd3        ;br if no grid jump yet
  866. grd2b:
  867.     add.w    d5,d3        ;adjust ypos
  868.     sub.w    d5,d1
  869.     bpl    grd2b    
  870. grd3a:
  871.     moveq    #-1,d7
  872. grd3:
  873.     move.w    d1,ygridoff
  874.     tst.w    forceupd    ;check for forced update
  875.     bne    grd4
  876.     tst.w    d7
  877.     beq    lib_m        ;don't flash if we haven't grid-moved
  878. grd4:
  879. *
  880. *  Check for outside window (we don't permit outside window)
  881. *
  882.     bsr    offwind
  883.     beq    nogrid        ;br if on window
  884. *
  885.     movem.w    bsh_x,d2-d3    ;else, just use previous
  886. *
  887. *  End of grid maddness
  888. *
  889. nogrid:
  890.     movem.w    d2-d3,bsh_x
  891. *
  892.     sub.w    wx(a5),d2
  893.     add.w    xoffset(a5),d2
  894.     move.w    d2,d0
  895. *
  896.     lea    infox,a1
  897.     bsr    decitpad
  898. *
  899.     move.w    bsh_y,d0
  900.     sub.w    wy(a5),d0
  901.     add.w    yoffset(a5),d0
  902. *
  903.     lea    infoy,a1
  904.     bsr    decitpad
  905. *
  906.  
  907.     move.l    a0,-(sp)
  908.     move.w    #WORLD,d0
  909.     lea    infostrng,a0
  910.     bsr    DaveInfo
  911.     move.l    (sp)+,a0
  912. *
  913.     bsr    pastund
  914. *
  915. *
  916.     movem.w    bsh_x,d0-d4
  917.     bsr    bdisplay
  918. *
  919. *
  920.     bra    lib_m
  921. *
  922. *
  923. lib_xita:
  924.     bsr    wtritup
  925. *
  926. lib_xit:
  927.     bsr    pastund
  928. *
  929. *
  930. but_xit:
  931.     bsr    bsh2curs
  932. but_xit0:
  933.     move.w    #MouseOn,d0
  934.     bsr    Graf_Mouse
  935. *
  936.     bsr    Back2G        ;check for curbrush = cluster
  937. *
  938.     lea    world_ID,a0
  939.     move.w    #WORLD,d0
  940.     bsr    DaveName    ;put world name back on title bar
  941. *
  942.     bsr    fatquit
  943.     bsr    wtritup
  944. *
  945. *    lea    Mrets,a0
  946. *    bsr    Graf_mkstate    ;clean up AES
  947. *
  948.     movem.l    (sp)+,a0-a6/d0-d7
  949.  
  950.     rts
  951. *
  952. *  Put system cursor at about the center of the brush
  953. *
  954. bsh2curs:
  955.     movem.l    a1/d0-d3,-(sp)
  956.     move.l    mouseptr,a1
  957.     movem.w    bsh_x,d0-d3
  958.     lsr.w    #1,d2
  959.     lsr.w    #1,d3
  960.     add.w    d2,d0
  961.     add.w    d3,d1
  962. *
  963. *  clip new x,y mouse position to the screen
  964. *
  965.     tst.w    d0
  966.     bpl    mxok
  967.     moveq    #0,d0
  968. mxok:
  969.     cmp.w    form_width,d0
  970.     bcs    mxok1
  971.     move.w    form_width,d0
  972. mxok1:
  973.     tst.w    d1
  974.     bpl    myok
  975.     moveq    #0,d1
  976. myok:
  977.     cmp.w    form_height,d1
  978.     bcs    myok1
  979.     move.w    form_height,d1
  980. myok1:
  981. *
  982.     movem.w    d0-d1,(a1)
  983.     movem.l    (sp)+,a1/d0-d3
  984.     rts
  985. *
  986. *
  987. *   Wait for right button to come up
  988. *
  989. wtritup:
  990.     bsr    getmouse
  991.     and.w    #1,d3
  992.     bne    wtritup
  993. *
  994.     bclr.b    #1,BUT_STATE+1
  995.     bne    wtritup
  996.     bclr.b    #0,BUT_STATE+1
  997.     bne    wtritup
  998.     rts
  999. *
  1000. *
  1001. *   Let Cary call this to display xoffset/yoffset
  1002. *
  1003. DisplayXY:
  1004.     movem.l    a0-a6/d0-d7,-(sp)
  1005.     move.w    wstruct+xoffset,d0
  1006.     lea    infox,a1
  1007.     bsr    decitpad
  1008. *
  1009.     move.w    wstruct+yoffset,d0
  1010.     lea    infoy,a1
  1011.     bsr    decitpad
  1012. *
  1013.     move.w    #WORLD,d0
  1014.     lea    infostrng,a0
  1015.     bsr    DaveInfo
  1016.     movem.l    (sp)+,a0-a6/d0-d7
  1017.     rts
  1018. *
  1019. *
  1020. *  Check for outside window (we don't permit outside window)
  1021. *
  1022. *  assume d2-d3 is bsh_x, bsh_y
  1023. *  a5 -> wstruct
  1024. *
  1025. offwind:
  1026.     movem.w    bsh_wid,d0-d1
  1027.     add.w    d2,d0        ;get brush right edge +1
  1028.     move.w    wx(a5),d6    ;get window x-minimum
  1029.     cmp.w    d0,d6
  1030.     bge    offwx
  1031. *
  1032.     add.w    wwidth(a5),d6    ;get window x-max +1
  1033. *
  1034.     subq.w    #1,d6
  1035.     cmp.w    form_width,d6    ;window exceeds screen?
  1036.     ble    nxscre
  1037.     move.w    form_width,d6
  1038. nxscre:
  1039.     addq.w    #1,d6
  1040. *
  1041.     cmp.w    d2,d6
  1042.     ble    offwx
  1043. *
  1044.     add.w    d3,d1        ;get brush bot edge +1
  1045.     move.w    wy(a5),d7
  1046.     cmp.w    d1,d7
  1047.     bge    offwx
  1048. *
  1049.     add.w    wheight(a5),d7
  1050.  
  1051.     subq.w    #1,d7
  1052.     cmp.w    form_height,d7    ;window exceeds screen?
  1053.     ble    nyscre
  1054.     move.w    form_height,d7
  1055. nyscre:
  1056.     addq.w    #1,d7
  1057. *
  1058.     cmp.w    d3,d7
  1059.     bgt    onwind
  1060. offwx:
  1061.     moveq    #-1,d0        ;indicate off window
  1062.     rts
  1063. onwind:
  1064.     moveq    #0,d0        ;indicate on window
  1065.     rts
  1066. *
  1067. *
  1068. ********************************************************
  1069. *
  1070. *   This comes from Cary when a key is hit
  1071. *
  1072. *    d0 = shift keys
  1073. *    d1 = scan code + ASCII code of a key
  1074. *    d2 = topped window (-1 if not one of ours)
  1075. *
  1076. DaveKey:
  1077.     cmpi.w    #WORLD,d2    ;is world window topped?
  1078.     bne    Dky1        ;br if not topped        
  1079.     cmpi.b    #"a",d1        ;force upper case
  1080.     bcs    Dky0
  1081.     subi.b    #$20,d1        
  1082. Dky0:
  1083.     cmpi.b    #"C",d1        ;enter "cluster" mode?
  1084.     beq    docluster    ;br if so
  1085. *
  1086.     cmpi.b    #"B",d1        ;enter "bridge" mode?
  1087.     beq    dobridge
  1088. *
  1089.     cmpi.b    #"R",d1        ;enter filled Rectangle mode?
  1090.     beq    dorect
  1091. Dky1:
  1092.     rts            ;exit to ignore any other key
  1093. *
  1094. *
  1095. *
  1096. docluster:
  1097.     movem.l    a0-a6/d0-d7,-(sp)
  1098.     move.w    #$8001,aggreg    ;indicate a cluster aggregate
  1099.     bra    aggregate
  1100. *
  1101. *
  1102. dobridge:
  1103.     movem.l    a0-a6/d0-d7,-(sp)
  1104.     move.w    #1,aggreg    ;indicate bridge aggregate
  1105. *
  1106. *  Enter CLUSTER/BRIDGE select mode
  1107. *
  1108. aggregate:
  1109.     moveq    #outlnx,d0
  1110.     bsr    Graf_Mouse
  1111. *
  1112.     clr.w    butt        ;init button edge shadow
  1113. *
  1114.     lea    tempbuf,a3    ;start cluster list here
  1115.  
  1116.     move.w    #$7fff,d0    ;largest 16-bit signed
  1117.     move.w    d0,d1
  1118.     move.w    #$8000,d2    ;smallest 16-bit signed
  1119.     move.w    d2,d3
  1120.     movem.w    d0-d3,xmin_clust    ;init min/max stuff
  1121. *
  1122. aggrcnt:
  1123.     lea    bridg_msg,a0
  1124.     move.w    aggreg,d0
  1125.     cmpi.w    #4,d0        ;reached end of a bridge?
  1126.     beq    brid_xit    ;br if so
  1127. *
  1128.     bclr.l    #15,d0
  1129.     beq    aggr0
  1130.     lea    clust_msg,a0
  1131. aggr0:
  1132.     lea    17(a0),a1
  1133.     bsr    decitpad
  1134. *
  1135.     move.w    #WORLD,d0
  1136.     move.l    a3,-(sp)    ;save the cluster list ptr
  1137.     bsr    DaveInfo    ;tell 'em our mode
  1138.     move.l    (sp)+,a3
  1139. *
  1140. aggrlp:
  1141.     bsr    getmouse    ;let GEM have control for a while
  1142.     andi.w    #1,d3        ;any mouse buttons?
  1143.     beq    aggr3        ;br if none
  1144. *
  1145.     move.w    BUT_STATE,d6    ;get left & right
  1146.     clr.w    BUT_STATE    
  1147.     move.w    butt,d5
  1148.     move.w    d3,butt
  1149.     eor.w    d3,d5
  1150.     bne    aggrbut        ;br if positive edge on button
  1151. aggr3:
  1152.     move.w    d3,butt
  1153. *
  1154.     tst.w    d4        ;any keyboard?
  1155.     beq    aggrlp        ;br if not
  1156. *
  1157. *  we got a key
  1158. *
  1159.     tst.b    d4        ;ASCII code?
  1160.     beq    aggrlp        ;br if not
  1161. *
  1162.     cmpi.b    #"a",d4
  1163.     bcs    aggr1
  1164.     subi.b    #$20,d4        ;force upper case
  1165. aggr1:
  1166.     cmpi.b    #esc,d4        ;are we escape?
  1167.     beq    ag_abort    ;br if so
  1168. *
  1169.     bra    aggrlp        ;go for more user input
  1170. *
  1171. *  Button was pressed--find sprite selected
  1172. *
  1173. aggrbut:
  1174.     btst.l    #1,d6        ;check for right button
  1175.     bne    aggr_xit    ;exit if right button
  1176. *
  1177.     lea    wstruct,a5
  1178.     move.l    mouseptr,a0
  1179.     movem.w    (a0),d0-d1    ;get mouse screen cursor x/y
  1180. *
  1181. *   Gotta be on the world window
  1182. *
  1183.     movem.w    wx(a5),d2-d3
  1184.     cmp.w    d2,d0    ;
  1185.     blt    aggrlp        ;exit if off window
  1186.     cmp.w    d3,d1
  1187.     blt    aggrlp
  1188. *
  1189.     add.w    wwidth(a5),d2
  1190.     cmp.w    d2,d0
  1191.     bge    aggrlp
  1192. *
  1193.     add.w    wheight(a5),d3
  1194.     cmp.w    d3,d1
  1195.     bge    aggrlp
  1196. *
  1197. *  mouse is on the world window work area
  1198. *
  1199.     sub.w    wx(a5),d0
  1200.     add.w    xoffset(a5),d0    ;adjust for world co-ords
  1201.     sub.w    wy(a5),d1
  1202.     add.w    yoffset(a5),d1
  1203. *
  1204. *  Search the worldblk for the highest priority object
  1205. *   whose rectangle falls within the mouse position
  1206. *
  1207.     cmp.w    w_wid(a5),d0    ;are we right of the world
  1208.     bge    aggrlp        ;br if so
  1209.     cmp.w    w_hite(a5),d1
  1210.     bge    aggrlp        ;br if below world
  1211. *
  1212.     move.l    wblkptr,a0        ;get pointer to end +1
  1213.     move.l    #worldblk,a1        ; & ptr to beginning
  1214.     lea    bshblock,a2
  1215.     bra    aggrreci
  1216. aggreclp:
  1217.     move.w    -(a0),d3    ;get vpos
  1218.     move.w    -(a0),d2    ;hpos
  1219.     subq.l    #2,a0        ;skip special effects
  1220.     move.w    -(a0),d4    ;brush #
  1221. *
  1222.     cmp.w    d0,d2        ;are we entirely to left?
  1223.     bgt    aggrreci    ;br if so
  1224. *
  1225.     cmp.w    d1,d3        ;are we entirely above?
  1226.     bgt    aggrreci    ;br if yes
  1227. *
  1228. *  we may have found our boy--check width & height
  1229. *
  1230.     move.w    d4,d5
  1231.     swap    d5        ;save possible curbrush in upper word
  1232. *
  1233.     lsl.w    #4,d4        ;get offset into bshblock
  1234.     move.w    (a2,d4.w),d5    ;get width
  1235.     move.w    2(a2,d4.w),d6    ; & height
  1236.     add.w    d2,d5
  1237.     add.w    d3,d6
  1238. *
  1239.     cmp.w    d0,d5
  1240.     ble    aggrreci
  1241. *
  1242.     cmp.w    d1,d6
  1243.     ble    aggrreci    ;br if outside rect
  1244. *
  1245.     move.w    d5,a4
  1246.     move.w    d6,a6        ;save in case we need
  1247. *
  1248. *  we're inside a rectangle--check mask for pixel level match
  1249. *
  1250.     move.l    4(a2,d4.w),a5    ;get graphics s_form
  1251.     adda.w    12(a2,d4.w),a5    ;get mono mask s_form
  1252.     move.w    14(a2,d4.w),d5    ;get bytes/line
  1253.     lsr.w    #2,d5
  1254.     move.w    d0,d6
  1255.     sub.w    d2,d6        ;d6 = horz offset into mask form
  1256.     move.w    d1,d7
  1257.     sub.w    d3,d7        ;d7 = # rows down the form
  1258.     mulu    d5,d7
  1259.     add.l    d7,a5
  1260.     move.w    d6,d7
  1261.     asr.w    #3,d7
  1262.     adda.w    d7,a5
  1263.     not.w    d6
  1264.     andi.w    #7,d6        ;d6 = dot address    
  1265.     btst.b    d6,(a5)        ;do we have a hit, or miss
  1266.     beq    aggrreci
  1267. *
  1268. *  we have hit the nail on the head
  1269. *
  1270.     swap    d5
  1271.     move.w    d5,d0        ;brush # to d0
  1272. *
  1273.     move.w    a4,d5
  1274.     move.w    a6,d6
  1275. *
  1276. *  d2 - xmin
  1277. *  d3 - ymin
  1278. *  d5 - xmax +1
  1279. *  d6 - ymax +1
  1280. *
  1281. *  accumulate cluster-wide min/max info
  1282. *
  1283.     cmp.w    xmin_clust,d2
  1284.     bge    aggr5
  1285.     move.w    d2,xmin_clust
  1286. aggr5:
  1287.     cmp.w    ymin_clust,d3
  1288.     bge    aggr6
  1289.     move.w    d3,ymin_clust
  1290. aggr6:
  1291.     cmp.w    xmax_clust,d5
  1292.     ble    aggr7
  1293.     move.w    d5,xmax_clust
  1294. aggr7:
  1295.     cmp.w    ymax_clust,d6
  1296.     ble    aggr8
  1297.     move.w    d6,ymax_clust
  1298. aggr8:
  1299. *
  1300. *  we got one--see if we got it already
  1301. *
  1302.     movem.l    a1/a3,-(sp)    ;keep our place on list
  1303.     cmp.l    #tempbuf+100,a3    ;have we gone beyond capacity here?
  1304.     bcc    xistskip
  1305. *
  1306.     lea    tempbuf,a1
  1307.     bra    xistchki
  1308. xistchk:
  1309.     cmp.l    -(a3),a0
  1310.     bne    xistchki
  1311. *
  1312. *  we've already selected this item--skip it this time
  1313. *
  1314. xistskip:
  1315.     movem.l    (sp)+,a1/a3
  1316.     bra    aggrcnt    
  1317. xistchki:
  1318.     cmp.l    a3,a1        ;reached beginning?
  1319.     bcs    xistchk        ;br if not
  1320. *
  1321. *  else, our new one hasn't been picked already..
  1322. *    
  1323.     movem.l    (sp)+,a1/a3    ;end exist check
  1324.     
  1325.     move.l    a0,(a3)+    ;save cluster ptr
  1326. *
  1327.     move.l    a3,-(sp)
  1328.     lea    bshblock,a0
  1329.     bsr    upname        ;put up the name
  1330.     move.l    (sp)+,a3
  1331. *
  1332.     addq.w    #1,aggreg
  1333. *
  1334.     bra    aggrcnt        ;count up next one
  1335. *    
  1336. aggrreci:
  1337.     cmp.l    a0,a1
  1338.     bcs    aggreclp    ;look for next item in world
  1339. *
  1340. *  no more items, air-ball click here..
  1341. *
  1342.     bra    aggrlp        ;get next user input
  1343. *
  1344. *  We finished a bridge (always 3 elements)..
  1345. *
  1346. brid_xit:
  1347. *
  1348. *  see if horz or vert bridge..
  1349. *
  1350.     lea    tempbuf,a0
  1351.     lea    bshblock,a5
  1352. *
  1353. *  see if any of the three are aggregates..
  1354. *
  1355.     moveq    #2,d1        ;check all three
  1356.     moveq    #0,d2        ;count of aggregates found
  1357. aggr3lp:
  1358.     move.l    (a0)+,a1    ;get next item
  1359. aggr3lp0:
  1360.     move.w    (a1)+,d0    ;check derived
  1361.     cmp.w    maxintrins,d0    ;are we intrinsic or derived?
  1362.     bls    aggrno        ;br if intrinsic
  1363. *
  1364.     lsl.w    #4,d0
  1365.     move.l    8(a5,d0.w),a1    ;look at derived info block
  1366.     addq.l    #4,a1        ;skip over string ptr
  1367.     tst.w    (a1)+        ;multiple elements here?
  1368.     beq    aggr3lp0    ;br if not--recheck for intrinsic
  1369.     move.l    -(a0),d3    ;put root of this aggregate in d3
  1370.     addq.l    #4,a0
  1371.     addq.w    #1,d2        ;inc the agg count
  1372. aggrno:
  1373.     dbra    d1,aggr3lp    ;search rest of 'em
  1374. *
  1375.     lea    tempbuf,a0
  1376.     movem.l    (a0),a1-a3    ;a1, a2, a3 -> three element entries
  1377.     lea    brshfile,a4
  1378. *
  1379. *
  1380. *******temp test
  1381. *    bra    aggrnox        ;just jump into normal aggregate
  1382. *    tst.w    d2
  1383. *    bne    ag_abort    ;abort if ANY aggregates
  1384. *** end test
  1385. *
  1386. *
  1387.     cmpi.w    #1,d2
  1388.     bhi    ag_abort    ;abort if more than 1 aggregate
  1389.     tst.w    d2
  1390.     beq    aggrnox        ;do normal if no aggregates
  1391. *
  1392. *  we have 1 aggregate--look at other two for orientation..
  1393. *
  1394.     cmp.l    d3,a1
  1395.     bne    aggrchk
  1396.     exg    a3,a1
  1397.     bra    aggrx1
  1398. aggrchk:
  1399.     cmp.l    d3,a2
  1400.     bne    aggrx1
  1401.     exg    a3,a2
  1402. *
  1403. *  a1 & a2 are singles, a3 is aggregate
  1404. *
  1405. aggrx1:
  1406.  
  1407.     movem.w    4(a1),d0-d1    ;get hpos/vpos of one 
  1408.     movem.w    4(a2),d6-d7    ; & hpos/vpos of the other
  1409.     sub.w    d0,d6
  1410.     bpl    aggrx2        ;get absolute value of horz delta
  1411.     neg.w    d6
  1412. aggrx2:
  1413.     sub.w    d1,d7
  1414.     bpl    aggrx3        ;get vert delta
  1415.     neg.w    d7
  1416. aggrx3:
  1417.     cmp.w    d7,d6        ;which is greater, horz or vert?
  1418.     ble    v2big        ;br if vertical
  1419. *
  1420. *  a1, a2 -> intrinsics
  1421. *
  1422.     move.w    4(a1),d0
  1423.     cmp.w    4(a2),d0
  1424.     bcs    aggrx4
  1425.     exg    a1,a2        ;a1 -> leftmost intrinsic
  1426. aggrx4:
  1427. *
  1428. *  we're horz--which end of compound bridge to bridge to?
  1429. *
  1430. *  check 1st endbrush and eliminate if:
  1431. *
  1432. *    Endbrush horizontally between intrinsics
  1433. *    Endbrush face needed for new bridge is bridged already
  1434. *    Mean intrinsics vpos alignment with endbrush exceeds height
  1435. *
  1436. *
  1437.     move.w    (a3),d0
  1438.     lsl.w    #4,d0
  1439.     move.l    8(a5,d0.w),a6    
  1440.     movem.w    4(a3),d2-d3    ;get base hpos/vpos of compound bridge
  1441. *
  1442.     moveq    #0,d0        ;assume both endbrushes OK
  1443. *
  1444.     movem.w    10(a6),d4-d5    ;get relative hpos/vpos of 1st endbrush
  1445.     add.w    d2,d4        ;form absolute hpos
  1446.     add.w    d3,d5        ; & vpos
  1447.     move.w    d4,d6
  1448.     move.w    d4,d1
  1449.     sub.w    4(a1),d6
  1450.     sub.w    4(a2),d1
  1451.     eor.w    d6,d1        ;check endbrush between intrinsics
  1452.     bmi    must2        ;br if must reject 1st
  1453. *
  1454.     move.w    10(a6),d1    ;get relative hpos 1st endbrush
  1455.     sub.w    22(a6),d1    ;find delta with previous bridge
  1456.     beq    vbridg        ;br if its a vertical--face is avail
  1457.     eor.w    d6,d1        ;check for available face
  1458.     bpl    must2        ;br if face not avail, must select other or none
  1459. vbridg:
  1460.     move.w    6(a1),d1
  1461.     add.w    6(a2),d1
  1462.     lsr.w    #1,d1        ;d1 = average vpos of intrinsics
  1463.     sub.w    d5,d1        ;get delta with vpos of this endbrush
  1464.     bpl    hcheck
  1465.     neg.w    d1        ;get positive delta
  1466. hcheck:
  1467.     move.w    6(a6),d5    ;find 1st endbrush height
  1468.     lsl.w    #4,d5
  1469.     cmp.w    2(a5,d5.w),d1    ;1st endbrush height >= delta?
  1470.     bhi    must2        ;br if vertical alignment not good enough
  1471. *
  1472. *  we pass the 3 tests for 1st endbrush, now check last
  1473. *
  1474.     bra    mustchk2
  1475. must2:
  1476.     ori.w    #1,d0        ;indicate 1st endbrush rejected
  1477. mustchk2:
  1478.     move.w    d4,-(sp)    ;save hpos of 1st endbrush
  1479. *
  1480. *  Last endbrush must pass three tests
  1481. *
  1482.     move.w    4(a6),d7    ;get compound item count
  1483.     mulu    #12,d7
  1484.     movem.w    10(a6,d7.w),d4-d5 ;get relative hpos/vpos of last endbrush
  1485.     add.w    d2,d4        ;form absolute hpos
  1486.     add.w    d3,d5        ; & vpos
  1487.     move.w    d4,d6
  1488.     move.w    d4,d1
  1489.     sub.w    4(a1),d6
  1490.     sub.w    4(a2),d1
  1491.     eor.w    d6,d1        ;check endbrush between intrinsics
  1492.     bmi    must1        ;br if must select first or none
  1493. *
  1494.     move.w    10(a6,d7.w),d1    ;get relative hpos 1st endbrush
  1495.     sub.w    -2(a6,d7.w),d1    ;find delta with previous bridge
  1496.     beq    vbridg0        ;br if its a vertical--face is avail
  1497.     eor.w    d6,d1        ;check for available face
  1498.     bpl    must1        ;br if face not avail, must select other or none
  1499. vbridg0:
  1500.     move.w    6(a1),d1
  1501.     add.w    6(a2),d1
  1502.     lsr.w    #1,d1        ;d1 = average vpos of intrinsics
  1503.     sub.w    d5,d1        ;get delta with vpos of this endbrush
  1504.     bpl    hcheck0
  1505.     neg.w    d1        ;get positive delta
  1506. hcheck0:
  1507.     move.w    6(a6,d7.w),d5    ;find last endbrush height
  1508.     lsl.w    #4,d5
  1509.     cmp.w    2(a5,d5.w),d1    ;1st endbrush height >= delta?
  1510.     bhi    must1        ;br if vertical alignment not good enough
  1511. *
  1512. *  we pass the 3 tests
  1513. *
  1514.     bra    mustchk
  1515. must1:
  1516.     ori.w    #2,d0        ;reject last brush
  1517. mustchk:
  1518.     move.w    (sp)+,d5    ;reget 1st endbrush hpos
  1519. *
  1520.     cmpi.w    #3,d0        ;rejected both?
  1521.     beq    ag_abort    ;br if so
  1522. *
  1523.     cmpi.w    #2,d0        ;selected 1st & rejected last?
  1524.     beq    dohfirst    ;br to do 1st
  1525. *
  1526.     cmpi.w    #1,d0        ;selected last & rejected first?
  1527.     beq    dohlast        ;br to do last
  1528. *
  1529. *  both brushes are eligible--choose the one closest
  1530. *  d4.w = last endbrush hpos, d5.w = 1st endbrush hpos
  1531. *
  1532.     move.w    d4,d1
  1533.     sub.w    4(a1),d1
  1534.     bpl    hcheck1
  1535.     neg.w    d1
  1536. hcheck1:
  1537.     sub.w    4(a2),d4
  1538.     bpl    hcheck2
  1539.     neg.w    d4
  1540. hcheck2:
  1541.     cmp.w    d4,d1
  1542.     bcc    hcheck3
  1543.     move.w    d1,d4
  1544. hcheck3:
  1545. *
  1546. *   d4 = minimum abs horz delta for last endbrush
  1547. *
  1548.     move.w    d5,d1
  1549.     sub.w    4(a1),d1
  1550.     bpl    hcheck4
  1551.     neg.w    d1
  1552. hcheck4:
  1553.     sub.w    4(a2),d5
  1554.     bpl    hcheck5
  1555.     neg.w    d5
  1556. hcheck5:
  1557.     cmp.w    d5,d1
  1558.     bcc    hcheck6
  1559.     move.w    d1,d5
  1560. hcheck6:
  1561. *
  1562. *   d5 = minimum abs horz delta for 1st endbrush
  1563. *
  1564.     cmp.w    d4,d5        ;which is closer?
  1565.     bcc    dohlast 
  1566. *
  1567. *  we picked 1st or last endbrush..
  1568. *
  1569. dohfirst:
  1570.     moveq    #0,d1
  1571.     bra    comphorz
  1572. dohlast:
  1573.     moveq    #-1,d1
  1574. comphorz:
  1575.     move.w    d1,tempbuf+26
  1576. *
  1577.     move.w    (a3),d0
  1578.     lsl.w    #4,d0
  1579.     move.l    8(a5,d0.w),a6
  1580.     movem.w    4(a3),d2-d3
  1581.     tst.w    d1
  1582.     beq    cphorz0
  1583.     move.w    4(a6),d1    ;get last index
  1584. cphorz0:
  1585.     mulu    #12,d1
  1586.     add.w    10(a6,d1.l),d2    ;add relative h/v positions to 
  1587.     add.w    12(a6,d1.l),d3    ;  get absolute hpos/vpos of endbrush
  1588.     move.w    6(a6,d1.l),d1    ;  & get endbrush #
  1589. *
  1590. *  check horz position-order amongst the three
  1591. *
  1592.     cmp.w    4(a1),d2    ;is left intrinsic left of endbrush?
  1593.     bge    h123        ;br if so
  1594. *
  1595. *  else, we do a3,a1,a2 order
  1596. *
  1597.     move.l    a0,(a4)+
  1598.     move.l    (a3)+,(a0)+    ;copy brush & effects
  1599.     move.l    (a3)+,(a0)+    ;use hpos/vpos
  1600. *
  1601. *  now a1 & a2 must use vpos in d3, a1 must use xpos at left side of endbrush
  1602. *
  1603.     move.l    a0,(a4)+
  1604.     move.l    (a1)+,(a0)+
  1605.     lsl.w    #4,d1
  1606.     add.w    (a5,d1.w),d2
  1607.     move.w    d2,(a0)+
  1608.     move.w    d3,(a0)+
  1609. *
  1610.     move.l    a0,(a4)+
  1611.     move.l    (a2)+,(a0)+
  1612.     move.w    (a2)+,(a0)+
  1613.     move.w    d3,(a0)+
  1614. *    
  1615.     move.w    #$8000,(a0)    ;indicate stretch destination is intrinsic
  1616.     bra    wehclust
  1617. *
  1618. *  do a1,a2,a3 order
  1619. *    
  1620. h123:
  1621.     move.l    a0,(a4)+
  1622.     move.l    (a1)+,(a0)+
  1623.     move.w    (a1),(a0)+
  1624.     move.w    d3,(a0)+
  1625. *
  1626.     move.l    a0,(a4)+
  1627.     move.w    -8(a0),d1
  1628.     lsl.w    #4,d1
  1629.     move.w    (a5,d1.w),d1
  1630.     add.w    (a1),d1
  1631.     move.l    (a2)+,(a0)+
  1632.     move.w    d1,(a0)+
  1633.     move.w    d3,(a0)+
  1634. *
  1635.     move.l    a0,(a4)+
  1636.     move.l    (a3)+,(a0)+
  1637.     move.l    (a3)+,(a0)+
  1638. *
  1639.     move.w    d2,(a0)    ;save stretch destination into complex bridge
  1640.     bra    wehclust
  1641. *
  1642. *
  1643. ***************************************************
  1644. *
  1645. *    We're going for the vertical orientation
  1646. *
  1647. *
  1648. v2big:
  1649.     move.w    6(a1),d0
  1650.     cmp.w    6(a2),d0
  1651.     bcs    v2bigx4
  1652.     exg    a1,a2        ;a1 -> topmost intrinsic
  1653. v2bigx4:
  1654. *
  1655. *  we're vert--which end of compound bridge to bridge to?
  1656. *
  1657. *  check 1st endbrush and eliminate if:
  1658. *
  1659. *    Endbrush vertically between intrinsics
  1660. *    Endbrush face needed for new bridge is bridged already
  1661. *    Mean intrinsics hpos alignment with endbrush exceeds width
  1662. *
  1663. *
  1664.     move.w    (a3),d0
  1665.     lsl.w    #4,d0
  1666.     move.l    8(a5,d0.w),a6
  1667.     movem.w    4(a3),d2-d3    ;get base hpos/vpos of compound bridge
  1668. *
  1669.     moveq    #0,d0        ;assume both endbrushes OK
  1670. *
  1671.     movem.w    10(a6),d4-d5    ;get relative hpos/vpos of 1st endbrush
  1672.     add.w    d2,d4        ;form absolute hpos
  1673.     add.w    d3,d5        ; & vpos
  1674.     move.w    d5,d6
  1675.     move.w    d5,d1
  1676.     sub.w    6(a1),d6
  1677.     sub.w    6(a2),d1
  1678.     eor.w    d6,d1        ;check endbrush between intrinsics
  1679.     bmi    mustv2        ;br if must reject 1st
  1680. *
  1681.     move.w    12(a6),d1    ;get relative vpos 1st endbrush
  1682.     sub.w    24(a6),d1    ;find delta with previous bridge
  1683.     beq    hbridg        ;br if its a horz--face is avail
  1684.     eor.w    d6,d1        ;check for available face
  1685.     bpl    mustv2        ;br if must reject 1st (face unavail)
  1686. hbridg:
  1687.     move.w    4(a1),d1
  1688.     add.w    4(a2),d1
  1689.     lsr.w    #1,d1        ;d1 = average hpos of intrinsics
  1690.     sub.w    d4,d1        ;get delta with hpos of this endbrush
  1691.     bpl    vcheck
  1692.     neg.w    d1        ;get positive delta
  1693. vcheck:
  1694.     move.w    6(a6),d4    ;get 1st endbrush #
  1695.     lsl.w    #4,d4
  1696.     cmp.w    (a5,d4.w),d1    ;1st endbrush width >= delta?
  1697.     bhi    mustv2        ;br if vertical alignment not good enough
  1698. *
  1699. *  we pass the 3 tests for 1st endbrush, now check last
  1700. *
  1701.     bra    mustcvk2
  1702. mustv2:
  1703.     ori.w    #1,d0        ;indicate 1st endbrush rejected
  1704. mustcvk2:
  1705.     move.w    d5,-(sp)    ;save vpos of 1st endbrush
  1706. *
  1707. *  Last endbrush must pass three tests
  1708. *
  1709.     move.w    4(a6),d7    ;get compound item count
  1710.     mulu    #12,d7
  1711.     movem.w    10(a6,d7.w),d4-d5 ;get relative hpos/vpos of last endbrush
  1712.     add.w    d2,d4        ;form absolute hpos
  1713.     add.w    d3,d5        ; & vpos
  1714.     move.w    d5,d6
  1715.     move.w    d5,d1
  1716.     sub.w    6(a1),d6
  1717.     sub.w    6(a2),d1
  1718.     eor.w    d6,d1        ;check endbrush between intrinsics
  1719.     bmi    mustv1        ;br if must reject last
  1720. *
  1721.     move.w    12(a6,d7.w),d1    ;get relative vpos 1st endbrush
  1722.     sub.w    (a6,d7.w),d1    ;find delta with previous bridge
  1723.     beq    hbridg0        ;br if its a vertical--face is avail
  1724.     eor.w    d6,d1        ;check for available face
  1725.     bpl    mustv1        ;br if face not avail, must select other or none
  1726. hbridg0:
  1727.     move.w    4(a1),d1
  1728.     add.w    4(a2),d1
  1729.     lsr.w    #1,d1        ;d1 = average hpos of intrinsics
  1730.     sub.w    d4,d1        ;get delta with hpos of this endbrush
  1731.     bpl    vcheck0
  1732.     neg.w    d1        ;get positive delta
  1733. vcheck0:
  1734.     move.w    6(a6,d7.w),d4    ;find last endbrush #
  1735.     lsl.w    #4,d4
  1736.     cmp.w    (a5,d4.w),d1    ;1st endbrush width >= delta?
  1737.     bhi    mustv1        ;br if vertical alignment not good enough
  1738. *
  1739. *  we pass the 3 tests
  1740. *
  1741.     bra    mustcvk
  1742. mustv1:
  1743.     ori.w    #2,d0        ;reject last brush
  1744. mustcvk:
  1745.     move.w    (sp)+,d4    ;reget 1st endbrush hpos
  1746. *
  1747.     cmpi.w    #3,d0        ;rejected both?
  1748.     beq    ag_abort    ;br if so
  1749. *
  1750.     cmpi.w    #2,d0        ;selected 1st & rejected last?
  1751.     beq    dovfirst    ;br to do 1st
  1752. *
  1753.     cmpi.w    #1,d0        ;selected last & rejected first?
  1754.     beq    dovlast        ;br to do last
  1755. *
  1756. *  both brushes are eligible--choose the one closest
  1757. *  d4.w = first endbrush vpos, d5.w = last endbrush vpos
  1758. *
  1759.     move.w    d4,d1
  1760.     sub.w    6(a1),d1
  1761.     bpl    vcheck1
  1762.     neg.w    d1
  1763. vcheck1:
  1764.     sub.w    6(a2),d4
  1765.     bpl    vcheck2
  1766.     neg.w    d4
  1767. vcheck2:
  1768.     cmp.w    d4,d1
  1769.     bcc    vcheck3
  1770.     move.w    d1,d4
  1771. vcheck3:
  1772. *
  1773. *   d4 = minimum abs vert delta for last endbrush
  1774. *
  1775.     move.w    d5,d1
  1776.     sub.w    6(a1),d1
  1777.     bpl    vcheck4
  1778.     neg.w    d1
  1779. vcheck4:
  1780.     sub.w    6(a2),d5
  1781.     bpl    vcheck5
  1782.     neg.w    d5
  1783. vcheck5:
  1784.     cmp.w    d5,d1
  1785.     bcc    vcheck6
  1786.     move.w    d1,d5
  1787. vcheck6:
  1788. *
  1789. *   d5 = minimum abs vert delta for 1st endbrush
  1790. *
  1791.     cmp.w    d5,d4        ;which is closer?
  1792.     bcc    dovlast 
  1793. *
  1794. *  we picked 1st or last endbrush..
  1795. *
  1796. dovfirst:
  1797.     moveq    #0,d1
  1798.     bra    compvert
  1799. dovlast:
  1800.     moveq    #-1,d1
  1801. compvert:
  1802.     move.w    d1,tempbuf+26
  1803. *
  1804.     move.w    (a3),d0
  1805.     lsl.w    #4,d0
  1806.     move.l    8(a5,d0.w),a6
  1807.     movem.w    4(a3),d2-d3
  1808.     tst.w    d1
  1809.     beq    cpvert0
  1810.     move.w    4(a6),d1    ;get last index
  1811. cpvert0:
  1812.     mulu    #12,d1
  1813.     add.w    10(a6,d1.l),d2    ;add relative h/v positions to 
  1814.     add.w    12(a6,d1.l),d3    ;  get absolute hpos/vpos of endbrush
  1815.     move.w    6(a6,d1.l),d1    ;  & get endbrush #
  1816. *
  1817. *  check vert position-order amongst the three
  1818. *
  1819.     cmp.w    6(a1),d3    ;is top intrinsic above endbrush?
  1820.     bge    v123        ;br if so
  1821. *
  1822. *  else, we do a3,a1,a2 order
  1823. *
  1824.     move.l    a0,(a4)+
  1825.     move.l    (a3)+,(a0)+    ;copy brush & effects
  1826.     move.l    (a3)+,(a0)+    ;use hpos/vpos
  1827. *
  1828. *  now a1 & a2 must use hpos in d2, a1 must use ypos at bottom of endbrush
  1829. *
  1830.     move.l    a0,(a4)+
  1831.     move.l    (a1)+,(a0)+
  1832.     lsl.w    #4,d1
  1833.     add.w    2(a5,d1.w),d3
  1834.     move.w    d2,(a0)+
  1835.     move.w    d3,(a0)+
  1836. *
  1837.     move.l    a0,(a4)+
  1838.     move.l    (a2)+,(a0)+
  1839.     move.w    d2,(a0)+
  1840.     addq.l    #2,a2
  1841.     move.w    (a2)+,(a0)+
  1842. *    
  1843.     move.w    #$8000,(a0)    ;indicate stretch destination is intrinsic
  1844.     bra    wevclust
  1845. *
  1846. *  do a1,a2,a3 order
  1847. *    
  1848. v123:
  1849.     move.l    a0,(a4)+
  1850.     move.l    (a1)+,(a0)+
  1851.     move.w    d2,(a0)+
  1852.     addq.l    #2,a1
  1853.     move.w    (a1),(a0)+
  1854. *
  1855.     move.l    a0,(a4)+
  1856.     move.w    -8(a0),d1
  1857.     lsl.w    #4,d1
  1858.     move.w    2(a5,d1.w),d1
  1859.     add.w    (a1),d1
  1860.     move.l    (a2)+,(a0)+
  1861.     move.w    d2,(a0)+
  1862.     move.w    d1,(a0)+
  1863. *
  1864.     move.l    a0,(a4)+
  1865.     move.l    (a3)+,(a0)+
  1866.     move.l    (a3)+,(a0)+
  1867. *
  1868.     move.w    d3,(a0)    ;save stretch destination into complex bridge
  1869.     bra    wevclust
  1870. *
  1871. ***************************************************
  1872. *
  1873. *  All three are intrinsics--either left edge or top edge
  1874. *    
  1875. aggrnox:
  1876. *
  1877.     moveq    #4,d5        ;check hpos
  1878.     bsr    chepsort
  1879. *
  1880.     movem.l    a1-a3,(a0)    ;save horz sort order
  1881.     move.w    d3,d0
  1882.     sub.w    d1,d0        ;d0 = max horz displacement
  1883. *
  1884.     moveq    #6,d5
  1885.     bsr    chepsort
  1886. *
  1887.     move.w    d3,d4
  1888.     sub.w    d1,d4        ;d4 = max vert displacement
  1889. *
  1890.     cmp.w    d4,d0        ;vert:horz max?
  1891.     ble    vertbrg        ;br if this will be vert bridge
  1892. *
  1893. *  Horz bridge
  1894. *
  1895.     movem.l    (a0),a1-a3
  1896. *
  1897.     move.l    a0,(a4)+
  1898.     move.l    (a1)+,(a0)+    ;copy brush/effects
  1899.     move.w    (a1)+,d0    ;get xpos
  1900.     move.w    d0,(a0)+
  1901.     move.w    d0,xmin_clust    ;adjust cluster xmin
  1902.     move.w    (a1)+,d0    ;get ypos
  1903.     move.w    d0,(a0)+
  1904.     move.w    d0,ymin_clust    ;adjust cluster ymin
  1905. *
  1906.     move.w    -8(a0),d1
  1907.     lsl.w    #4,d1
  1908.     move.w    2(a5,d1.w),d2    ;get brush height
  1909.     add.w    d0,d2
  1910.     move.w    d2,ymax_clust
  1911.     move.w    (a5,d1.w),d2    ;get 1st brush width
  1912.     add.w    -4(a0),d2
  1913. *
  1914. *
  1915.     move.l    a0,(a4)+
  1916.     move.l    (a2)+,(a0)+
  1917.     move.w    d2,(a0)+
  1918.     move.w    d0,(a0)+
  1919. *
  1920.     move.w    -8(a0),d1
  1921.     lsl.w    #4,d1
  1922.     move.w    2(a5,d1.w),d1    ;get brush height
  1923.     add.w    d0,d1
  1924.     cmp.w    ymax_clust,d1
  1925.     ble    hbrid0
  1926.     move.w    d1,ymax_clust
  1927. hbrid0:
  1928. *
  1929. *
  1930.     move.l    a0,(a4)+
  1931.     move.l    (a3)+,(a0)+
  1932.     move.w    (a3)+,(a0)+
  1933.     move.w    d0,(a0)+
  1934. *
  1935.     move.w    -8(a0),d1
  1936.     lsl.w    #4,d1
  1937.     move.w    2(a5,d1.w),d1    ;get brush height
  1938.     add.w    d0,d1
  1939.     cmp.w    ymax_clust,d1
  1940.     ble    hbrid1
  1941.     move.w    d1,ymax_clust
  1942. hbrid1:
  1943.     move.w    #$8000,(a0)    ;indicate stretch destination is intrinsic
  1944. wehclust:
  1945.     bsr    clustit
  1946. *
  1947.     bsr    hstretch    ;h-stretch the middle elemnt of 3-item cluster
  1948. *
  1949.     bsr    reclumsk    ;rebuild cluster mask    
  1950. *
  1951. *  unwrap bridge d'bridges here..
  1952. *
  1953. *   We have three items bridged--expand deriveds
  1954. *
  1955. brid_unw:
  1956.     move.w    curbrush,d0
  1957.     lea    bshblock,a2
  1958.     lsl.w    #4,d0
  1959.     move.l    8(a2,d0.w),a3
  1960.     move.w    6(a3),d0    ;get first endbrush
  1961.     cmp.w    maxintrins,d0    ;is it derived
  1962.     bls    brid_un0    ;br if not
  1963. *
  1964. *  1st endbrush is derived--check for cluster/bridge
  1965. *
  1966.     lsl.w    #4,d0
  1967.     move.l    8(a2,d0.w),a4
  1968.     move.w    4(a4),d1    ;is this derived made up of multiples
  1969.     beq    brid_un0    ;br if not
  1970. *
  1971.     add.w    d1,4(a3)    ;increase cluster count
  1972. *
  1973.     movem.w    10(a3),d4-d6    ;retain hpos/vpos base offset
  1974. *
  1975.     move.w    d1,d2
  1976.     mulu    #12,d2        ;here's how much we need to add
  1977. *
  1978.     move.l    derblkend,a5
  1979.     lea    (a5,d2.l),a6
  1980.     move.l    a6,derblkend
  1981. *
  1982.     moveq    #5,d3
  1983. dervexp:
  1984.     move.l    -(a5),-(a6)    ;move 2 intrinsics to end of list
  1985.     dbra    d3,dervexp
  1986. *
  1987.     suba.w    #12,a5        ;go to head of (1st) derived entry
  1988.     lea    6(a4),a6    ; & to head of corresponding cluster list
  1989.     moveq    #0,d3        ;assume no adjust
  1990.     tst.w    tempbuf+26    ;check first/last link endbrush
  1991.     bmi    dervx        ;br if last was connect
  1992.     adda.l    d2,a6        ;go to tail of cluster list
  1993.     move.w    #24,d3        ;here's a new decrement value
  1994. dervx:
  1995.     move.l    (a6)+,(a5)+    ;put in brush # & effects
  1996.     move.w    (a6)+,d2
  1997.     add.w    d4,d2
  1998.     move.w    d2,(a5)+
  1999.     move.w    (a6)+,d2
  2000.     add.w    d5,d2
  2001.     move.w    d2,(a5)+
  2002.     move.l    (a6)+,(a5)+
  2003.     suba.w    d3,a6
  2004.     dbra    d1,dervx
  2005. *
  2006.     bra    brid_unx    ;we're all set
  2007. *
  2008. *   check for derived at last endbrush of this bridge
  2009. *
  2010. brid_un0:
  2011.     move.w    30(a3),d0    ;get last endbrush
  2012.     cmp.w    maxintrins,d0
  2013.     bls    brid_unx    ;exit if not derived
  2014. *
  2015.     lsl.w    #4,d0
  2016.     move.l    8(a2,d0.w),a4
  2017.     move.w    4(a4),d1    ;is this derived made up of multiples
  2018.     beq    brid_unx    ;br if not
  2019. *
  2020.     add.w    d1,4(a3)    ;increase cluster count
  2021. *
  2022.     movem.w    34(a3),d4-d6    ;retain hpos/vpos base offset
  2023. *
  2024.     move.w    d1,d2
  2025.     mulu    #12,d2        ;here's how much we need to add
  2026. *
  2027.     move.l    derblkend,a5
  2028.     lea    (a5,d2.l),a6
  2029.     move.l    a6,derblkend
  2030. *
  2031.     suba.w    #12,a5        ;go to head of (1st) derived entry
  2032.     lea    6(a4),a6    ; & to head of corresponding cluster list
  2033.     moveq    #0,d3        ;assume no adjust
  2034.     tst.w    tempbuf+26    ;check first/last link endbrush
  2035.     bpl    dervxx        ;br if first was connect
  2036.     adda.l    d2,a6        ;go to tail of cluster list
  2037.     move.w    #24,d3        ;here's a new decrement value
  2038. dervxx:
  2039.     move.l    (a6)+,(a5)+    ;put in brush # & effects
  2040.     move.w    (a6)+,d2
  2041.     add.w    d4,d2
  2042.     move.w    d2,(a5)+
  2043.     move.w    (a6)+,d2
  2044.     add.w    d5,d2
  2045.     move.w    d2,(a5)+
  2046.     move.l    (a6)+,(a5)+
  2047.     suba.w    d3,a6
  2048.     dbra    d1,dervxx
  2049. *
  2050. brid_unx:
  2051.     bra    aggr_i
  2052. *
  2053. *
  2054. *
  2055. ********************************************************
  2056. *  Horz stretch the middle item of a three item cluster
  2057. *
  2058. *    a0 -> base of graphics buffer
  2059. *
  2060. *   curbrush = derived brush of a 3 element cluster
  2061. *
  2062. hstretch:
  2063.     movem.l    a0-a1/d0-d3/d5,-(sp)
  2064.  
  2065.     move.w    curbrush,d0
  2066.     lea    bshblock,a2
  2067.     lsl.w    #4,d0
  2068.     move.w    14(a2,d0.w),d7    ;cluster s_nxln
  2069.     move.l    8(a2,d0.w),a3    ;get cluster elements ptr
  2070.     adda.w    #18,a3        ;go for 2nd (bridging) element
  2071.     move.w    (a3),d0        ;get bridge brush #
  2072.     move.w    #Hbridge,2(a3)    ;stuff in a special effect
  2073.     lsl.w    #4,d0
  2074.     move.w    2(a2,d0.w),d5    ;d5 = bridge height
  2075.     lsl.w    #2,d5
  2076.     move.w    6(a3),d1    ;vpos of bridge element
  2077.     mulu    d7,d1
  2078.     adda.l    d1,a0
  2079.     move.w    (a2,d0.w),d0    ;d0 = bridge intrinsic width
  2080.     move.w    d0,d4        ;save in d4
  2081.  
  2082.     move.w    tempbuf+24,d1    ;check for complex destination
  2083.     cmpi.w    #$8000,d1    ;should we just use intrinsic?
  2084.     beq    hintrz
  2085.     sub.w    xmin_clust,d1
  2086.     bra    hintrz0
  2087. hintrz:    
  2088.     move.w    16(a3),d1    ;d1 = hpos of last element
  2089. hintrz0:
  2090.     move.w    4(a3),d3    ;d3 = hpos of bridge element
  2091.     add.w    d3,d4        ;get dot addr +1 of rite bridge column
  2092.     move.w    d1,d2
  2093.     sub.w    d3,d2        ;d2 = desired width
  2094.     swap    d0        ;intrinsic width * 65536
  2095.     clr.w    d0
  2096.     divu    d2,d0        ;get frac for DDA
  2097.     subq.w    #1,d0        ;inc value
  2098.     move.w    d0,d3
  2099.     lsr.w    #1,d3        ;d3 = initial DDA value
  2100. *
  2101.     subq.w    #1,d4        ;adjust dot addr to ritemost bridge
  2102.     move.w    d4,d6
  2103.     lsr.w    #3,d6
  2104.     andi.w    #$fffe,d6
  2105.     lea    (a0,d6.w),a3    ;SRC ptr
  2106.     not.w    d4
  2107.     andi.w    #$f,d4        ;SRC bit # in word
  2108. *
  2109.     subq.w    #1,d1        ;DST dot addr
  2110.     move.w    d1,d6
  2111.     lsr.w    #3,d6
  2112.     andi.w    #$fffe,d6
  2113.     lea    (a0,d6.w),a4    ;DST ptr
  2114.     not.w    d1
  2115.     andi.w    #$f,d1        ;DST bit # in word
  2116.     lsr.w    #2,d7        ;get s_nxpl
  2117.     move.w    d0,a2
  2118. *
  2119. *
  2120. *    d0 =  <unused> 
  2121. *    d1 =  DST bit # in word
  2122. *    d2 =  desired (stretched) width
  2123. *    d3 =  DDA accum
  2124. *    d4 =  SRC bit # in word
  2125. *    d5 =  # of plane-lines to expand
  2126. *    d6 = <unused>
  2127. *    d7 =  s_nxpl
  2128. *
  2129. *    a2 = DDA inc
  2130. *    a3 -> SRC in form
  2131. *    a4 -> DST in form
  2132. *
  2133.     bra    hexpandi
  2134. hexpand:
  2135.     movem.l    a3-a4/d1-d4,-(sp)
  2136.     move.w    (a4),d6        ; & DST word
  2137.     move.w    (a3),d0        ;pick up SRC word
  2138. hexp:
  2139.     btst.l    d4,d0
  2140.     bne    hex2
  2141. hex0:
  2142.     subq.w    #1,d2
  2143.     bmi    hexi
  2144.     bclr.l    d1,d6
  2145.     addq.w    #1,d1
  2146.     andi.w    #$f,d1
  2147.     bne    hex1
  2148.     move.w    d6,(a4)
  2149.     move.w    -(a4),d6
  2150. hex1:
  2151.     add.w    a2,d3
  2152.     bcc    hex0
  2153.     addq.w    #1,d4
  2154.     andi.w    #$f,d4
  2155.     bne    hexp
  2156.     move.w    -(a3),d0
  2157.     bra    hexp
  2158. hex2:
  2159.     subq.w    #1,d2
  2160.     bmi    hexi
  2161.     bset.l    d1,d6
  2162.     addq.w    #1,d1
  2163.     andi.w    #$f,d1
  2164.     bne    hex3
  2165.     move.w    d6,(a4)
  2166.     move.w    -(a4),d6
  2167. hex3:
  2168.     add.w    a2,d3
  2169.     bcc    hex2
  2170.     addq.w    #1,d4
  2171.     andi.w    #$f,d4
  2172.     bne    hexp
  2173.     move.w    -(a3),d0
  2174.     bra    hexp
  2175. hexi:
  2176.     move.w    d6,(a4)
  2177.     movem.l    (sp)+,a3-a4/d1-d4
  2178.     adda.w    d7,a3
  2179.     adda.w    d7,a4
  2180. hexpandi:
  2181.     dbra    d5,hexpand
  2182. *
  2183.     movem.l    (sp)+,a0-a1/d0-d3/d5
  2184.     rts
  2185. *
  2186. *
  2187. *
  2188. *
  2189. *
  2190. *
  2191. *  Vert bridge
  2192. *
  2193. *    a1,a2 & a3 are the sorted element ptr's
  2194. *
  2195. vertbrg:
  2196. *
  2197.     move.l    a0,(a4)+
  2198.     move.l    (a1)+,(a0)+
  2199.     move.w    (a1)+,d0
  2200.     move.w    d0,xmin_clust
  2201.     move.w    d0,(a0)+
  2202.     move.w    (a1)+,d1
  2203.     move.w    d1,(a0)+
  2204.     move.w    d1,ymin_clust
  2205. *
  2206.     move.w    -8(a0),d1
  2207.     lsl.w    #4,d1
  2208.     move.w    (a5,d1.w),d2    ;get brush width
  2209.     add.w    d0,d2
  2210.     move.w    d2,xmax_clust
  2211.     move.w    2(a5,d1.w),d2    ;get height
  2212.     add.w    -2(a0),d2    ;get vpos of next item
  2213. *
  2214. *
  2215.     move.l    a0,(a4)+
  2216.     move.l    (a2)+,(a0)+
  2217.     move.w    d0,(a0)+
  2218.     addq.l    #4,a2
  2219.     move.w    d2,(a0)+    ;vpos of second just below 1st
  2220. *
  2221.     move.w    -8(a0),d1
  2222.     lsl.w    #4,d1
  2223.     move.w    (a5,d1.w),d1    ;get brush width
  2224.     add.w    d0,d1
  2225.     cmp.w    xmax_clust,d1
  2226.     ble    vbrid0
  2227.     move.w    d1,xmax_clust
  2228. vbrid0:
  2229. *
  2230. *
  2231.     move.l    a0,(a4)+
  2232.     move.l    (a3)+,(a0)+
  2233.     move.w    d0,(a0)+
  2234.     addq.l    #2,a3
  2235.     move.w    (a3)+,(a0)+
  2236. *
  2237.     move.w    -8(a0),d1
  2238.     lsl.w    #4,d1
  2239.     move.w    (a5,d1.w),d1    ;get brush width
  2240.     add.w    d0,d1
  2241.     cmp.w    xmax_clust,d1
  2242.     ble    vbrid1
  2243.     move.w    d1,xmax_clust
  2244. vbrid1:
  2245.     move.w    #$8000,(a0)
  2246. wevclust:
  2247.     bsr    clustit        ;build it like any cluster
  2248. *
  2249. * preserve a0-a1/d0-d3/d5 here
  2250. *
  2251.     bsr    vstretch    ;v-stretch the middle elemnt of 3-item cluster
  2252. *
  2253.     bsr    reclumsk    ;rebuild cluster mask
  2254.  
  2255.     bra    brid_unw    ;perform the bridge unwrap
  2256. *
  2257. *
  2258. ********************************************************
  2259. *  Vert stretch the middle item of a three item cluster
  2260. *
  2261. *
  2262. *   curbrush = derived brush of a 3 element cluster
  2263. *
  2264. *
  2265. *  Must be called right after clustit
  2266. *
  2267. vstretch:
  2268.     movem.l    a0-a1/a6/d0-d3/d5,-(sp)
  2269. *
  2270.     move.w    curbrush,d0
  2271.     lea    bshblock,a2
  2272.     lsl.w    #4,d0
  2273.     move.l    8(a2,d0.w),a3    ;get cluster elements ptr
  2274.     adda.w    #18,a3        ;go for 2nd (bridging) element
  2275.     move.w    (a3),d0        ;get bridge brush #
  2276.     move.w    #Vbridge,2(a3)    ;stuff in a special effect
  2277.     movem.w    4(a3),d2-d3
  2278.     move.w    d3,d5
  2279.     lsl.w    #4,d0
  2280.     move.w    2(a2,d0.w),d4    ;d4 = intrinsic height of bridge
  2281.     add.w    d4,d3        ;d3 = vpos 1 line below bottom of bridge
  2282.     subq.w    #1,d3        ;d3 = vpos of last line
  2283.     movem.w    d2-d3,d_xmin(a6)
  2284.     lea    s_xmin(a6),a0
  2285.     lea    d_xmin(a6),a1
  2286.     moveq    #6,d2
  2287. vstret0:
  2288.     move.w    (a1)+,(a0)+
  2289.     dbra    d2,vstret0
  2290. *
  2291.     move.l    #$03030303,op_tab(a6)
  2292. *
  2293.     move.w    (a2,d0.w),b_width(a6)    ;set width of bridge element
  2294.     move.w    #1,b_height(a6)    ;do 1 line at a time
  2295. *
  2296.     move.w    tempbuf+24,d1
  2297.     cmpi.w    #$8000,d1
  2298.     beq    vintrz
  2299.     sub.w    ymin_clust,d1
  2300.     bra    vintrz0    
  2301. vintrz:
  2302.     move.w    18(a3),d1    ;d1 = vpos of last element, d3 = vpos bridge
  2303. vintrz0:
  2304.     move.w    d1,d0
  2305.     sub.w    d5,d0        ;d0 = desired height
  2306.     subq.w    #1,d1
  2307.     move.w    d1,d_ymin(a6)
  2308. *
  2309.     swap    d4        ;intrinsic height * 65536
  2310.     clr.w    d4
  2311.     divu    d0,d4        ;get frac for DDA
  2312.     subq.w    #1,d4        ;inc value
  2313.     move.w    d4,d3
  2314.     lsr.w    #1,d3        ;d3 = initial DDA value
  2315.  
  2316.     bra    movslini
  2317. movslin:
  2318.     move.w    #4,plane_ct(a6)
  2319.     movem.l    a0-a6/d0-d7,-(sp)    
  2320.     .dc.w    bitblt
  2321.     movem.l    (sp)+,a0-a6/d0-d7
  2322.     subq.w    #1,d_ymin(a6)
  2323.     add.w    d4,d3        ;check DDA
  2324.     bcc    movslini
  2325.     subq.w    #1,s_ymin(a6)
  2326. movslini:
  2327.     dbra    d0,movslin
  2328. *
  2329. *
  2330.     movem.l    (sp)+,a0-a1/a6/d0-d3/d5
  2331.     rts
  2332. *
  2333. ********************************************
  2334. *
  2335. *
  2336. chepsort:
  2337.     move.w    (a1,d5.w),d1
  2338.     move.w    (a2,d5.w),d2
  2339.     move.w    (a3,d5.w),d3
  2340. *
  2341.     cmp.w    d2,d1
  2342.     ble    brid0
  2343.     exg    d1,d2
  2344.     exg    a1,a2
  2345. brid0:
  2346.     cmp.w    d3,d1
  2347.     ble    brid1
  2348.     exg    d1,d3
  2349.     exg    a1,a3
  2350. brid1:
  2351.     cmp.w    d3,d2
  2352.     ble    brid2
  2353.     exg    d3,d2
  2354.     exg    a3,a2
  2355. brid2:
  2356.     rts
  2357. *    
  2358. *
  2359. *  Hit escape key--abort
  2360. *
  2361. ag_abort:
  2362.     lea    cxit_msg,a0    ;"Abort"
  2363.     bra    agxit
  2364. *
  2365. *  Close cluster select--& build the sucker
  2366. *
  2367. aggr_xit:
  2368.     move.w    aggreg,d7
  2369.     cmpi.b    #2,d7        ;check for 1 or less selected
  2370.     bls    ag_abort    ;abort if so
  2371.     cmpi.w    #3,d7        ;check for 2 or less selected (bridge)
  2372.     bls    ag_abort    ;abort if so
  2373. *    
  2374.     clr.l    brshfile    ;tell 'em we need to sort painter's order
  2375. *
  2376.     bsr    clustit        ;build a new cluster entry in derived
  2377. *
  2378. aggr_i:
  2379.     movem.l    a0/a1,-(sp)
  2380.  
  2381.     bsr    butninit
  2382. *
  2383.     bsr    makemsk
  2384. *
  2385.     moveq    #Arrow,d0
  2386.     bsr    Graf_Mouse
  2387. *
  2388.     movem.l    (sp)+,a0/a1
  2389. *
  2390.     move.l    a0,a3
  2391.     move.l    a1,a0
  2392. *
  2393.     lea    wstruct,a5
  2394.     movem.w    xmin_clust,d0-d1
  2395. *
  2396.     sub.w    xoffset(a5),d0
  2397.     add.w    wx(a5),d0
  2398.     sub.w    yoffset(a5),d1
  2399.     add.w    wy(a5),d1
  2400.  
  2401.     movem.w    d0-d1,bsh_x
  2402. *
  2403.     bra    bckdoorm    ;start a move thru the back door
  2404. *
  2405. agxit:
  2406.     move.w    #WORLD,d0
  2407.     bsr    DaveInfo    ;put up exit msg
  2408. *
  2409.     moveq    #Arrow,d0
  2410.     bsr    Graf_Mouse
  2411.  
  2412.     movem.l    (sp)+,a0-a6/d0-d7
  2413.     rts
  2414. *
  2415. *
  2416. *
  2417. *******************************************
  2418. *
  2419. *  Build a cluster
  2420. *
  2421. *
  2422. *  Entry:
  2423. *
  2424. *   a list of ptr's to the cluster elements is found in the brshfile
  2425. *    buffer if cluster file is read in; else the 1st longword
  2426. *    in brshfile buffer is zero & it is assumed that tempbuf has
  2427. *    the list which needs to be put in painter's order.
  2428. *
  2429. *    aggreg  = $8000 + (count-1) if cluster
  2430. *        =    + (count-1) if bridge
  2431. *                 where "count" is # of elements
  2432. *
  2433. *    The following inputs define the size of the cluster:
  2434. *
  2435. *    xmin_clust
  2436. *    ymin_clust
  2437. *    xmax_clust
  2438. *    ymax_clust
  2439. *
  2440. *
  2441. *  Exit:
  2442. *        a0-> mono mask form
  2443. *        a1-> graphics form of new cluster brush  
  2444. clustit:
  2445. *
  2446. *  find size of form needed for this cluster
  2447. *
  2448.     movem.w    xmin_clust,d0-d3
  2449.     sub.w    d0,d2        ;get width
  2450.     sub.w    d1,d3        ;& height
  2451. *
  2452.     movem.w    d2-d3,bsh_wid
  2453. *
  2454.     lea    clustblt,a6    ;it should be alright to use this
  2455. *
  2456.     move.w    d2,d4
  2457.     addi.w    #15,d4
  2458.     andi.w    #$fff0,d4
  2459.     lsr.w    #1,d4        ;DST form-width
  2460. *
  2461.     move.w    #2,d_nxwd(a6)
  2462.     move.w    #2,s_nxwd(a6)
  2463.     move.w    d4,d_nxln(a6)
  2464.     move.w    d4,d5
  2465.     lsr.w    #2,d4
  2466.     move.w    d4,bsh_monoln
  2467.     move.w    d4,d_nxpl(a6)
  2468.     move.l    derivdend,a1    ;base of DST form
  2469.     move.l    a1,d_form(a6)
  2470.     moveq    #0,d7
  2471.     move.l    d7,p_addr(a6)
  2472.     move.l    d7,s_xmin(a6)
  2473. *
  2474.     move.w    maxderivd,d7
  2475.     addq.w    #1,d7
  2476.     move.w    d7,maxderivd
  2477.     move.w    d7,curbrush
  2478. *
  2479.     lea    bshblock,a2
  2480.     lsl.w    #4,d7
  2481.     move.w    d2,(a2,d7.w)    ;width
  2482.     move.w    d3,2(a2,d7.w)    ;height
  2483.     move.l    a1,4(a2,d7.w)    ;s_form
  2484.     move.l    derblkend,a3
  2485.     move.l    a3,8(a2,d7.w)    ;derive block ptr
  2486.     move.w    d5,14(a2,d7.w)    ;s_nxln
  2487. *    
  2488.     mulu    d3,d5        ;d5 = grafix form size
  2489.     move.w    d5,12(a2,d7.w)    ;mask-offset
  2490. *
  2491.     move.l    d5,d6
  2492.     lsr.l    #2,d6
  2493.     add.l    d5,d6        ;form size (with mask)
  2494.     add.l    a1,d6        ;add base to get end
  2495.     move.l    d6,derivdend    ;Malloc for this dude
  2496. *
  2497.     lsr.l    #2,d5        ;# of long words
  2498.     moveq    #0,d6
  2499. clusclr:
  2500.     move.l    d6,(a1)+    ;clear out the cluster form
  2501.     dbra    d5,clusclr
  2502. *
  2503.     move.l    dstrngend,a4
  2504.     move.l    a4,(a3)+    ;put in an id string
  2505. *
  2506.     lea    clustrng,a1
  2507.     move.w    aggreg,d7    ;get count
  2508.     bclr.l    #15,d7
  2509.     bne    cluscp0
  2510.     lea    bridstrng,a1
  2511. cluscp0:
  2512.     sub.w    #2,d7
  2513.  
  2514. cluscp:
  2515.     move.b    (a1)+,(a4)+
  2516.     bne    cluscp
  2517. *
  2518.     move.l    a4,dstrngend    
  2519. *
  2520.     addi.b    #1,-2(a1)
  2521. *
  2522.     move.w    d7,(a3)+    ;& a brush count (-1)
  2523. *
  2524. *  Now put selections in painters order
  2525. *
  2526.     move.w    d7,d4
  2527.     beq    buildc        ;br if only one entry
  2528. *
  2529.     move.l    wblkptr,d3    ;address beyond our limit 
  2530.     move.l    #worldblk,d2    ;get address of lowest entry
  2531. *
  2532.     lea    brshfile,a1
  2533.     tst.l    (a1)        ;are we already set in painter's order?
  2534.     bne    buildcc        ;skip ordering stuff if so
  2535. *
  2536. blist:
  2537.     move.w    d7,d4
  2538.     lea    tempbuf,a0
  2539. nolist:
  2540.     cmp.l    (a0)+,d2
  2541.     beq    olist
  2542.     dbra    d4,nolist
  2543.     bra    nnolist
  2544. olist:
  2545.     move.l    d2,(a1)+
  2546. nnolist:
  2547.     addq.l    #8,d2
  2548.     cmp    d3,d2
  2549.     bcs    blist        
  2550. *
  2551.     move.l    -(a1),d2
  2552.     addq.l    #8,d2
  2553.     move.l    d2,wblkcur    ;set priority 1 higher than highest
  2554. *
  2555. buildcc:
  2556.     lea    brshfile,a0
  2557. *    
  2558. buildc:
  2559.     move.l    (a0)+,a1    ;get world entry ptr
  2560.     move.w    (a1)+,d4
  2561.     move.w    d4,(a3)+    ;put in brush # (may be derived)
  2562.     clr.w    (a3)+        ;no special effect
  2563.     addq.l    #2,a1        ;skip special effects
  2564.     movem.w    (a1),d2-d3    ;x/ypos
  2565.     sub.w    d0,d2        ;xpos relative to cluster
  2566.     sub.w    d1,d3
  2567.     movem.w    d2-d3,(a3)
  2568.     addq.l    #8,a3        ;adjust for next entry
  2569.     move.w    d2,d_xmin(a6)
  2570.     move.w    d3,d_ymin(a6)
  2571. *
  2572.     lsl.w    #4,d4        ;get brush data
  2573.     move.w    (a2,d4.w),b_width(a6)
  2574.     move.w    2(a2,d4.w),b_height(a6)
  2575.     move.l    4(a2,d4.w),a4
  2576.     move.l    a4,-(sp)
  2577.     adda.w    12(a2,d4.w),a4    
  2578.     move.l    a4,s_form(a6)
  2579.     move.l    (sp)+,a4
  2580.     move.w    14(a2,d4.w),d2
  2581.     lsr.w    #2,d2
  2582.     move.w    d2,s_nxln(a6)
  2583.     clr.w    s_nxpl(a6)
  2584. *
  2585.     move.l    #$04040404,op_tab(a6)
  2586.     move.w    #4,plane_ct(a6)
  2587.  
  2588.     movem.l    a0/a2-a4/a6/d0-d1/d7,-(sp)
  2589.     .dc.w    bitblt    
  2590.     movem.l    (sp)+,a0/a2-a4/a6/d0-d1/d7
  2591.  
  2592.     move.l    a4,s_form(a6)
  2593.     move.l    #$07070707,op_tab(a6)
  2594.     move.w    #4,plane_ct(a6)
  2595.     move.w    s_nxln(a6),d2
  2596.     move.w    d2,s_nxpl(a6)
  2597.     add.w    d2,d2
  2598.     add.w    d2,d2
  2599.     move.w    d2,s_nxln(a6)
  2600.  
  2601.     movem.l    a0/a2-a4/a6/d0-d1/d7,-(sp)
  2602.     .dc.w    bitblt    
  2603.     movem.l    (sp)+,a0/a2-a4/a6/d0-d1/d7
  2604.     dbra    d7,buildc
  2605. *
  2606.     move.l    a3,derblkend        ;save new derive block end
  2607. *
  2608. *   Now build mask
  2609. *
  2610.     move.l    d_form(a6),a0
  2611.     move.w    d_nxln(a6),d0
  2612.     move.w    d0,d6
  2613.     lsr.w    #2,d0
  2614.     move.w    d0,d5
  2615.     lsr.w    #1,d5
  2616.     subq.w    #1,d5            ;d5 = # of words in line (-1)
  2617. *
  2618.     move.w    d0,d1
  2619.     add.w    d1,d1            ;d1 = offset to plane #2
  2620.     move.w    d1,d2
  2621.     add.w    d0,d2            ;d2 = offset to plane #3
  2622.     move.w    ymax_clust,d3
  2623.     sub.w    ymin_clust,d3        ;get form height
  2624.     mulu    d3,d6
  2625.     lea    (a0,d6.l),a1
  2626. *
  2627. *  Enter here if we need to rebuild mask
  2628. *
  2629. reclumsk:
  2630.     movem.l    a0/a1/d3,-(sp)
  2631.     bra    clust_8i
  2632. clust_81:
  2633.     move.w    d5,d6
  2634. clust_82:
  2635.     move.w    (a0,d2.w),d4
  2636.     or.w    (a0,d1.w),d4
  2637.     or.w    (a0,d0.w),d4
  2638.     or.w    (a0)+,d4
  2639.     move.w    d4,(a1)+
  2640.     dbra    d6,clust_82    
  2641.     adda.w    d2,a0
  2642. clust_8i:
  2643.     dbra    d3,clust_81
  2644. *
  2645.     movem.l    (sp)+,a0/a1/d3
  2646.     rts
  2647. *
  2648. ***********************************************
  2649. *
  2650. *
  2651. *
  2652. *   Build a rectangle fo' the people
  2653. *
  2654. dorect:
  2655.     movem.l    a0-a6/d0-d7,-(sp)
  2656. *
  2657.     moveq    #thincros,d0
  2658.     bsr    Graf_Mouse        ;put up a thin cross
  2659. *
  2660.     clr.w    butt            ;init 
  2661. *
  2662.     move.w    #1,rectwid
  2663.     move.w    #1,recthite
  2664. *    move.w    #15,rectcol
  2665. *
  2666.     lea    rectmsg,a0
  2667.     move.w    #WORLD,d0
  2668.     bsr    DaveInfo
  2669. *
  2670. rectlp:
  2671.     bsr    getmouse
  2672.     bsr    rectsel        ;check keyboard for color change
  2673.     
  2674.     and    #1,d3        ;any mouse button down yet
  2675.     beq    rectlp        ;br if none
  2676. *
  2677.     bclr.b    #1,BUT_STATE+1
  2678.     bne    rectx0
  2679. *
  2680.     bclr.b    #0,BUT_STATE+1
  2681.     beq    rectlp
  2682. *
  2683. *  Qualify left click (must be on world window)
  2684. *
  2685.     move.l    mouseptr,a0
  2686.     movem.w    (a0),d0-d1    ;save mouse position
  2687.     movem.w    d0-d1,-(sp)
  2688.     bsr    clipinit
  2689.     movem.w    (sp)+,d0-d1
  2690.     movem.w    d0-d1,(a0)    ;restore mouse
  2691.     cmp.w    Mclpxmn,d0
  2692.     blt    rectlp        ;mouse off the left side
  2693.     cmp.w    Mclpymn,d1
  2694.     blt    rectlp
  2695.     cmp.w    Mclpxmx,d0
  2696.     bge    rectlp
  2697.     cmp.w    Mclpymx,d1
  2698.     bge    rectlp
  2699. *
  2700. *  we're on the world window
  2701. *
  2702.     bsr    butninit
  2703. *
  2704.     move.w    maxderivd,d7
  2705.     addq.w    #1,d7
  2706. *
  2707. *    Build a brush block entry but don't allocate it yet
  2708. *
  2709. *    d7 = curbrush
  2710. *
  2711. rectloop:
  2712.     bsr    genarect    ;generate a filled rectangle entry
  2713.     movem.l    a1/d7,-(sp)
  2714. *
  2715.     move.w    #LIBRARY,d0
  2716.     move.l    a4,a0
  2717.     bsr    DaveInfo
  2718. *
  2719.     movem.w    mousex,d0-d1
  2720.     movem.w    rectwid,d2-d3
  2721.     move.w    d2,d4
  2722.     lsr.w    #1,d4
  2723.     sub.w    d4,d0
  2724.     move.w    d3,d4
  2725.     lsr.w    #1,d4
  2726.     sub.w    d4,d1
  2727.     moveq    #0,d4
  2728.     movem.w    d0-d4,bsh_x
  2729.     lea    allones,a3
  2730.     move.w    rectcol,d5
  2731.     lea    (a3,d5.w),a0    ;encode color in mask ptr
  2732. *
  2733.     bsr    bdisplay
  2734.     movem.l    (sp)+,a1/d7
  2735. *
  2736. momouse:
  2737.     bsr    getmouse
  2738.     bsr    rectsel        ;respond to color select
  2739. *
  2740.     andi.w    #1,d3        ;has button been released?
  2741.     beq    gotrect
  2742. *
  2743.     bclr.b    #1,BUT_STATE+1    ;was it a right button
  2744.     bne    rectx1        ;exit if so
  2745. *
  2746.     move.l    mouseptr,a2
  2747.     movem.w    (a2),d0-d1
  2748.     move.l    relcentx,(a2)
  2749. *
  2750.     move.w    d4,d3        ;d4 = 0 if no color change
  2751. *
  2752.     sub.w    relcentx,d0    ;get relative horz motion
  2753.     beq    rectlp3a
  2754.     addq.w    #1,d3
  2755.     add.w    rectwid,d0
  2756.     cmpi.w    #1,d0
  2757.     bge    rectlp2
  2758.     moveq    #1,d0
  2759. rectlp2:
  2760.     cmpi.w    #maxrectw,d0
  2761.     ble    rectlp3
  2762.     move.w    #maxrectw,d0
  2763. rectlp3:
  2764.     move.w    d0,rectwid
  2765. *
  2766. rectlp3a:
  2767.     sub.w    relcenty,d1    ;get relative vert motion
  2768.     beq    rectlp5a
  2769.     addq.w    #1,d3
  2770.     add.w    recthite,d1
  2771.     cmpi.w    #1,d1
  2772.     bge    rectlp4
  2773.     moveq    #1,d1
  2774. rectlp4:
  2775.     cmpi.w    #maxrecth,d1
  2776.     ble    rectlp5
  2777.     move.w    #maxrecth,d1
  2778. rectlp5:
  2779.     move.w    d1,recthite
  2780. rectlp5a:
  2781.     tst.w    d3
  2782.     beq    momouse        ;br if no move here
  2783. *
  2784.     bsr    pastund
  2785.     bra    rectloop
  2786. *
  2787. *   d0,d1 is screen hpos,vpos of cursor
  2788. *
  2789. rectx0:
  2790. *    move.l    mouseptr,a0
  2791. *    movem.w    (a0),d0-d1
  2792.     moveq    #1,d2
  2793.     moveq    #1,d3
  2794.     movem.w    d0-d3,bsh_x
  2795.     move.w    #-1,undhite    ;tell pastund not to do anything
  2796. *
  2797.     move.w    #MouseOff,d0
  2798.     bsr    Graf_Mouse
  2799. rectx1:
  2800.     move.w    #Arrow,d0
  2801.     bsr    Graf_Mouse
  2802. *
  2803.     move.w    #WORLD,d0
  2804.     lea    rectabrt,a0
  2805.     bsr    DaveInfo
  2806.     bra    lib_xita
  2807. *
  2808. *
  2809. gotrect:
  2810.     move.l    a1,dstrngend
  2811.     add.l    #18,derblkend
  2812.     addq.w    #1,maxderivd
  2813.     move.w    maxderivd,curbrush
  2814. *
  2815.     moveq    #Arrow,d0
  2816.     bsr    Graf_Mouse
  2817. *
  2818.     lea    allones,a3
  2819.     move.w    rectcol,d5
  2820.     lea    (a3,d5.w),a0
  2821.     bra    lib_m    
  2822. *
  2823. *
  2824. rectsel:
  2825.     tst.w    d4        ;check for any keys
  2826.     beq    rectselx
  2827.     cmpi.b    #"a",d4
  2828.     bcs    rectsel0
  2829.     subi.b    #$20,d4
  2830. rectsel0:
  2831.     subi.b    #"0",d4        ;check for a color key
  2832.     bcs    rectselx    ;br if not a 0-F
  2833.     cmpi.b    #10,d4        ;is it 0-9?
  2834.     bcs    rectsel1    ;br if so
  2835.     subi.b    #7,d4        
  2836.     cmpi.b    #10,d4
  2837.     bcs    rectselx
  2838.     cmpi.b    #16,d4
  2839.     bcc    rectselx
  2840. *
  2841. *  stuff the color
  2842. *
  2843. rectsel1:
  2844.     move.b    d4,rectcol+1
  2845.     moveq    #1,d4        ;indicate a color change
  2846.     rts
  2847. rectselx:
  2848.     moveq    #0,d4        ;no change
  2849.     rts
  2850. *
  2851. *
  2852. *  Generate the rect fill string
  2853. *
  2854. *    Entry:
  2855. *    d7 = curbrush
  2856. *    rectwid,recthite,rectcol are valid
  2857. *
  2858. *    Exit:
  2859. *    a1 -> end of fill ID string (+1) to save in dstrngend
  2860. *    a4 -> start of fill ID string (from dstrngend) 
  2861. genarect:
  2862.     lea    bshblock,a2
  2863.     move.w    d7,d0
  2864.     lsl.w    #4,d0
  2865.     movem.w    rectwid,d2-d4
  2866.     movem.w    d2-d3,(a2,d0.w)
  2867.     move.l    #allones,4(a2,d0.w)
  2868.     move.l    derblkend,a3
  2869.     move.l    a3,8(a2,d0.w)
  2870.     move.w    rectcol,12(a2,d0.w)    ;save color in offset
  2871.     clr.w    14(a2,d0.w)    ;s_nxln = 0
  2872.     move.l    dstrngend,a4    ;we'll build a derived string
  2873.     move.l    a4,(a3)+
  2874.     clr.w    (a3)+        ;object cnt = 0
  2875.     clr.w    (a3)+        ;bsh # (not relevent)
  2876.     move.w    rectcol,d0
  2877.     lsl.w    #8,d0
  2878.     ori.w    #$8000,d0
  2879.     move.w    d0,(a3)+    ;indicate effect + color
  2880.     clr.l    (a3)+
  2881.     move.l    a4,a1
  2882.     lea    rectstrg,a0
  2883. rectcp:
  2884.     move.b    (a0)+,(a1)+
  2885.     bne    rectcp
  2886. *
  2887.     subq.l    #1,a1
  2888.     move.w    d2,d0        ;put out width
  2889.     movem.w    d3-d4,-(sp)
  2890.     bsr    decitpad
  2891.     movem.w    (sp)+,d3-d4
  2892.     move.w    #"0",d0
  2893. rectcp0:
  2894.     cmp.b    -(a1),d0
  2895.     bhi    rectcp0
  2896.     addq.l    #1,a1
  2897.     move.b    #":",(a1)+
  2898.     move.b    #"h",(a1)+
  2899.     move.w    d3,d0        ;put out height
  2900.     move.w    d4,-(sp)
  2901.     bsr    decitpad
  2902.     move.w    (sp)+,d4
  2903.     move.w    #"0",d0
  2904. rectcp1:
  2905.     cmp.b    -(a1),d0
  2906.     bhi    rectcp1
  2907.     addq.l    #1,a1
  2908.     move.b    #":",(a1)+
  2909.     move.b    #"c",(a1)+
  2910.     move.w    d4,d0        ;put out color
  2911.     bsr    decitpad
  2912.     move.w    #"0",d0
  2913. rectcp2:
  2914.     cmp.b    -(a1),d0
  2915.     bhi    rectcp2
  2916.     addq.l    #1,a1
  2917.     clr.b    (a1)+
  2918.     rts
  2919. *
  2920. *
  2921. *
  2922. *
  2923. allones:
  2924.     .dc.w    $ffff
  2925. *
  2926. rectstrg:
  2927.     .dc.b    "FILL/w",0,0
  2928. *    .dc.b    "FILL/w000:h000:c000  ",0
  2929.