home *** CD-ROM | disk | FTP | other *** search
/ 100 af Verdens Bedste Spil / 100Spil.iso / dos / wolf3d / source / wolfsrc.1 / WL_DR_A.ASM < prev    next >
Assembly Source File  |  1993-02-04  |  15KB  |  740 lines

  1.     IDEAL
  2.     MODEL    MEDIUM,C
  3.     P286
  4.  
  5. SCREENSEG    =    0a000h
  6.  
  7. FINEANGLES    =    3600
  8. DEG90        =    900
  9. DEG180        =    1800
  10. DEG270        =    2700
  11. DEG360        =    3600
  12.  
  13. OP_JLE        =    07eh
  14. OP_JGE        =    07dh
  15.  
  16. EXTRN    finetangent:DWORD    ; far array, starts at offset 0
  17.  
  18. EXTRN    HitHorizWall:FAR
  19. EXTRN    HitVertWall:FAR
  20. EXTRN    HitHorizDoor:FAR
  21. EXTRN    HitVertDoor:FAR
  22. EXTRN    HitHorizPWall:FAR
  23. EXTRN    HitVertPWall:FAR
  24.  
  25.  
  26. DATASEG
  27.  
  28. EXTRN    viewwidth:WORD
  29.  
  30. EXTRN    tilemap:BYTE
  31. EXTRN    spotvis:BYTE
  32. EXTRN    pixelangle:WORD
  33.  
  34.  
  35. EXTRN    midangle:WORD
  36. EXTRN    angle:WORD
  37.  
  38. EXTRN    focaltx:WORD
  39. EXTRN    focalty:WORD
  40. EXTRN    viewtx:WORD
  41. EXTRN    viewty:WORD
  42. EXTRN    viewx:DWORD
  43. EXTRN    viewy:DWORD
  44.  
  45. EXTRN    xpartialup:WORD
  46. EXTRN    ypartialup:WORD
  47. EXTRN    xpartialdown:WORD
  48. EXTRN    ypartialdown:WORD
  49.  
  50. EXTRN    tilehit:WORD
  51. EXTRN    pixx:WORD
  52. EXTRN    wallheight:WORD            ; array of VIEWWIDTH entries
  53.  
  54. EXTRN    xtile:WORD
  55. EXTRN    ytile:WORD
  56. EXTRN    xtilestep:WORD
  57. EXTRN    ytilestep:WORD
  58. EXTRN    xintercept:DWORD
  59. EXTRN    yintercept:DWORD
  60. EXTRN    xstep:DWORD
  61. EXTRN    ystep:DWORD
  62.  
  63. EXTRN    doorposition:WORD        ; table of door position values
  64.  
  65.  
  66. EXTRN    pwallpos:WORD            ; amound a pushable wall has been moved
  67.  
  68. CODESEG
  69.  
  70. ;-------------------
  71. ;
  72. ; xpartialbyystep
  73. ;
  74. ; multiplies long [ystep] (possibly negative), by word [xpartial] (in BX)
  75. ;
  76. ; returns dx:ax
  77. ; trashes bx,cx,di
  78. ;
  79. ;-------------------
  80.  
  81. PROC xpartialbyystep NEAR
  82. ;
  83. ; setup
  84. ;
  85.     mov    ax,[WORD ystep]
  86.     mov    cx,[WORD ystep+2]
  87.     or    cx,cx               ; is ystep negatice?
  88.     jns    @@multpos
  89. ;
  90. ; multiply negative cx:ax by bx
  91. ;
  92.     neg    cx
  93.     neg    ax
  94.     sbb    cx,0
  95.  
  96.     mul    bx                    ; fraction*fraction
  97.     mov    di,dx                ; di is low word of result
  98.     mov    ax,cx                ;
  99.     mul    bx                    ; units*fraction
  100.     add    ax,di
  101.     adc    dx,0
  102.  
  103.     neg    dx
  104.     neg    ax
  105.     sbb    dx,0
  106.     ret
  107. ;
  108. ; multiply positive cx:ax by bx
  109. ;
  110. EVEN
  111. @@multpos:
  112.     mul    bx                    ; fraction*fraction
  113.     mov    di,dx                ; di is low word of result
  114.     mov    ax,cx                ;
  115.     mul    bx                    ; units*fraction
  116.     add    ax,di
  117.     adc    dx,0
  118.  
  119.     ret
  120.  
  121. ENDP
  122.  
  123.  
  124.  
  125. ;-------------------
  126. ;
  127. ; ypartialbyxstep
  128. ;
  129. ; multiplies long [xstep] (possibly negative), by word [ypartial] (in BP)
  130. ;
  131. ; returns dx:ax
  132. ; trashes cx,di,bp
  133. ;
  134. ;-------------------
  135.  
  136. PROC ypartialbyxstep NEAR
  137. ;
  138. ; setup
  139. ;
  140.     mov    ax,[WORD xstep]
  141.     mov    cx,[WORD xstep+2]
  142.     or    cx,cx               ; is ystep negatice?
  143.     jns    @@multpos
  144. ;
  145. ; multiply negative cx:ax by bx
  146. ;
  147.     neg    cx
  148.     neg    ax
  149.     sbb    cx,0
  150.  
  151.     mul    bp                    ; fraction*fraction
  152.     mov    di,dx                ; di is low word of result
  153.     mov    ax,cx                ;
  154.     mul    bp                    ; units*fraction
  155.     add    ax,di
  156.     adc    dx,0
  157.  
  158.     neg    dx
  159.     neg    ax
  160.     sbb    dx,0
  161.     ret
  162. ;
  163. ; multiply positive cx:ax by bx
  164. ;
  165. EVEN
  166. @@multpos:
  167.     mul    bp                    ; fraction*fraction
  168.     mov    di,dx                ; di is low word of result
  169.     mov    ax,cx                ;
  170.     mul    bp                    ; units*fraction
  171.     add    ax,di
  172.     adc    dx,0
  173.     ret
  174.  
  175. ENDP
  176.  
  177.  
  178. ;============================
  179. ;
  180. ; AsmRefresh
  181. ;
  182. ;
  183. ;============================
  184.  
  185. PROC    AsmRefresh
  186. PUBLIC    AsmRefresh
  187.  
  188.     push    si
  189.     push    di
  190.     push    bp
  191.  
  192.     mov    [pixx],0
  193. ;---------------------------------------------------------------------------
  194. ;
  195. ; Setup to trace a ray through pixx view pixel
  196. ;
  197. ; CX : angle of the ray through pixx
  198. ; ES : points to segment of finetangent array for this block of code
  199. ;
  200. ; Upon entrance to initialize block
  201. ;
  202. ; BX : xpartial
  203. ; BP : ypartial
  204. ;
  205. ;---------------------------------------------------------------------------
  206.     EVEN
  207. pixxloop:
  208.     mov    ax,SEG finetangent
  209.     mov    es,ax
  210.     mov    cx,[midangle]            ; center of view area
  211.     mov    bx,[pixx]
  212.     shl    bx,1
  213.     add    cx,[pixelangle+bx]        ; delta for this pixel
  214.     cmp    cx,0
  215.     jge    not0
  216. ;----------
  217. ;
  218. ; -90 - -1 degree arc
  219. ;
  220. ;----------
  221.     add    cx,FINEANGLES            ; -90 is the same as 270
  222.     jmp    entry360
  223.  
  224. not0:
  225.     cmp    cx,DEG90
  226.     jge    not90
  227. ;----------
  228. ;
  229. ; 0-89 degree arc
  230. ;
  231. ;----------
  232. entry90:
  233.     mov    [xtilestep],1            ; xtilestep = 1
  234.     mov    [ytilestep],-1            ; ytilestep = -1
  235.     mov    [BYTE cs:horizop],OP_JGE    ; patch a jge in
  236.     mov    [BYTE cs:vertop],OP_JLE        ; patch a jle in
  237.     mov    bx,DEG90-1
  238.     sub    bx,cx
  239.     shl    bx,2
  240.     mov    ax,[es:bx]
  241.     mov    dx,[es:bx+2]
  242.     mov    [WORD xstep],ax
  243.     mov    [WORD xstep+2],dx        ; xstep = finetangent[DEG90-1-angle]
  244.     mov    bx,cx
  245.     shl    bx,2
  246.     mov    ax,[es:bx]
  247.     mov    dx,[es:bx+2]
  248.     neg    dx
  249.     neg    ax
  250.     sbb    dx,0
  251.     mov    [WORD ystep],ax
  252.     mov    [WORD ystep+2],dx        ; ystep = -finetangent[angle]
  253.  
  254.     mov    bx,[xpartialup]            ; xpartial = xpartialup
  255.     mov    bp,[ypartialdown]        ; ypartial = ypartialdown
  256.     jmp    initvars
  257.  
  258. not90:
  259.     cmp    cx,DEG180
  260.     jge    not180
  261. ;----------
  262. ;
  263. ; 90-179 degree arc
  264. ;
  265. ;----------
  266.     mov    ax,-1
  267.     mov    [xtilestep],ax            ; xtilestep = -1
  268.     mov    [ytilestep],ax            ; ytilestep = -1
  269.     mov    [BYTE cs:horizop],OP_JLE    ; patch a jle in
  270.     mov    [BYTE cs:vertop],OP_JLE        ; patch a jle in
  271.  
  272.     mov    bx,cx
  273.     shl    bx,2
  274.     mov    ax,[es:bx-DEG90*4]
  275.     mov    dx,[es:bx+2-DEG90*4]
  276.     neg    dx
  277.     neg    ax
  278.     sbb    dx,0
  279.     mov    [WORD xstep],ax
  280.     mov    [WORD xstep+2],dx        ; xstep = -finetangent[angle-DEG90]
  281.     mov    bx,DEG180-1
  282.     sub    bx,cx
  283.     shl    bx,2
  284.     mov    ax,[es:bx]
  285.     mov    dx,[es:bx+2]
  286.     neg    dx
  287.     neg    ax
  288.     sbb    dx,0
  289.     mov    [WORD ystep],ax
  290.     mov    [WORD ystep+2],dx        ; ystep = -finetangent[DEG180-1-angle]
  291.  
  292.     mov    bx,[xpartialdown]        ; xpartial = xpartialdown
  293.     mov    bp,[ypartialdown]        ; ypartial = ypartialdown
  294.     jmp    initvars
  295.  
  296. not180:
  297.     cmp    cx,DEG270
  298.     jge    not270
  299. ;----------
  300. ;
  301. ; 180-269 degree arc
  302. ;
  303. ;----------
  304.     mov    [xtilestep],-1            ; xtilestep = -1
  305.     mov    [ytilestep],1            ; ytilestep = 1
  306.     mov    [BYTE cs:horizop],OP_JLE    ; patch a jle in
  307.     mov    [BYTE cs:vertop],OP_JGE        ; patch a jge in
  308.  
  309.     mov    bx,DEG270-1
  310.     sub    bx,cx
  311.     shl    bx,2
  312.     mov    ax,[es:bx]
  313.     mov    dx,[es:bx+2]
  314.     neg    dx
  315.     neg    ax
  316.     sbb    dx,0
  317.     mov    [WORD xstep],ax
  318.     mov    [WORD xstep+2],dx        ; xstep = -finetangent[DEG270-1-angle]
  319.     mov    bx,cx
  320.     shl    bx,2
  321.     mov    ax,[es:bx-DEG180*4]
  322.     mov    dx,[es:bx+2-DEG180*4]
  323.     mov    [WORD ystep],ax
  324.     mov    [WORD ystep+2],dx        ; ystep = finetangent[angle-DEG180]
  325.  
  326.     mov    bx,[xpartialdown]        ; xpartial = xpartialdown
  327.     mov    bp,[ypartialup]            ; ypartial = ypartialup
  328.     jmp    initvars
  329.  
  330.  
  331. not270:
  332.     cmp    cx,DEG360
  333.     jge    not360
  334. ;----------
  335. ;
  336. ; 270-359 degree arc
  337. ;
  338. ;----------
  339. entry360:
  340.     mov    ax,1
  341.     mov    [xtilestep],ax            ; xtilestep = 1
  342.     mov    [ytilestep],ax            ; ytilestep = 1
  343.     mov    [BYTE cs:horizop],OP_JGE    ; patch a jge in
  344.     mov    [BYTE cs:vertop],OP_JGE        ; patch a jge in
  345.  
  346.     mov    bx,cx
  347.     shl    bx,2
  348.     mov    ax,[es:bx-DEG270*4]
  349.     mov    dx,[es:bx+2-DEG270*4]
  350.     mov    [WORD xstep],ax
  351.     mov    [WORD xstep+2],dx        ; xstep = finetangent[angle-DEG270]
  352.     mov    bx,DEG360-1
  353.     sub    bx,cx
  354.     shl    bx,2
  355.     mov    ax,[es:bx]
  356.     mov    dx,[es:bx+2]
  357.     mov    [WORD ystep],ax
  358.     mov    [WORD ystep+2],dx        ; ystep = finetangent[DEG360-1-angle]
  359.  
  360.     mov    bx,[xpartialup]            ; xpartial = xpartialup
  361.     mov    bp,[ypartialup]            ; ypartial = ypartialup
  362.     jmp    initvars
  363.  
  364.  
  365. not360:
  366. ;----------
  367. ;
  368. ; 360-449 degree arc
  369. ;
  370. ;----------
  371.     sub    cx,FINEANGLES            ; -449 is the same as 89
  372.     jmp    entry90
  373.  
  374. ;---------------------------------------------------------------------------
  375. ;
  376. ; initialise variables for intersection testing
  377. ;
  378. ;---------------------------------------------------------------------------
  379. initvars:
  380.     call    NEAR xpartialbyystep    ; xpartial is in BX
  381.     add    ax,[WORD viewy]
  382.     adc    dx,[WORD viewy+2]
  383.     mov    [WORD yintercept],ax
  384.     mov    [WORD yintercept+2],dx
  385.  
  386.     mov    si,[focaltx]
  387.     add    si,[xtilestep]
  388.     mov    [xtile],si                    ; xtile = focaltx+xtilestep
  389.     shl    si,6
  390.     add    si,dx                        ; xspot = (xtile<<6) + yinttile
  391.  
  392.  
  393.     call    NEAR ypartialbyxstep    ; ypartial is in BP
  394.     add    ax,[WORD viewx]
  395.     adc    dx,[WORD viewx+2]
  396.     mov    [WORD xintercept],ax
  397.     mov    cx,dx
  398.  
  399.     mov    bx,[focalty]
  400.     add    bx,[ytilestep]
  401.     mov    bp,bx                        ; ytile = focalty+ytilestep
  402.     mov    di,dx
  403.     shl    di,6
  404.     add    di,bx                        ; yspot = (xinttile<<6) + ytile
  405.  
  406.     mov    bx,[xtile]
  407.     mov    dx,[WORD yintercept+2]
  408.     mov    ax,SCREENSEG
  409.     mov    es,ax                        ; faster than mov es,[screenseg]
  410.  
  411.  
  412. ;---------------------------------------------------------------------------
  413. ;
  414. ; trace along this angle until we hit a wall
  415. ;
  416. ; CORE LOOP!
  417. ;
  418. ; All variables are killed when a wall is hit
  419. ;
  420. ; AX : scratch
  421. ; BX : xtile
  422. ; CX : high word of xintercept
  423. ; DX : high word of yintercept
  424. ; SI : xspot (yinttile<<6)+xtile (index into tilemap and spotvis)
  425. ; DI : yspot (xinttile<<6)+ytile (index into tilemap and spotvis)
  426. ; BP : ytile
  427. ; ES : screenseg
  428. ;
  429. ;---------------------------------------------------------------------------
  430.  
  431. ;-----------
  432. ;
  433. ; check intersections with vertical walls
  434. ;
  435. ;-----------
  436.  
  437.     EVEN
  438. vertcheck:
  439.     cmp    dx,bp
  440. vertop:                                ; 0x7e = jle (ytilestep==-1)
  441.     jle    horizentry                    ; 0x7d = jge (ytilestep==1)
  442. vertentry:
  443.     test [BYTE tilemap+si],0ffh        ; tilehit = *((byte *)tilemap+xspot);
  444.     jnz    hitvert
  445. passvert:
  446.     mov    [BYTE spotvis+si],1            ; *((byte *)spotvis+xspot) = true;
  447.     add    bx,[xtilestep]                ; xtile+=xtilestep
  448.     mov    ax,[WORD ystep]
  449.     add    [WORD yintercept],ax        ; yintercept += ystep
  450.     adc    dx,[WORD ystep+2]
  451.     mov    si,bx
  452.     shl    si,6
  453.     add    si,dx                        ; xspot = (xtile<<6)+yinttile
  454.     jmp    vertcheck
  455.  
  456.     EVEN
  457. hitvert:
  458.     mov    al,[BYTE tilemap+si]        ; tilehit = *((byte *)tilemap+xspot);
  459.     mov    [BYTE tilehit],al
  460.     or    al,al                        ; set flags
  461.     jns    notvertdoor
  462.     jmp    vertdoor
  463. notvertdoor:
  464.     mov    [WORD xintercept],0
  465.     mov    [WORD xintercept+2],bx
  466.     mov    [xtile],bx
  467.     mov    [WORD yintercept+2],dx
  468.     mov    [ytile],dx
  469.     call FAR HitVertWall
  470.     jmp nextpix
  471.  
  472.  
  473. ;-----------
  474. ;
  475. ; check intersections with horizontal walls
  476. ;
  477. ;-----------
  478.     EVEN
  479. horizcheck:
  480.     cmp    cx,bx
  481. horizop:                            ; 0x7e = jle (xtilestep==-1)
  482.     jle    vertentry                    ; 0x7d = jge (xtilestep==1)
  483. horizentry:
  484.     test [BYTE tilemap+di],0ffh        ; tilehit = *((byte *)tilemap+yspot);
  485.     jnz    hithoriz
  486. passhoriz:
  487.     mov    [BYTE spotvis+di],1            ; *((byte *)spotvis+yspot) = true;
  488.     add    bp,[ytilestep]                ; ytile+=ytilestep
  489.     mov    ax,[WORD xstep]
  490.     add    [WORD xintercept],ax        ; xintercept += xstep
  491.     adc    cx,[WORD xstep+2]
  492.     mov    di,cx
  493.     shl    di,6
  494.     add    di,bp                        ; yspot = (xinttile<<6)+ytile
  495.     jmp    horizcheck
  496.  
  497.     EVEN
  498. hithoriz:
  499.     mov    al,[BYTE tilemap+di]        ; tilehit = *((byte *)tilemap+yspot);
  500.     mov    [BYTE tilehit],al
  501.     or    al,al                        ; set flags
  502.     js    horizdoor
  503.     mov    [WORD xintercept+2],cx
  504.     mov    [xtile],cx
  505.     mov    [WORD yintercept],0
  506.     mov    [WORD yintercept+2],bp
  507.     mov    [ytile],bp
  508.     call FAR HitHorizWall
  509.     jmp nextpix
  510.  
  511. ;---------------------------------------------------------------------------
  512. ;
  513. ; next pixel over
  514. ;
  515. ;---------------------------------------------------------------------------
  516.  
  517. nextpix:
  518.     mov    ax,[pixx]
  519.     inc    ax
  520.     mov    [pixx],ax
  521.     cmp    ax,[viewwidth]
  522.     jge    done
  523.     jmp    pixxloop
  524. done:
  525.     pop    bp
  526.     pop    di
  527.     pop    si
  528.     retf
  529.  
  530. ;===========================================================================
  531.  
  532. ;=============
  533. ;
  534. ; hit a special horizontal wall, so find which coordinate a door would be
  535. ; intersected at, and check to see if the door is open past that point
  536. ;
  537. ;=============
  538. horizdoor:
  539.     mov    [xtile],bx                    ; save off live register variables
  540.     mov    [WORD yintercept+2],dx
  541.  
  542.     test al,040h                      ; both high bits set == pushable wall
  543.     jnz    horizpushwall
  544.  
  545.     mov    bx,ax
  546.     and    bx,7fh                        ; strip high bit
  547.     shl    bx,1                        ; index into word width door table
  548.  
  549.     mov    ax,[WORD xstep]
  550.     mov    dx,[WORD xstep+2]
  551.     sar    dx,1
  552.     rcr ax,1                        ; half a step gets to door position
  553.  
  554.     add    ax,[WORD xintercept]        ; add half step to current intercept pos
  555.     adc    dx,cx                        ; CX hold high word of xintercept
  556.  
  557.     cmp    cx,dx                        ; is it still in the same tile?
  558.     je    hithmid
  559. ;
  560. ; midpoint is outside tile, so it hit the side of the wall before a door
  561. ;
  562. continuehoriz:
  563.     mov    bx,[xtile]                    ; reload register variables
  564.     mov    dx,[WORD yintercept+2]
  565.     jmp    passhoriz                    ; continue tracing
  566. ;
  567. ; the trace hit the door plane at pixel position AX, see if the door is
  568. ; closed that much
  569. ;
  570. hithmid:
  571.     cmp    ax,[doorposition+bx]        ; position of leading edge of door
  572.     jb    continuehoriz
  573. ;
  574. ; draw the door
  575. ;
  576.     mov    [WORD xintercept],ax        ; save pixel intercept position
  577.     mov    [WORD xintercept+2],cx
  578.  
  579.     mov    [WORD yintercept],8000h        ; intercept in middle of tile
  580.     mov    [WORD yintercept+2],bp
  581.  
  582.     call    FAR HitHorizDoor
  583.     jmp    nextpix
  584.  
  585. ;============
  586. ;
  587. ; hit a sliding horizontal wall
  588. ;
  589. ;============
  590.  
  591. horizpushwall:
  592.     mov    ax,[WORD xstep+2]            ; multiply xstep by pwallmove (0-63)
  593.     mul    [pwallpos]
  594.     mov    bx,ax
  595.     mov    ax,[WORD xstep]
  596.     mul    [pwallpos]
  597.     add    dx,bx
  598.  
  599.     sar    dx,1                        ; then divide by 64 to accomplish a
  600.     rcr ax,1                        ; fixed point multiplication
  601.     sar    dx,1
  602.     rcr ax,1
  603.     sar    dx,1
  604.     rcr ax,1
  605.     sar    dx,1
  606.     rcr ax,1
  607.     sar    dx,1
  608.     rcr ax,1
  609.     sar    dx,1
  610.     rcr ax,1
  611.  
  612.     add    ax,[WORD xintercept]        ; add partial step to current intercept
  613.     adc    dx,cx                        ; CX hold high word of xintercept
  614.  
  615.     cmp    cx,dx                        ; is it still in the same tile?
  616.     jne    continuehoriz                ; no, it hit the side
  617.  
  618. ;
  619. ; draw the pushable wall at the new height
  620. ;
  621.     mov    [WORD xintercept],ax        ; save pixel intercept position
  622.     mov    [WORD xintercept+2],dx
  623.  
  624.     mov    [WORD yintercept+2],bp
  625.     mov    [WORD yintercept],0
  626.  
  627.     call    FAR HitHorizPWall
  628.     jmp    nextpix
  629.  
  630.  
  631.  
  632. ;===========================================================================
  633.  
  634. ;=============
  635. ;
  636. ; hit a special vertical wall, so find which coordinate a door would be
  637. ; intersected at, and check to see if the door is open past that point
  638. ;
  639. ;=============
  640. vertdoor:
  641.     mov    [xtile],bx                    ; save off live register variables
  642.     mov    [WORD yintercept+2],dx
  643.  
  644.     test al,040h                      ; both high bits set == pushable wall
  645.     jnz    vertpushwall
  646.  
  647.     mov    bx,ax
  648.     and    bx,7fh                        ; strip high bit
  649.     shl    bx,1                        ; index into word width doorposition
  650.  
  651.     mov    ax,[WORD ystep]
  652.     mov    dx,[WORD ystep+2]
  653.     sar    dx,1
  654.     rcr ax,1                        ; half a step gets to door position
  655.  
  656.     add    ax,[WORD yintercept]        ; add half step to current intercept pos
  657.     adc    dx,[WORD yintercept+2]
  658.  
  659.     cmp    [WORD yintercept+2],dx        ; is it still in the same tile?
  660.     je    hitvmid
  661. ;
  662. ; midpoint is outside tile, so it hit the side of the wall before a door
  663. ;
  664. continuevert:
  665.     mov    bx,[xtile]                    ; reload register variables
  666.     mov    dx,[WORD yintercept+2]
  667.     jmp    passvert                    ; continue tracing
  668. ;
  669. ; the trace hit the door plane at pixel position AX, see if the door is
  670. ; closed that much
  671. ;
  672. hitvmid:
  673.     cmp    ax,[doorposition+bx]        ; position of leading edge of door
  674.     jb    continuevert
  675. ;
  676. ; draw the door
  677. ;
  678.     mov    [WORD yintercept],ax        ; save pixel intercept position
  679.     mov    [WORD xintercept],8000h        ; intercept in middle of tile
  680.     mov    ax,[xtile]
  681.     mov    [WORD xintercept+2],ax
  682.  
  683.     call    FAR HitVertDoor
  684.     jmp    nextpix
  685.  
  686. ;============
  687. ;
  688. ; hit a sliding vertical wall
  689. ;
  690. ;============
  691.  
  692. vertpushwall:
  693.     mov    ax,[WORD ystep+2]            ; multiply ystep by pwallmove (0-63)
  694.     mul    [pwallpos]
  695.     mov    bx,ax
  696.     mov    ax,[WORD ystep]
  697.     mul    [pwallpos]
  698.     add    dx,bx
  699.  
  700.     sar    dx,1                        ; then divide by 64 to accomplish a
  701.     rcr ax,1                        ; fixed point multiplication
  702.     sar    dx,1
  703.     rcr ax,1
  704.     sar    dx,1
  705.     rcr ax,1
  706.     sar    dx,1
  707.     rcr ax,1
  708.     sar    dx,1
  709.     rcr ax,1
  710.     sar    dx,1
  711.     rcr ax,1
  712.  
  713.     add    ax,[WORD yintercept]        ; add partial step to current intercept
  714.     adc    dx,[WORD yintercept+2]
  715.  
  716.     cmp    [WORD yintercept+2],dx        ; is it still in the same tile?
  717.     jne    continuevert                ; no, it hit the side
  718.  
  719. ;
  720. ; draw the pushable wall at the new height
  721. ;
  722.     mov    [WORD yintercept],ax        ; save pixel intercept position
  723.     mov    [WORD yintercept+2],dx
  724.  
  725.     mov    bx,[xtile]
  726.     mov    [WORD xintercept+2],bx
  727.     mov    [WORD xintercept],0
  728.  
  729.     call    FAR HitVertPWall
  730.     jmp    nextpix
  731.  
  732.  
  733.  
  734. ENDP
  735.  
  736.  
  737. END
  738.  
  739.  
  740.