home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / !BONUS / GAMES / ENGINES / DOOMES19.ZIP / DOOM_ES / ADDWALL.S < prev    next >
Text File  |  1997-06-16  |  27KB  |  802 lines

  1. *=======================================================*
  2. *    AddWall: latest update 27/11/95            *
  3. *=======================================================*
  4. *    Build wall & floor runs for 3D environment.    *
  5. *=======================================================*
  6. *     >    New 68030 replacement by Douglas Little.    *
  7. *     >    Atari C conversion by Johan Klockars.        *
  8. *     >    Original C++ code for the PC by Jake Hill    *
  9. *=======================================================*
  10. *    Some improvements made to 68030 version:    *
  11. *=======================================================*
  12. *     >    Algorithm cleaned up to reduce overprinting.    *
  13. *     >    Fewer calculations performed on 'invisibles'.    *
  14. *     >    Upper & lower walls now update occlusion list.    *
  15. *     >    Walls can be placed on sub-pixel boundaries.    *
  16. *     >    Bugs in floors & ceilings removed.        *
  17. *     >    Algorithm uses ~ 90% register based logic.    *
  18. *     >    Local variables accessed from structure.    *
  19. *     >    Optimised (non-stackable) program-flow.        *
  20. *     >    Missing-column bug greatly suppressed.        *
  21. *     >    Higher accuracy arithmetic used on walls.    *
  22. *     >    Improved column clipping logic (drawing bugs).    *
  23. *=======================================================*
  24.  
  25. ;customflow    ; enable for optimised non-stackable subroutines.
  26.         ; this produces bigger code, but no stack access.
  27.         ; it would benefit more from better cacheing and
  28.         ; isn't really worth enabling yet.
  29.  
  30. *-------------------------------------------------------*
  31. *    These register equates are for clarity        *
  32. *-------------------------------------------------------*
  33.  
  34. column_lasttop        equr    a2
  35. column_lastmaxy        equr    a3
  36. column_lastbot        equr    a4
  37. column_lastminy        equr    a5
  38.  
  39. column_thistop        equr    d2
  40. column_thisminy        equr    d3
  41. column_thismaxy        equr    d4
  42. column_thisbot        equr    d5
  43.  
  44. floor_tex        equr    d0
  45. floor_y1        equr    d1
  46. floor_y2        equr    d6
  47.  
  48. *-------------------------------------------------------*
  49. *    Custom program-flow macros            *
  50. *-------------------------------------------------------*
  51.  
  52. jsu    macro        ; call subunit & return to current location (non stackable)
  53.     ifd        customflow
  54.     lea        .r\@(pc),a1
  55.     bra        \1
  56.     elseif
  57.     bsr        \1
  58.     endc
  59. .r\@:
  60.     endm
  61.  
  62. jsur    macro        ; call subunit & return to distant location (non stackable)
  63.     ifd        customflow
  64.     lea        (\2)(pc),a1
  65.     bra        \1
  66.     elseif
  67.     bsr        \1
  68.     bra.s        \2
  69.     endc
  70. .r\@:
  71.     endm
  72.     
  73. rtu    macro        ; return from subunit
  74.     ifd        customflow
  75.     jmp        (a1)
  76.     elseif
  77.     rts
  78.     endc
  79.     endm
  80.  
  81. advance    macro
  82.     moveq        #0,d6
  83.     move.w        addwall_ysize(a6),d6
  84.     move.w        addwall_y1a(a6),column_thistop
  85.     move.l        addwall_y1i(a6),d0
  86.     ext.l        column_thistop
  87.     bpl.s        .tc1
  88.     moveq        #0,column_thistop
  89. .tc1:    add.l        d0,addwall_y1a(a6)
  90.     move.w        addwall_y2a(a6),column_thisbot
  91.     move.l        addwall_y2i(a6),d0
  92.     ext.l        column_thisbot
  93.     cmp.l        column_thisminy,column_thisbot
  94.     bpl.s        .bc1
  95.     move.l        column_thisminy,column_thisbot
  96. .bc1:    add.l        d0,addwall_y2a(a6)
  97.     cmp.l        column_thismaxy,column_thistop
  98.     bmi.s        .tc2
  99.     move.l        column_thismaxy,column_thistop
  100. .tc2:    cmp.l        d6,column_thisbot
  101.     bmi.s        .bc2
  102.     move.l        d6,column_thisbot
  103. .bc2:
  104.     endm
  105.  
  106. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  107. *    Generate a new wall, floor & ceiling chunk    *
  108. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  109. AddWall:pea        (a3)
  110.     pea        (a4)
  111. *-------------------------------------------------------*
  112.     move.w        wallruncount,addwall_runs(a6)
  113.     move.w        columns,addwall_columns(a6)
  114. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  115. *    Vertical (y) perspective projection        *
  116. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  117. *    y' = y * ( (w/2) / z ) + (h/2)            *
  118. *-------------------------------------------------------*
  119.     moveq        #0,d6
  120.     move.w        addwall_ysize(a6),d6
  121.     moveq        #0,d0
  122.     move.w        addwall_xsize(a6),d0
  123.     lsr.w        d0            ; (w/2)
  124.     lsr.w        d6            ; (h/2)
  125.     move.l        addwall_y1(a6),d1
  126.     swap        d0
  127.     swap        d6
  128.     move.l        d0,d2
  129.     muls.l        d1,d7:d2
  130.     divs.l        addwall_z1(a6),d7:d2
  131.     add.l        d6,d2
  132.     move.l        d0,d5
  133.     muls.l        d1,d7:d5
  134.     divs.l        addwall_z2(a6),d7:d5
  135.     move.l        addwall_y2(a6),d1
  136.     add.l        d6,d5
  137.     move.l        d0,d3
  138.     muls.l        d1,d7:d3
  139.     divs.l        addwall_z1(a6),d7:d3
  140.     add.l        d6,d3
  141.     move.l        d0,d4
  142.     muls.l        d1,d7:d4
  143.     divs.l        addwall_z2(a6),d7:d4
  144.     add.l        d6,d4
  145. *-------------------------------------------------------*
  146. *    Calculate dy1 & dy2 gradients            *    
  147. *-------------------------------------------------------*
  148. .flip:    move.l        addwall_i2(a6),d0
  149.     sub.l        addwall_i1(a6),d0
  150.     sub.l        d2,d5
  151.     swap        d5
  152.     move.w        d5,d6
  153.     ext.l        d6
  154.     move.w        addwall_i1(a6),d7
  155.     clr.w        d5
  156.     divs.l        d0,d6:d5    ; dy1 = (ry1-ly1) / (x2-x1)
  157.     move.l        d4,d1
  158.     sub.l        d3,d1
  159.     swap        d1
  160.     move.w        d1,d6
  161.     ext.l        d6
  162.     clr.w        d1
  163.     divs.l        d0,d6:d1    ; dy2 = (ry2-ly2) / (x2-x1)
  164. *-------------------------------------------------------*
  165. *    Clip wall against left edge            *    
  166. *-------------------------------------------------------*
  167.     ext.l        d7
  168.     bpl.s        .nolc
  169.     move.l        d7,d6
  170.     muls.l        d5,d6
  171.     sub.l        d6,d2        ; y1 = y1 - (x1*dy1)
  172.     move.l        d7,d6
  173.     muls.l        d1,d6
  174.     sub.l        d6,d3        ; y2 = y2 - (x1*dy2)
  175.     moveq        #0,d7
  176. *-------------------------------------------------------*
  177. *    Load results into local loop registers        *    
  178. *-------------------------------------------------------*
  179. .nolc:    move.l        d2,addwall_y1a(a6)
  180.     move.l        d3,addwall_y2a(a6)
  181.     move.l        d5,addwall_y1i(a6)
  182.     move.l        d1,addwall_y2i(a6)
  183. *-------------------------------------------------------*
  184. *    Clip wall against right edge            *
  185. *-------------------------------------------------------*
  186.     move.w        addwall_i2(a6),d6
  187.     move.w        addwall_xsize(a6),d0
  188.     cmp.w        d0,d6
  189.     bmi.s        .x2in
  190.     move.w        d0,d6
  191. .x2in:    move.w        d6,addwall_ci2(a6)
  192. *-------------------------------------------------------*
  193. *    Prefetch column history registers        *
  194. *-------------------------------------------------------*
  195.     lea        miny,a0
  196.     move.w        (a0,d7.l*2),column_lastminy
  197.     moveq        #0,column_thisminy
  198.     lea        maxy,a0
  199.     move.w        (a0,d7.l*2),column_lastmaxy
  200.     moveq        #0,column_thismaxy
  201.     move.l        column_lastminy,column_lasttop
  202.     move.l        column_lastmaxy,column_lastbot
  203. *-------------------------------------------------------*
  204. *    Determine logic group for edge generation    *
  205. *-------------------------------------------------------*
  206.     cmp.b        #UPPER_TYPE,addwall_type(a6)
  207.     beq        AddUpperWall
  208.     cmp.b        #LOWER_TYPE,addwall_type(a6)
  209.     beq        AddLowerWall
  210.  
  211. *-------------------------------------------------------*
  212. AddMidWall:
  213. *-------------------------------------------------------*
  214. midwall_loop:
  215. *-------------------------------------------------------*
  216. *    Fetch vertical clipping bounds            *
  217. *-------------------------------------------------------*
  218.     lea        miny,a0
  219.     move.w        (a0,d7.l*2),column_thisminy
  220.     lea        maxy,a0
  221.     move.w        (a0,d7.l*2),column_thismaxy
  222. *-------------------------------------------------------*
  223. *    Advance edge accumulators            *
  224. *-------------------------------------------------------*
  225.     advance
  226. *-------------------------------------------------------*
  227. *    Generate floor buckets                *
  228. *-------------------------------------------------------*
  229.     cmp.l        column_thismaxy,column_thisbot
  230.     bpl.s        .clip_lower
  231. *-------------------------------------------------------*
  232.     cmp.l        column_lastbot,column_thisbot
  233.     bpl.s        .nf1
  234.     move.l        column_thisbot,floor_y1
  235.     move.l        column_lastbot,floor_y2
  236.     jsu        flat_leftedge
  237. .nf1:    cmp.l        column_thismaxy,column_lastmaxy
  238.     bpl.s        .nf2
  239.     move.l        column_lastmaxy,floor_y1
  240.     move.l        column_thismaxy,floor_y2
  241.     jsu        flat_leftedge
  242. .nf2:    cmp.l        column_lastbot,column_thisbot
  243.     ble.s        .nf3
  244.     move.l        column_lastbot,floor_y1
  245.     move.l        column_thisbot,floor_y2
  246.     move.w        addwall_fc(a6),floor_tex
  247.     jsu        flat_rightedge
  248. .nf3:    cmp.l        column_thismaxy,column_lastmaxy
  249.     ble.s        .floor_done
  250.     move.l        column_thismaxy,floor_y1
  251.     move.l        column_lastmaxy,floor_y2
  252.     move.w        addwall_fc(a6),floor_tex
  253.     jsur        flat_rightedge,.floor_done
  254. *-------------------------------------------------------*
  255. .clip_lower:
  256. *-------------------------------------------------------*
  257.     cmp.l        column_lastbot,column_lastmaxy
  258.     ble.s        .floor_done
  259.     move.l        column_lastbot,floor_y1
  260.     move.l        column_lastmaxy,floor_y2
  261.     move.w        addwall_fc(a6),floor_tex
  262.     jsu        flat_rightedge
  263. *-------------------------------------------------------*
  264. .floor_done:
  265. *-------------------------------------------------------*
  266. *    Generate ceiling buckets            *
  267. *-------------------------------------------------------*
  268.     cmp.l        column_thisminy,column_thistop
  269.     ble.s        .clip_upper
  270. *-------------------------------------------------------*
  271.     cmp.l        column_lasttop,column_thistop
  272.     ble.s        .nc1
  273.     move.l        column_lasttop,floor_y1
  274.     move.l        column_thistop,floor_y2
  275.     jsu        flat_leftedge
  276. .nc1:    cmp.l        column_thisminy,column_lastminy
  277.     ble.s        .nc2
  278.     move.l        column_thisminy,floor_y1
  279.     move.l        column_lastminy,floor_y2
  280.     jsu        flat_leftedge
  281. .nc2:    cmp.l        column_lasttop,column_thistop
  282.     bpl.s        .nc3
  283.     move.l        column_thistop,floor_y1
  284.     move.l        column_lasttop,floor_y2
  285.     move.w        addwall_cc(a6),floor_tex
  286.     jsu        flat_rightedge
  287. .nc3:    cmp.l        column_thisminy,column_lastminy
  288.     bpl.s        .ceiling_done
  289.     move.l        column_lastminy,floor_y1
  290.     move.l        column_thisminy,floor_y2
  291.     move.w        addwall_cc(a6),floor_tex
  292.     jsur        flat_rightedge,.ceiling_done
  293. *-------------------------------------------------------*
  294. .clip_upper:
  295. *-------------------------------------------------------*
  296.     cmp.l        column_lasttop,column_lastminy
  297.     bpl.s        .ceiling_done
  298.     move.l        column_lastminy,floor_y1
  299.     move.l        column_lasttop,floor_y2
  300.     move.w        addwall_cc(a6),floor_tex
  301.     jsu        flat_rightedge
  302. *-------------------------------------------------------*
  303. .ceiling_done:
  304. *-------------------------------------------------------*
  305. *    Rotate column history registers            *
  306. *-------------------------------------------------------*
  307.     move.l        column_thistop,column_lasttop 
  308.     move.l        column_thisbot,column_lastbot 
  309.     move.l        column_thisminy,column_lastminy 
  310.     move.l        column_thismaxy,column_lastmaxy 
  311. *-------------------------------------------------------*
  312. *    Check - column is already sealed off        *
  313. *-------------------------------------------------------*
  314.     cmp.l        column_thisminy,column_thismaxy 
  315.     ble        .skip
  316. *-------------------------------------------------------*
  317. *    Check - column below [maxy] - blocked by roof    *
  318. *-------------------------------------------------------*
  319.     cmp.l        column_thistop,column_thismaxy 
  320.     ble.s        .update_window
  321. *-------------------------------------------------------*
  322. *    Check - column above [miny] - blocked by floor    *
  323. *-------------------------------------------------------*
  324.     cmp.l        column_thisbot,column_thisminy 
  325.     bpl.s        .update_window
  326. *-------------------------------------------------------*
  327. *    Clip - top of column cropped by [miny]        *
  328. *-------------------------------------------------------*
  329.     cmp.l        column_thistop,column_thisminy 
  330.     ble.s        .ncl1
  331.     move.l        column_thisminy,column_thistop 
  332. *-------------------------------------------------------*
  333. *    Clip - bottom of column cropped by [maxy]    *
  334. *-------------------------------------------------------*
  335. .ncl1:    cmp.l        column_thisbot,column_thismaxy 
  336.     bpl.s        .ncl2
  337.     move.l        column_thismaxy,column_thisbot 
  338. *-------------------------------------------------------*
  339. *    Check - column cropped to zero length        *
  340. *-------------------------------------------------------*
  341. .ncl2:    cmp.l        column_thistop,column_thisbot 
  342.     ble.s        .update_window
  343. *-------------------------------------------------------*
  344. *    Column bucket generator                *
  345. *-------------------------------------------------------*
  346.     moveq        #0,d6
  347.     move.w        addwall_runs(a6),d6
  348.     lea        wallruns,a0
  349.     move.l        d6,d0
  350.     lsl.l        #3,d0
  351.     add.l        d0,a0
  352.     move.w        d7,d0
  353.     tst.b        addwall_opaque(a6)
  354.     beq.s        .solid
  355.     not.w        d0
  356. .solid:    move.w        addwall_tex(a6),wall_id(a0)
  357.     move.w        d0,wall_x(a0)
  358.     move.w        column_thistop,wall_y1(a0)
  359.     move.w        column_thisbot,wall_y2(a0)
  360.     addq        #1,d6
  361.     move.w        d6,addwall_runs(a6)
  362. *-------------------------------------------------------*
  363. *    Update vertical clipping bar            *
  364. *-------------------------------------------------------*
  365. .update_window:
  366. *-------------------------------------------------------*
  367.     tst.b        addwall_opaque(a6)
  368.     bne.s        .trans
  369.     moveq        #0,column_thisbot
  370.     move.w        addwall_ysize(a6),column_thistop
  371. .trans:    cmp.l        column_thistop,column_thisbot
  372.     bgt.s        .upd
  373.     lea        occlusion_list,a0
  374.     move.b        #0,(a0,d7.l)
  375.     subq.w        #1,addwall_columns(a6)
  376.     beq.s        .stop
  377. .upd:    lea        miny,a0
  378.     move.w        column_thistop,(a0,d7.l*2)
  379.     lea        maxy,a0
  380.     move.w        column_thisbot,(a0,d7.l*2)
  381. *-------------------------------------------------------*
  382. *    Advance to next column                *
  383. *-------------------------------------------------------*
  384. .skip:    addq.l        #1,d7
  385.     cmp.w        addwall_ci2(a6),d7
  386.     bmi        midwall_loop
  387.     bra.s        .done
  388. *-------------------------------------------------------*
  389. *    Premature termination                *
  390. *-------------------------------------------------------*
  391. .stop    addq.l        #1,d7
  392. *-------------------------------------------------------*
  393. *    Fill gaps left in floor & ceiling by edges    *
  394. *-------------------------------------------------------*
  395. .done:    cmp.l        column_lastbot,column_lastmaxy
  396.     ble.s        .nfl
  397.     move.l        column_lastbot,floor_y1
  398.     move.l        column_lastmaxy,floor_y2
  399.     move.w        addwall_fc(a6),floor_tex
  400.     jsu        flat_rightedge
  401. .nfl:    cmp.l        column_lasttop,column_lastminy
  402.     bpl.s        .ncl
  403.     move.l        column_lastminy,floor_y1
  404.     move.l        column_lasttop,floor_y2
  405.     move.w        addwall_cc(a6),floor_tex
  406.     jsu        flat_rightedge
  407. *-------------------------------------------------------*
  408. .ncl:    move.w        addwall_runs(a6),wallruncount
  409.     move.w        addwall_columns(a6),columns
  410.     pop.l        a4
  411.     pop.l        a3
  412.     rts
  413.  
  414. *-------------------------------------------------------*
  415. AddUpperWall:
  416. *-------------------------------------------------------*
  417. upperwall_loop:
  418. *-------------------------------------------------------*
  419. *    Fetch vertical clipping bounds            *
  420. *-------------------------------------------------------*
  421.     lea        miny,a0
  422.     move.w        (a0,d7.l*2),column_thisminy
  423.     lea        maxy,a0
  424.     move.w        (a0,d7.l*2),column_thismaxy
  425. *-------------------------------------------------------*
  426. *    Advance edge accumulators            *
  427. *-------------------------------------------------------*
  428.     advance
  429. *-------------------------------------------------------*
  430. *    Generate ceiling buckets            *
  431. *-------------------------------------------------------*
  432.     cmp.l        column_thisminy,column_thistop
  433.     ble.s        .clip_upper
  434. *-------------------------------------------------------*
  435.     cmp.l        column_lasttop,column_thistop
  436.     ble.s        .nc1
  437.     move.l        column_lasttop,floor_y1
  438.     move.l        column_thistop,floor_y2
  439.     jsu        flat_leftedge
  440. .nc1:    cmp.l        column_thisminy,column_lastminy
  441.     ble.s        .nc2
  442.     move.l        column_thisminy,floor_y1
  443.     move.l        column_lastminy,floor_y2
  444.     jsu        flat_leftedge
  445. .nc2:    cmp.l        column_lasttop,column_thistop
  446.     bpl.s        .nc3
  447.     move.l        column_thistop,floor_y1
  448.     move.l        column_lasttop,floor_y2
  449.     move.w        addwall_cc(a6),floor_tex
  450.     jsu        flat_rightedge
  451. .nc3:    cmp.l        column_thisminy,column_lastminy
  452.     bpl.s        .ceiling_done
  453.     move.l        column_lastminy,floor_y1
  454.     move.l        column_thisminy,floor_y2
  455.     move.w        addwall_cc(a6),floor_tex
  456.     jsur        flat_rightedge,.ceiling_done
  457. *-------------------------------------------------------*
  458. .clip_upper:
  459. *-------------------------------------------------------*
  460.     cmp.l        column_lasttop,column_lastminy
  461.     bpl.s        .ceiling_done
  462.     move.l        column_lastminy,floor_y1
  463.     move.l        column_lasttop,floor_y2
  464.     move.w        addwall_cc(a6),floor_tex
  465.     jsu        flat_rightedge
  466. *-------------------------------------------------------*
  467. .ceiling_done:
  468. *-------------------------------------------------------*
  469. *    Rotate column history registers            *
  470. *-------------------------------------------------------*
  471.     move.l        column_thistop,column_lasttop 
  472.     move.l        column_thisbot,column_lastbot 
  473.     move.l        column_thisminy,column_lastminy 
  474.     move.l        column_thismaxy,column_lastmaxy 
  475. *-------------------------------------------------------*
  476. *    Check - column is already sealed off        *
  477. *-------------------------------------------------------*
  478.     cmp.l        column_thisminy,column_thismaxy 
  479.     ble.s        .skip
  480. *-------------------------------------------------------*
  481. *    Check - column above [miny] - ignore it        *
  482. *-------------------------------------------------------*
  483.     cmp.l        column_thisbot,column_thisminy 
  484.     bpl.s        .skip
  485. *-------------------------------------------------------*
  486. *    Check - column below [maxy] - blocked by roof    *
  487. *-------------------------------------------------------*
  488.     cmp.l        column_thistop,column_thismaxy 
  489.     ble.s        .update_window
  490. *-------------------------------------------------------*
  491. *    Clip - top of column cropped by [miny]        *
  492. *-------------------------------------------------------*
  493.     cmp.l        column_thistop,column_thisminy 
  494.     ble.s        .ncl1
  495.     move.l        column_thisminy,column_thistop 
  496. *-------------------------------------------------------*
  497. *    Clip - bottom of column cropped by [maxy]    *
  498. *-------------------------------------------------------*
  499. .ncl1:    cmp.l        column_thisbot,column_thismaxy 
  500.     bpl.s        .ncl2
  501.     move.l        column_thismaxy,column_thisbot 
  502. *-------------------------------------------------------*
  503. *    Check - column cropped to zero length        *
  504. *-------------------------------------------------------*
  505. .ncl2:    cmp.l        column_thistop,column_thisbot 
  506.     ble.s        .update_window
  507. *-------------------------------------------------------*
  508. *    Column bucket generator                *
  509. *-------------------------------------------------------*
  510.     moveq        #0,d6
  511.     move.w        addwall_runs(a6),d6
  512.     lea        wallruns,a0
  513.     move.l        d6,d0
  514.     lsl.l        #3,d0
  515.     add.l        d0,a0
  516.     move.w        addwall_tex(a6),wall_id(a0)
  517.     move.w        d7,wall_x(a0)
  518.     move.w        column_thistop,wall_y1(a0)
  519.     move.w        column_thisbot,wall_y2(a0)
  520.     addq        #1,d6
  521.     move.w        d6,addwall_runs(a6)
  522. *-------------------------------------------------------*
  523. *    Update vertical clipping bar            *
  524. *-------------------------------------------------------*
  525. .update_window:
  526. *-------------------------------------------------------*
  527.     move.l        column_thisbot,d1
  528.     cmp.l        column_thismaxy,d1
  529.     blt.s        .upd
  530.     lea        occlusion_list,a0
  531.     move.b        #0,(a0,d7.l)
  532.     subq.w        #1,addwall_columns(a6)
  533.     beq.s        .stop
  534.     lea        maxy,a0
  535.     move.w        #0,(a0,d7.l*2)
  536.     move.w        addwall_ysize(a6),d1
  537. .upd:    lea        miny,a0
  538.     move.w        d1,(a0,d7.l*2)
  539. *-------------------------------------------------------*
  540. *    Advance to next column                *
  541. *-------------------------------------------------------*
  542. .skip:    addq.l        #1,d7
  543.     cmp.w        addwall_ci2(a6),d7
  544.     bmi        upperwall_loop
  545.     bra.s        .done
  546. *-------------------------------------------------------*
  547. *    Premature termination                *
  548. *-------------------------------------------------------*
  549. .stop    addq.l        #1,d7
  550. *-------------------------------------------------------*
  551. *    Fill gaps left in floor & ceiling by edges    *
  552. *-------------------------------------------------------*
  553. .done:    cmp.l        column_lasttop,column_lastminy
  554.     bpl.s        .ncl
  555.     move.l        column_lastminy,floor_y1
  556.     move.l        column_lasttop,floor_y2
  557.     move.w        addwall_cc(a6),floor_tex
  558.     jsu        flat_rightedge
  559. *-------------------------------------------------------*
  560. .ncl:    move.w        addwall_runs(a6),wallruncount
  561.     move.w        addwall_columns(a6),columns
  562.     pop.l        a4
  563.     pop.l        a3
  564.     rts
  565.  
  566. *-------------------------------------------------------*
  567. AddLowerWall:
  568. *-------------------------------------------------------*
  569. lowerwall_loop:
  570. *-------------------------------------------------------*
  571. *    Fetch vertical clipping bounds            *
  572. *-------------------------------------------------------*
  573.     lea        miny,a0
  574.     move.w        (a0,d7.l*2),column_thisminy
  575.     lea        maxy,a0
  576.     move.w        (a0,d7.l*2),column_thismaxy
  577. *-------------------------------------------------------*
  578. *    Advance edge accumulators            *
  579. *-------------------------------------------------------*
  580.     advance
  581. *-------------------------------------------------------*
  582. *    Generate floor buckets                *
  583. *-------------------------------------------------------*
  584.     cmp.l        column_thismaxy,column_thisbot
  585.     bpl.s        .clip_lower
  586. *-------------------------------------------------------*
  587.     cmp.l        column_lastbot,column_thisbot
  588.     bpl.s        .nf1
  589.     move.l        column_thisbot,floor_y1
  590.     move.l        column_lastbot,floor_y2
  591.     jsu        flat_leftedge
  592. .nf1:    cmp.l        column_thismaxy,column_lastmaxy
  593.     bpl.s        .nf2
  594.     move.l        column_lastmaxy,floor_y1
  595.     move.l        column_thismaxy,floor_y2
  596.     jsu        flat_leftedge
  597. .nf2:    cmp.l        column_lastbot,column_thisbot
  598.     ble.s        .nf3
  599.     move.l        column_lastbot,floor_y1
  600.     move.l        column_thisbot,floor_y2
  601.     move.w        addwall_fc(a6),floor_tex
  602.     jsu        flat_rightedge
  603. .nf3:    cmp.l        column_thismaxy,column_lastmaxy
  604.     ble.s        .floor_done
  605.     move.l        column_thismaxy,floor_y1
  606.     move.l        column_lastmaxy,floor_y2
  607.     move.w        addwall_fc(a6),floor_tex
  608.     jsur        flat_rightedge,.floor_done
  609. *-------------------------------------------------------*
  610. .clip_lower:
  611. *-------------------------------------------------------*
  612.     cmp.l        column_lastbot,column_lastmaxy
  613.     ble.s        .floor_done
  614.     move.l        column_lastbot,floor_y1
  615.     move.l        column_lastmaxy,floor_y2
  616.     move.w        addwall_fc(a6),floor_tex
  617.     jsu        flat_rightedge    
  618. *-------------------------------------------------------*
  619. .floor_done:
  620. *-------------------------------------------------------*
  621. *    Rotate column history registers            *
  622. *-------------------------------------------------------*
  623.     move.l        column_thistop,column_lasttop 
  624.     move.l        column_thisbot,column_lastbot 
  625.     move.l        column_thisminy,column_lastminy 
  626.     move.l        column_thismaxy,column_lastmaxy 
  627. *-------------------------------------------------------*
  628. *    Check - column is already sealed off        *
  629. *-------------------------------------------------------*
  630.     cmp.l        column_thisminy,column_thismaxy 
  631.     ble.s        .skip
  632. *-------------------------------------------------------*
  633. *    Check - column below [maxy] - ingore it        *
  634. *-------------------------------------------------------*
  635.     cmp.l        column_thistop,column_thismaxy 
  636.     ble.s        .skip
  637. *-------------------------------------------------------*
  638. *    Check - column above [miny] - blocked by floor    *
  639. *-------------------------------------------------------*
  640.     cmp.l        column_thisbot,column_thisminy 
  641.     bpl.s        .update_window
  642. *-------------------------------------------------------*
  643. *    Clip - top of column cropped by [miny]        *
  644. *-------------------------------------------------------*
  645.     cmp.l        column_thistop,column_thisminy 
  646.     ble.s        .ncl1
  647.     move.l        column_thisminy,column_thistop 
  648. *-------------------------------------------------------*
  649. *    Clip - bottom of column cropped by [maxy]    *
  650. *-------------------------------------------------------*
  651. .ncl1:    cmp.l        column_thisbot,column_thismaxy 
  652.     bpl.s        .ncl2
  653.     move.l        column_thismaxy,column_thisbot 
  654. *-------------------------------------------------------*
  655. *    Check - column cropped to zero length        *
  656. *-------------------------------------------------------*
  657. .ncl2:    cmp.l        column_thistop,column_thisbot 
  658.     ble.s        .update_window
  659. *-------------------------------------------------------*
  660. *    Column bucket generator                *
  661. *-------------------------------------------------------*
  662.     moveq        #0,d6
  663.     move.w        addwall_runs(a6),d6
  664.     lea        wallruns,a0
  665.     move.l        d6,d0
  666.     lsl.l        #3,d0
  667.     add.l        d0,a0
  668.     move.w        addwall_tex(a6),wall_id(a0)
  669.     move.w        d7,wall_x(a0)
  670.     move.w        column_thistop,wall_y1(a0)
  671.     move.w        column_thisbot,wall_y2(a0)
  672.     addq        #1,d6
  673.     move.w        d6,addwall_runs(a6)
  674. *-------------------------------------------------------*
  675. *    Update vertical clipping bar            *
  676. *-------------------------------------------------------*
  677. .update_window:
  678. *-------------------------------------------------------*
  679.     move.l        column_thistop,d6
  680.     cmp.l        column_thisminy,d6
  681.     bgt.s        .upd
  682.     lea        occlusion_list,a0
  683.     move.b        #0,(a0,d7.l)
  684.     subq.w        #1,addwall_columns(a6)
  685.     beq.s        .stop
  686.     lea        miny,a0
  687.     move.w        addwall_ysize(a6),(a0,d7.l*2)
  688.     moveq        #0,d6
  689. .upd:    lea        maxy,a0
  690.     move.w        d6,(a0,d7.l*2)
  691. *-------------------------------------------------------*
  692. *    Advance to next column                *
  693. *-------------------------------------------------------*
  694. .skip:    addq.l        #1,d7
  695.     cmp.w        addwall_ci2(a6),d7
  696.     bmi        lowerwall_loop
  697.     bra.s        .done
  698. *-------------------------------------------------------*
  699. *    Premature termination                *
  700. *-------------------------------------------------------*
  701. .stop    addq.l        #1,d7
  702. *-------------------------------------------------------*
  703. *    Fill gaps left in floor & ceiling by edges    *
  704. *-------------------------------------------------------*
  705. .done:    cmp.l        column_lastbot,column_lastmaxy
  706.     ble.s        .nfl
  707.     move.l        column_lastbot,floor_y1
  708.     move.l        column_lastmaxy,floor_y2
  709.     move.w        addwall_fc(a6),floor_tex
  710.     jsu        flat_rightedge
  711. *-------------------------------------------------------*
  712. .nfl:    move.w        addwall_runs(a6),wallruncount
  713.     move.w        addwall_columns(a6),columns
  714.     pop.l        a4
  715.     pop.l        a3
  716.     rts
  717.  
  718. *-------------------------------------------------------*
  719. *    Generate left edges of [dy] 'flats'.        *
  720. *-------------------------------------------------------*
  721. flat_leftedge:
  722. *-------------------------------------------------------*
  723.     rept        1
  724.     sub.l        d1,d6
  725.     subq.l        #1,d6                ; number of flat runs needed
  726.     lea        flatruncounts,a0
  727.     add.l        d1,a0
  728.     add.l        d1,a0
  729.     moveq        #0,d0
  730.     move.w        #(flat_len*max_xint),d0
  731.     lsl.l        #8,d1
  732.     add.l        d1,d1                ; 8+1 = 6+3 = 64*8 = flat_len*max_xint
  733. *    mulu.w        d0,d1
  734.     sub.l        d0,d1
  735.     lea        flatruns,a6
  736.     add.l        d1,a6                ; flatruns+(runsize*(runs-1))
  737.     moveq        #0,d1
  738. .vert:    move.w        (a0)+,d1            ; fetch bucket count for this row.
  739.     add.l        d0,a6                ; advance to next row in bucket buffer.
  740.     move.w        d7,flat_x1(a6,d1.l*flat_len)    ; store X1 @ (row+(count*size)).
  741.     dbra        d6,.vert
  742. .exit:    lea        addwall_struct,a6        ; we must restore a6 after trashing it
  743.     endr
  744.     rtu
  745.     
  746. *-------------------------------------------------------*
  747. *    Generate right edges of [dy] 'flats'.        *
  748. *-------------------------------------------------------*
  749. flat_rightedge:
  750. *-------------------------------------------------------*
  751.     rept        1
  752.     sub.l        d1,d6
  753.     push.l        d4
  754.     subq.l        #1,d6                ; number of flat runs needed
  755.     lea        flatruncounts,a0 
  756.     add.l        d1,a0
  757.     add.l        d1,a0
  758.     moveq        #0,d4
  759.     move.w        #(flat_len*max_xint),d4
  760.     lsl.l        #8,d1
  761.     add.l        d1,d1                ; 8+1 = 6+3 = 64*8 = flat_len*max_xint
  762. *    mulu.w        d4,d1
  763.     lea        flatruns,a6
  764.     add.l        d1,a6
  765.     sub.l        d4,a6                ; flatruns + (runsize*(runs-1))
  766.     swap        d0
  767.     move.w        d7,d0                ; merge X2 & texture-ID
  768.     moveq        #0,d1
  769. .vert:    move.w        (a0),d1                ; fetch bucket count for this row.
  770.     add.l        d4,a6                ; advance to next row in bucket buffer.
  771.     addq.w        #1,(a0)+            ; increment bucket count and move on.
  772.     move.l        d0,(a6,d1.l*flat_len)        ; store texture-ID & X2 @ (row+(count*size)).
  773.     dbra        d6,.vert
  774. .exit:    pop.l        d4
  775.     lea        addwall_struct,a6        ; we must restore a6 after trashing it
  776.     endr
  777.     rtu
  778.  
  779. *-------------------------------------------------------*
  780.             bss
  781. *-------------------------------------------------------*
  782.  
  783. addwall_struct:        ds.b    addwall_len        ; local variables for AddWall.
  784.  
  785. columns:        ds.w    1            ; counter for columns done.
  786.  
  787. occlusion_list:        ds.b    320            ; byte-per-column occlusion list.
  788.  
  789. maxy:            ds.w    320            ; upper clipping buffer.
  790. miny:            ds.w    320            ; lower clipping buffer.
  791.  
  792. wallruncount:        ds.w    1            ; counter for total wall runs.
  793. flatruncounts:        ds.w    200            ; word-per-row counters for flat runs.
  794.  
  795. flatruns:        ds.b    (200*max_xint*flat_len)    ; floor buckets (rows*buckets*bucketsize).
  796. wallruns:        ds.b    (maxwallruns*wall_len)    ; wall buckets (maxwallruns*bucketsize).
  797.  
  798. *-------------------------------------------------------*
  799.             text
  800. *-------------------------------------------------------*
  801.  
  802.