home *** CD-ROM | disk | FTP | other *** search
/ PC Underground / UNDERGROUND.ISO / graphic / poly.asm < prev    next >
Assembly Source File  |  1995-07-28  |  15KB  |  484 lines

  1. .286
  2. w equ word ptr
  3. b equ byte ptr
  4.  
  5. include texture.inc             ;implement texture macros
  6.  
  7. setnewlinel macro               ;use only ax and bx here !
  8. local dylpos,dxlpos,dxlgreat,macro_finished
  9.   mov bx,4043h                  ;code for inc ax (in bh) and inc bx (in bl)
  10.   mov bp,left
  11.   mov ax,poly2d[bp+8]           ;store destination coordinates
  12.   mov xl1,ax
  13.   mov ax,poly2d[bp+10d]
  14.   mov yl1,ax
  15.  
  16.   mov ax,poly2d[bp]             ;left x/y start in glob. var
  17.   mov xl0,ax
  18.   sub ax,xl1                    ;make delta x
  19.   inc xl1                       ;for the condition of truncation
  20.   neg ax                        ;xl1-xl0
  21.   jns dxlpos                    ;dxl negative ?
  22.   neg ax                        ;then obtain amount
  23.   mov bh,48h                    ;code for dec ax (dec xl0)
  24.   sub xl1,2                     ;extension of destination coordinate to negative
  25. dxlpos:
  26.   mov dxl,ax                    ;and store glob.
  27.   mov incflagl,ax               ;store in increment flag
  28.   mov ax,poly2d[bp+2]
  29.   mov yl0,ax
  30.   sub ax,yl1                    ;obtain |delta y|
  31.   inc yl1                       ;for the condition of trunctation
  32.   neg ax
  33.   jns dylpos                    ;negative ?
  34.   neg ax                        ;then obtain amount
  35.   mov bl,4bh                    ;code for dec bx (dec yl1)
  36.   sub yl1,2                     ;extension of destination coordinate to negative
  37. dylpos:
  38.   mov dyl,ax                    ;and store glob.
  39.   cmp dxl,ax                    ;dx < dy
  40.   jae dxlgreat
  41.   neg incflagl                  ;then sign change for increment flag
  42. dxlgreat:
  43.   mov cs:byte ptr incxl,bh      ;perform self modification
  44.   mov cs:byte ptr incyl,bl
  45.  
  46.   cmp texture,1                 ;textures required ?
  47.   jne macro_finished              ;no, then skip
  48.  
  49.   txt_makevarl                  ;otherwise calculate texture variables
  50.  
  51. macro_finished:
  52.   mov ax,xl0                    ;use register as control variable
  53.   mov bx,yl0
  54.   mov si,incflagl
  55. endm
  56.  
  57. setnewliner macro               ;use only cx and dx here !
  58. local dyrpos,dxrpos,dxrgreat,macro_finished
  59.   mov cx,4142h                  ;code for inc cx (in ch) and inc dx (in cl)
  60.   mov bp,right
  61.   mov dx,poly2d[bp]             ;get destination coordinates
  62.   mov xr1,dx
  63.   mov dx,poly2d[bp+2]
  64.   mov yr1,dx
  65.   mov dx,poly2d[bp+8]           ;right x/y in glob. var
  66.   mov xr0,dx
  67.   sub dx,xr1                    ;make |delta x|
  68.   inc xr1                       ;for the condition of truncation
  69.   neg dx
  70.   jns dxrpos                    ;negative ?
  71.   neg dx                        ;then obtain amount
  72.   mov ch,49h                    ;code for dec cx
  73.   sub xr1,2                     ;extension of destination coordinate to negative
  74. dxrpos:
  75.   mov dxr,dx                    ;store in glob. var
  76.   mov incflagr,dx
  77.   mov dx,poly2d[bp+10d]         ;make |delta y|
  78.   mov yr0,dx
  79.   sub dx,yr1
  80.   inc yr1                       ;for the condition of truncation
  81.   neg dx
  82.   jns dyrpos                    ;negative ?
  83.   neg dx                        ;then obtain amount
  84.   mov cl,4ah                    ;code for dec dx
  85.   sub yr1,2                     ;extension of destination coordinate to negative
  86. dyrpos:
  87.   mov dyr,dx                    ;and store in glob. var
  88.   cmp dxr,dx                    ;dx < dy ?
  89.   jae dxrgreat
  90.   neg incflagr                  ;then sign change for increment flag
  91. dxrgreat:
  92.   mov cs:byte ptr incxr,ch      ;self modification
  93.   mov cs:byte ptr incyr,cl
  94.  
  95.   cmp texture,1                 ;textures needed ?
  96.   jne macro_finished            ;no, then skip
  97.  
  98.   txt_makevarr                  ;otherwise calculate texture variables
  99.  
  100. macro_finished:
  101.   mov cx,xr0                    ;load register
  102.   mov dx,yr0
  103.   mov di,incflagr
  104. endm
  105.  
  106. data segment public
  107.   extrn vpage:word              ;current video page
  108.   extrn sf_shift                ;flag for surface shift suppression
  109.   extrn glass:byte;             ;flag for glass surfaces
  110.  
  111. ;texture variables:
  112.   extrn texture:byte            ;texture needed  ?
  113.   extrn txt_data:dataptr        ;array with pointer to graphic data
  114.   extrn txt_offs:dataptr        ;array with offsets within the texture image
  115.   extrn txt_size:dataptr        ;array with size specifications
  116.  
  117. d_x  dd 0                       ;relative x-coordinate
  118. d_y dd 0                        ;relative y-coordinate
  119. D    dd 0                       ;main determinant
  120. column1 dd 0                    ;components of the main determinant
  121.         dd 0
  122. column2 dd 0
  123.         dd 0
  124. upper_row dw 0                  ;which coordinates were used ?
  125. lower_row dw 0
  126.  
  127. xl_3d dd 0                      ;control values for 3d-coordinates when filling
  128. yl_3d dd 0
  129. zl_3d dd 0
  130. xr_3d dd 0
  131. yr_3d dd 0
  132. zr_3d dd 0
  133.  
  134. inc_xl dd 0                     ;values for addition to control values
  135. inc_yl dd 0
  136. inc_zl dd 0
  137. inc_xr dd 0
  138. inc_yr dd 0
  139. inc_zr dd 0
  140.  
  141. ;variables for fill algorithm
  142. high_point   dw 0               ;kept in dx during search
  143. high_y      dw 0                ;kept in bx during search
  144.  
  145. left        dw 0                ;point of left side
  146. right      dw 0                 ;point of right side
  147.  
  148. xl0  dw 0                       ;control values for left start and end points
  149. yl0 dw 0
  150. xl1 dw 0
  151. yl1 dw 0
  152. xr0 dw 0                        ;control values for right
  153. yr0 dw 0
  154. xr1 dw 0
  155. yr1 dw 0
  156. dxl dw 0                        ;delta X / Y for both pages
  157. dyl dw 0
  158. dxr dw 0
  159. dyr dw 0
  160. incflagl dw 0                   ;flags, when y has to be incremented
  161. incflagr dw 0 
  162.  
  163. data ends
  164.  
  165. code segment public
  166. assume cs:code,ds:data
  167. extrn polycol:word              ;surface color
  168. extrn polyn:word                ;number of corners
  169. extrn poly2d:word               ;array with 2D-coordinates
  170. extrn poly3d:word               ;array with 3D-coordinates
  171. extrn delta1,delta2:word        ;plane vectors
  172. extrn bline:near                ;draws line
  173.  
  174. lambda1 dd 0                    ;affine coordinates
  175. lambda2 dd 0
  176.  
  177. inc_lambda1 dd 0                ;steps
  178. inc_lambda2 dd 0
  179.  
  180. plane dw 0002h                  ;current plane to set
  181. x0 dw 0                         ;coordinates for line
  182. y0 dw 0
  183. x1 dw 0
  184. zz dw 0                         ;points still to be drawn
  185.  
  186. extrn txt_no:word               ;number of texture to be drawn
  187.  
  188. public drawpol
  189. ;draws wireframe model of surface in poly2d
  190. drawpol proc near
  191.   push es
  192.   pusha
  193.   xor si,si                     ;index to first entry
  194.   mov bp,polyn                  ;get number of corners
  195. @nline:
  196.   mov ax,poly2d[si]             ;get coordinates from table
  197.   mov bx,poly2d[si+2]
  198.   mov cx,poly2d[si+8]
  199.   mov dx,poly2d[si+10d]
  200.   push bp
  201.   push si
  202.   call bline                    ;draw line
  203.   pop si
  204.   pop bp
  205.   add si,8                      ;next line
  206.   dec bp                        ;decrement number
  207.   jne @nline
  208.   popa
  209.   pop es
  210.   ret
  211. drawpol endp
  212.  
  213. hline proc near                 ;draws horiz. line ax/bx -> cx/bx
  214.   pusha
  215.   push es
  216.   mov x0,ax                     ;store coordinates for later
  217.   mov y0,bx
  218.   mov x1,cx
  219.   sub cx,ax                     ;calculate number of pixels to be drawn
  220.   jne zzok
  221.   inc cx
  222.  
  223. zzok:
  224.   mov zz,cx
  225.  
  226.   cmp glass,1                   ;glass surface ?
  227.   jne Solid1
  228.   push ax                       ;yes, then GDC mode: OR
  229.   mov dx,3ceh
  230.   mov ax,1003h                  ;register 3: function select
  231.   out dx,ax
  232.   pop ax
  233.  
  234. Solid1:
  235.   mov dx,3c4h                   ;timing sequencer port
  236.   mov di,0a000h
  237.   mov es,di                     ;select VGA segment
  238.   mov di,ax                     ;calculate offset
  239.   shr di,2                      ;(x div 4) + y*80
  240.   add di,vpage                  ;add current page
  241.   mov bx,y0
  242.   imul bx,80d
  243.   add di,bx                     ;now in di
  244.   cmp zz,4
  245.   jl no_middle                  ;<draw 4 points -> no blocks of 4
  246.   and ax,11b                    ;two lower bits are important
  247.   je middle                     ;if 0 set blocks of 4 immediately
  248. no_middle:
  249.   mov bx,0f02h                  ;if no_shift, then use this mask
  250.   mov cx,zz                     ;set number of pixels in mask
  251.   cmp cx,20h                    ;beginning with 20h the 386 shifts back in !
  252.   jae no_shift
  253.   mov bx,0102h                  ;prepare mask
  254.   shl bh,cl                     ;number of pixels=number of bits to set
  255.   dec bh
  256.   and bh,0fh
  257. no_shift:
  258.   mov cx,ax                     ;shift correctly depending on start plane
  259.   and cl,3
  260.   shl bh,cl
  261.   mov ax,bx                     ;and mask finished
  262.   sub zz,4                      ;decrement pixels to be drawn
  263.   add zz,cx
  264. start:
  265.   out dx,ax                     ;set calculated write mask
  266.   mov al,b polycol              ;get color
  267.  
  268.   mov ah,es:[di]                ;load latches, only for glass solids
  269.  
  270.   stosb                         ;set
  271. middle:
  272.   cmp zz,4
  273.   jl close                    ;if no more blocks of 4 -> conclusion
  274.  
  275.   mov ax,0f02h                  ;select all planes
  276.   out dx,ax                     ;(zz div 4) set blocks of 4
  277.   mov cx,zz
  278.   shr cx,2
  279.   mov al,b polycol
  280.  
  281.   cmp glass,1                   ;glass solid ?
  282.   jne solid
  283.  
  284. @lp:
  285.   mov ah,es:[di]                ;load latches, only glass solids
  286.   stosb                         ;and write back
  287.   dec cx
  288.   jne @lp
  289.   jmp close
  290.  
  291. solid:
  292.   rep stosb                     ;draw middle part
  293.  
  294. close:
  295.   mov cx,x1                     ;set remaining pixels
  296.   and cx,3h
  297.   dec zz
  298.   js hline_finished             ;if nothing more there -> end
  299.   mov ax,0102h
  300.   shl ah,cl                     ;create mask
  301.   dec ah
  302.   out dx,ax
  303.   mov al,b polycol              ;get color
  304.  
  305.   mov ah,es:[di]                ;load latches, only for glass solids
  306.  
  307.   stosb                         ;and draw pixels
  308. hline_finished:
  309.   mov dx,3ceh                   ;GDC mode back to MOVE
  310.   mov ax,0003h
  311.   out dx,ax
  312.   pop es
  313.   popa
  314.   ret
  315. hline endp
  316.  
  317. txt_hline                       ;macro contains procedure "hline_texture"
  318.  
  319. public fillpol
  320. fillpol proc near               ;fills polygon in mode X
  321.   push bp
  322.   pusha
  323.  
  324.   cmp texture,1                 ;textures being used ?
  325.   jne fill                      ;no, then simply fill
  326.  
  327.   txt_maindet                   ;otherwise calculate main determinant
  328.  
  329. Fill:
  330.   xor si,si                     ;search for highest point, select first entry
  331.   mov cx,polyn                  ;number of corners
  332.   sub cx,2
  333.   mov bx,0ffffh                 ;very high value, in any case lower
  334. npoint:
  335.   mov ax,poly2d[si+2]           ;get y
  336.   cmp ax,bx                     ;if previous minimum lower
  337.   ja  no_min
  338.   mov bx,ax                     ;record new minimum
  339.   mov dx,si
  340. no_min:
  341.   add si,8
  342.   dec cx                        ;next corner, if not 0ffffh
  343.   jns npoint
  344.   mov high_point,dx             ;record in glob var
  345.   mov high_y,bx                 ;high point search concluded
  346.  
  347.   or dx,dx                      ;left = 0 ?
  348.   jne dec_valid
  349.   mov bx,polyn                  ;yes: right to the other end
  350.   sub bx,2
  351.   shl bx,3
  352.   jmp lr_finished               ;position
  353. dec_valid:
  354.   mov bx,dx                     ;otherwise
  355.   sub bx,8
  356. lr_finished:
  357.   mov left,dx                   ;record one beforehand in glob var
  358.   mov right,bx
  359.  
  360. ; ax/bx : start coordinates left    (xl0/yl0)
  361. ; cx/dx : start coordinates right   (xr0/yr0)
  362. ; si    : overflow flag left
  363. ; di    : overflow flag right
  364. ; bp    : pointer to current point
  365.  
  366.   setnewlinel                   ;load line variables
  367.   setnewliner
  368.  
  369. loopl:
  370.   cmp ax,xl1
  371.   je new_linel                  ;if end reached -> set new line
  372.   cmp bx,yl1
  373.   je new_linel                  ;otherwise continue drawing
  374.  
  375.   or si,si                      ;increment flag <= 0
  376.   jg flaglgreat
  377. incyl:                          ;this place is being patched !
  378.   inc bx                        ;continue y
  379.   add si,dxl                    ;continue setting inc flag
  380.  
  381.   txt_incl                      ;continue 3d coordinates also
  382.  
  383.   cmp bx,yl1                    ;destination reached ?
  384.   je new_linel                  ;then new line
  385.   jmp left_increased            ;y has been increased left -> now right
  386. flaglgreat:
  387.   sub si,dyl                    ;decrement inc flag
  388. incxl:                          ;this place being patched !
  389.   inc ax                        ;continue x
  390.   jmp loopl
  391.  
  392. finished__:
  393.   jmp finished
  394.  
  395. new_linel:
  396.   mov bx,left                   ;prepare increase
  397.   cmp bx,right
  398.   je finished__                 ;same, then finished
  399.   add bx,8                      ;continue left
  400.   mov ax,polyn                  ;is left at the end of the list ?
  401.   shl ax,3
  402.   sub ax,8                      ;end defined
  403.   cmp bx,ax                     ;compare
  404.   jb left_set
  405.   xor bx,bx                     ;if yes, then set to 0
  406. left_set:
  407.   mov left,bx
  408.   setnewlinel                   ;reload variables
  409.   jmp loopl
  410. finished_:
  411.   jmp finished
  412. left_increased:
  413.  
  414. loopr:
  415.   cmp cx,xr1
  416.   je new_liner                  ;if end reached -> set new line
  417.   cmp dx,yr1
  418.   je new_liner                  ;otherwise continue drawing
  419.  
  420.   or di,di                      ;increment flag <= 0
  421.   jg flagrgreat
  422. incyr:                          ;this place being patched !
  423.   inc dx                        ;continue y
  424.   add di,dxr                    ;continue setting inc flag
  425.  
  426.   txt_incr
  427.  
  428.   cmp dx,yr1                    ;destination reached ?
  429.   je new_liner                  ;then new line
  430.   jmp right_increased           ;y was increased right -> now draw line
  431. flagrgreat:
  432.   sub di,dyr                    ;decrement inc flag
  433. incxr:
  434.   inc cx                        ;this place being patched !
  435.   jmp loopr
  436.  
  437. new_liner:
  438.   mov dx,right                  ;prepare decrease
  439.   cmp dx,left
  440.   je finished_                  ;if same, then finished
  441.   sub dx,8                      ;if previously at 0->set at other end
  442.   jns right_set
  443.   mov dx,polyn
  444.   sub dx,2
  445.   shl dx,3                      ;positioned at end
  446. right_set:
  447.   mov right,dx
  448.  
  449.   setnewliner                   ;reload variables
  450.   jmp loopr
  451.  
  452. right_increased:
  453.   push ax
  454.   push cx
  455.   cmp cx,ax                     ;correct sequence ?
  456.   jae direct_ok                 ;then ok, otherwise:
  457.   cmp w sf_shift,0              ;suppress surface shift ?
  458.   je draw                       ;no, then draw anyway
  459.   pop cx
  460.   pop ax
  461.   jmp finished                  ;polygon will not be drawn
  462. draw:
  463.   xchg ax,cx                    ;coordinates in correct sequence
  464. direct_ok:
  465.  
  466.   cmp texture,1                 ;use textures ?
  467.   jne norm_fill                 ;no, then normal fill
  468.   call hline_texture            ;draw horizontal texture line
  469.   pop cx
  470.   pop ax
  471.   jmp loopl                     ;and continue
  472. norm_fill:
  473.   call hline                    ;draw horizontal line
  474.   pop cx
  475.   pop ax
  476.   jmp loopl                     ;and continue
  477. finished:
  478.   popa
  479.   pop bp
  480.   ret
  481. fillpol endp
  482. code ends
  483. end
  484.