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

  1.  .286
  2. w equ word ptr
  3. b equ byte ptr
  4. surfclen equ 200                ;maximum length of surface defined
  5. Pointlen equ 4*100              ;length of point array
  6. num_ar equ 30                   ;maximum number of areas
  7. num_cor equ 10                  ;maximum number of corners
  8. data segment                    ;external variables from Pascal segment
  9.   extrn vz:word                 ;total depth
  10.   extrn rotx:Word               ;angle of rotation
  11.   extrn roty:Word
  12.   extrn rotz:word
  13.   extrn worldconst:dataptr      ;array with points
  14.   extrn surfcconst:dataptr      ;array with surface definitions
  15.   extrn lightsrc:word           ;flag for light source shading
  16.   extrn sf_sort:word            ;flag for surface sorting
  17.   extrn sf_shift:word           ;flag for surface shift suppression
  18.   extrn Texture:Byte            ;flag for textures
  19.   extrn Fill:Byte               ;flag for fill / wireframe model
  20.  
  21. crotx dw 0                      ;x, y and z angle as offset to
  22. croty dw 0                      ;specific sine value
  23. crotz dw 0
  24.  
  25. rotx_x dw 0                     ;x,y,z to x-rot
  26. rotx_y dw 0
  27. rotx_z dw 0
  28. roty_x dw 0                     ;to y-rot
  29. roty_y dw 0
  30. roty_z dw 0
  31. rotz_x dw 0                     ;to z-rot, final
  32. rotz_y dw 0
  33. rotz_z dw 0
  34.  
  35. startpoly dw 0                  ;start of definition of current area
  36.  
  37. Point      dw Pointlen dup (0);receives calculated coordinates
  38. Pointptr   dw 0                 ;pointer in Point-Array
  39. Point3d    dw Pointlen dup (0)  ;receives completed 3D-coordinates (texture)
  40. mean      dw num_ar*2 dup (0)   ;list of mean z-values
  41. meanptr   dw 0                  ;pointer in Mean-Array
  42. n           dw 0,0,0,0,0,0      ;normal vector 32 Bit
  43. n_amnt      dw 0                ;amount of normal vector
  44.  
  45. extrn sine:dataptr
  46.  
  47. data ends
  48.  
  49. extrn drawpol:near              ;draws area as wireframe model
  50. extrn fillpol:near              ;fills area
  51. extrn root:near                 ;calculates root of ax
  52.  
  53. getdelta macro                  ;calculates the two surface vectors
  54.   mov ax,poly3d[0]              ;x: original corner
  55.   mov delta2[0],ax              ;store temporarily in delta2
  56.   sub ax,poly3d[8]              ;obtain difference to first point
  57.   mov delta1[0],ax              ;and delta1 finished
  58.  
  59.   mov ax,poly3d[2]              ;y: original corner
  60.   mov delta2[2],ax              ;store temporarily in delta2
  61.   sub ax,poly3d[10d]            ;obtain difference to first point
  62.   mov delta1[2],ax              ;and delta1 finished
  63.  
  64.   mov ax,poly3d[4]              ;z: original corner
  65.   mov delta2[4],ax              ;store temporarily in delta2
  66.   sub ax,poly3d[12d]            ;obtain difference to first point
  67.   mov delta1[4],ax              ;and delta1 finished
  68.  
  69.   mov bp,polyn                  ;select last point
  70.   dec bp
  71.   shl bp,3                      ;8 bytes at a time
  72.   mov ax,poly3d[bp]             ;get x
  73.   sub delta2[0],ax              ;obtain difference
  74.   mov ax,poly3d[bp+2]           ;get y
  75.   sub delta2[2],ax              ;obtain difference
  76.   mov ax,poly3d[bp+4]           ;get z
  77.   sub delta2[4],ax              ;obtain difference
  78. endm
  79.  
  80. setcoord macro source,offst     ;sets calculated screencoord
  81. .386
  82.   mov ax,source                 ;project coordinate
  83.   cwd
  84.   shld dx,ax,7
  85.   shl ax,7
  86.   idiv cx
  87.    add ax,offst                 ;middle of screen is 0/0/0
  88.   mov bx,Pointptr               ;note in Point-Array
  89.   mov Point[bx],ax
  90.   add Pointptr,2                ;add array pointer
  91. endm
  92.  
  93. z2cx macro tabofs               ;moves z-coordinate to cx
  94.   mov cx,tabofs + 4
  95.   add cx,vz                     ;add z-translation
  96.   mov bx,meanptr                ;note in Mean-Array
  97.   add mean[bx],cx
  98. endm
  99.  
  100. xrot macro zcoord,qcoord        ;rotates qcoord by x, stores in zcoord
  101. .386
  102.   mov bp,crotx                  ;get angle
  103.   mov bx,[qcoord]
  104.   shl bx,3                      ;x8, to align to point entries
  105.   mov Pointptr,bx
  106.  
  107.   sub bx,[qcoord]               ;insg. x6, to align to world entries
  108.   sub bx,[qcoord]
  109.   add bx,offset worldconst      ;set to world
  110.   mov ax,[bx]                   ;get x
  111.   mov zcoord,ax                 ;and set unchanged
  112.  
  113.   mov ax,[bx+2]                 ;get y
  114.   imul w ds:[bp+60d]            ;*cos rotx
  115.   shrd ax,dx,14d
  116.   mov cx,ax                     ;store in cx
  117.   mov ax,[bx+4]                 ;get z
  118.   imul w ds:[bp]                ;*-sin rotx
  119.   shrd ax,dx,14d
  120.   sub cx,ax
  121.   mov zcoord+2,cx               ;y value finished and set
  122.  
  123.   mov ax,[bx+2]                 ;get y
  124.   imul w ds:[bp]                ;*sin rotx
  125.   shrd ax,dx,14d
  126.   mov cx,ax                     ;store in cx
  127.   mov ax,[bx+4]                 ;get z
  128.   imul w ds:[bp+60d]            ;*cos rotx
  129.   shrd ax,dx,14d
  130.   add cx,ax
  131.   mov zcoord+4,cx
  132. endm
  133.  
  134. yrot macro zcoord,qcoord        ;rotates qcoord by y, stores in zcoord
  135.   mov bp,croty                  ;get angle
  136.   mov ax,qcoord+2               ;get y
  137.   mov zcoord+2,ax               ;and set unchanged
  138.  
  139.   mov ax,qcoord                 ;get x
  140.   imul w ds:[bp+60d]            ;*cos roty
  141.   shrd ax,dx,14d
  142.   mov cx,ax                     ;store in cx
  143.   mov ax,qcoord+4               ;get z
  144.   imul w ds:[bp]                ;*sin roty
  145.   shrd ax,dx,14d
  146.   add cx,ax
  147.   mov zcoord,cx                 ;x value finished and set
  148.  
  149.   mov ax,qcoord                 ;get x
  150.   imul w ds:[bp]                ;*-sin roty
  151.   shrd ax,dx,14d
  152.   mov cx,ax                     ;store in cx
  153.   mov ax,qcoord+4               ;get z
  154.   imul w ds:[bp+60d]            ;*cos roty
  155.   shrd ax,dx,14d
  156.   sub ax,cx
  157.   mov zcoord+4,ax
  158. endm
  159.  
  160. zrot macro zcoord,qcoord        ;rotates qcoord by z, saves in zcoord
  161.   mov bx,Pointptr               ;prepare entry in 3D-Point-Array
  162.  
  163.   mov bp,crotz                  ;get angle
  164.   mov ax,qcoord+4               ;get z
  165.   mov zcoord+4,ax               ;and set unchanged
  166.   mov Point3d[bx+4],ax          ;also note in 3D-Array
  167.  
  168.   mov ax,qcoord                 ;get x
  169.   imul w ds:[bp+60d]            ;*cos rotz
  170.   shrd ax,dx,14d
  171.   mov cx,ax                     ;store in cx
  172.   mov ax,qcoord+2               ;get y
  173.   imul w ds:[bp]                ;*-sin rotz
  174.   shrd ax,dx,14d
  175.   sub cx,ax
  176.   mov zcoord,cx                 ;x value finished and set
  177.   mov Point3d[bx],cx
  178.  
  179.   mov ax,qcoord                 ;get x
  180.   imul w ds:[bp]                ;*sin rotz
  181.   shrd ax,dx,14d
  182.   mov cx,ax                     ;store in cx
  183.   mov ax,qcoord+2               ;get y
  184.   imul w ds:[bp+60d]            ;*cos rotz
  185.   shrd ax,dx,14d
  186.   add cx,ax
  187.   mov zcoord+2,cx
  188.   mov Point3d[bx+2],cx
  189.  
  190. endm
  191.  
  192. get_normal macro                ;calculates normal vector of an area
  193.   mov ax,delta1[2]              ;a2*b3
  194.   imul delta2[4]
  195.   shrd ax,dx,4
  196.   mov n[0],ax
  197.   mov ax,delta1[4]              ;a3*b2
  198.   imul delta2[2]
  199.   shrd ax,dx,4
  200.   sub n[0],ax
  201.   mov ax,delta1[4]              ;a3*b1
  202.   imul delta2[0]
  203.   shrd ax,dx,4
  204.   mov n[2],ax
  205.   mov ax,delta1[0]              ;a1*b3
  206.   imul delta2[4]
  207.   shrd ax,dx,4
  208.   sub n[2],ax
  209.   mov ax,delta1[0]              ;a1*b2
  210.   imul delta2[2]
  211.   shrd ax,dx,4
  212.   mov n[4],ax
  213.   mov ax,delta1[2]
  214.   imul delta2[0]
  215.   shrd ax,dx,4
  216.   sub n[4],ax                   ;cross product (=normal vector) finished
  217.  
  218.   mov ax,n[0]                   ;x1 ^ 2
  219.   imul ax
  220.   mov bx,ax
  221.   mov cx,dx
  222.   mov ax,n[2]                   ;+x2 ^ 2
  223.   imul ax
  224.   add bx,ax
  225.   adc cx,dx
  226.   mov ax,n[4]                   ;+x3 ^ 2
  227.   imul ax
  228.   add ax,bx
  229.   adc dx,cx                     ;sum in dx:ax
  230.   push si
  231.   call root                     ;root in ax
  232.   pop si
  233.   mov n_amnt,ax                 ;amount of normal vector finished
  234. endm
  235.  
  236. light macro                     ;determines brightness of an area
  237.   mov ax,n[0]
  238.   imul l[0]                     ;light vector * normal vector
  239.   mov bx,ax                     ;form sum in cx:bx
  240.   mov cx,dx
  241.   mov ax,n[2]
  242.   imul l[2]
  243.   add bx,ax
  244.   adc cx,dx
  245.   mov ax,n[4]
  246.   imul l[4]
  247.   add ax,bx                     ;scalar product finished in dx:ax
  248.   adc dx,cx
  249.   idiv l_amnt                   ;divide by l_amnt
  250.  
  251.   mov bx,n_amnt                 ;and by n_amnt
  252.   cwd
  253.   shld dx,ax,5                  ;values from -32 bis +32
  254.   shl ax,5d
  255.   mov bp,startpoly              ;prepare addressing of  surface color
  256.   idiv bx                       ;division by denominator
  257.   inc ax
  258.   or ax,ax
  259.   js turned_toward              ;if cos α positive -> turned away from the light
  260.   xor ax,ax                     ;thus, no light
  261. turned_toward:
  262.   sub b polycol,al              ;cos<0 -> add to primary color
  263. endm
  264.  
  265. code segment
  266. assume cs:code,ds:data
  267.  
  268. public drawworld
  269.  
  270. public linecount
  271. public polycol
  272. public polyn
  273. public poly2d
  274. public poly3d
  275. linecount dw 0
  276. polycol dw 3                    ;current surface color
  277. polyn   dw 0                    ;number of existing corners
  278. poly2d dw num_cor*4 dup (0)     ;corners of polygon to be drawn
  279. poly3d dw num_cor*4 dup (0)     ;3D corners
  280.  
  281. public Txt_No
  282. Txt_No dw 0                     ;current texture number
  283.  
  284. public delta1,delta2
  285. delta1      dw 0,0,0            ;plane vectors
  286. delta2      dw 0,0,0
  287.  
  288. l            dw 11d,11d,11d     ;light vector
  289. l_amnt      dw 19d              ;amount of light vector
  290.  
  291.  
  292. drawworld proc pascal           ;draws three-dimensional world
  293.   push ds
  294.   push es
  295.   push bp
  296.   lea si,surfcconst             ;surfaces are addressed by si
  297.   mov meanptr,0                 ;start in Mean-Array with 0
  298.   mov ax,ds:[rotx]              ;get angle,
  299.   shl ax,1                      ;convert as memory offset
  300.   add ax,offset sine
  301.   mov crotx,ax                  ;and store in help variables
  302.   mov ax,ds:[roty]              ;exactly the same for y
  303.   shl ax,1
  304.   add ax,offset sine
  305.   mov croty,ax
  306.   mov ax,ds:[rotz]              ;and z
  307.   shl ax,1
  308.   add ax,offset sine
  309.   mov crotz,ax
  310. npoly:                          ;polygon loop
  311.   mov startpoly,si              ;store for later use
  312.   add si,2                      ;skip color
  313.   mov cx,[si]                   ;get number of corners
  314.   mov linecount,cx              ;load counter
  315.   inc cx                        ;due to closed area
  316.   mov w polyn,cx                ;enter in Point-Array
  317.   add si,2                      ;move to actual coordinates
  318.  
  319. nline:
  320.   xrot rotx_x,si                ;rotate coordinates by x
  321.   yrot roty_x,rotx_x            ;by y
  322.   zrot rotz_x,roty_x            ;and by z
  323.   z2cx rotz_x                   ;get z start
  324.  
  325.   setcoord rotz_x,160           ;write coordinates
  326.   setcoord rotz_y,100
  327.  
  328.   add si,2                      ;next corner point
  329.   dec linecount                 ;advance line counter
  330.   je polyok                     ;all drawn -> terminate
  331.   jmp nline                     ;otherwise next line
  332.  
  333. polyok:
  334.   mov bx,meanptr                ;calculate mean value:
  335.   mov ax,mean[bx]               ;get sum
  336.   mov cx,polyn
  337.   dec cx
  338.   cwd
  339.   div cx                        ;and divide by number of corners
  340.   mov mean[bx],ax               ;write back
  341.   mov ax,startpoly              ;write "number" of area also
  342.   mov mean[bx+2],ax
  343.   add meanptr,4                 ;continue
  344.   cmp w [si+2],0                ;polygons all finished ?
  345.   je finished
  346.   jmp npoly
  347.  
  348. finished:
  349.   cmp b sf_sort,0               ;sort surfaces ?
  350.   je no_quicksort
  351.   call quicksort pascal,0,bx    ;sort field from 0 to current position
  352.  
  353. no_quicksort:
  354.   mov mean[bx+4],0              ;set termination
  355.   mov ax,cs                     ;set destination segment
  356.   mov es,ax
  357.   xor bx,bx                     ;start with first surface
  358. npoly_draw:
  359.   lea di,poly2d                 ;destination:Poly-Array
  360.   mov bp,mean[bx+2]             ;get pointer to color and points of surface
  361.   mov ax,ds:[bp]                ;get color and set
  362.   mov polycol,ax
  363.  
  364.   mov texture,0                 ;Assumption: no texture
  365.   cmp ah,0ffh                   ;texture ?
  366.   jne no_texture
  367.   mov texture,1                 ;yes, then set
  368.   mov b txt_no,al               ;note number
  369.  
  370. no_texture:
  371.   mov b lightsrc,0              ;Assumption: no shading
  372.   cmp ah,0feh                   ;shading ?
  373.   jne no_lightsource
  374.   mov b lightsrc,1              ;yes, then set
  375.  
  376. no_lightsource:
  377.   add bp,2                      ;position on number
  378.   mov cx,ds:[bp]                ;get number of corners
  379.   mov polyn,cx                  ;write in Poly-Array
  380. npoint:
  381.   add bp,2
  382.   mov si,ds:[bp]                ;get pointer to actual point
  383.   shl si,3                      ;3 word entry !
  384.   add si,offset Point           ;and x/y from Point-Array to Poly-Coord.
  385.  
  386.   mov ax,[si+Point3d-Point]     ;3d-get x
  387.   mov es:[di+poly3d-poly2d],ax  ;set 3d-x
  388.   mov ax,[si+Point3d-Point+2]   ;3d-get y
  389.   mov es:[di+poly3d-poly2d+2],ax;set 3d-y
  390.   mov ax,[si+Point3d-Point+4]   ;3d-get z
  391.   mov es:[di+poly3d-poly2d+4],ax;set 3d-z
  392.  
  393.   movsw                         ;set 2D-coordinates
  394.   movsw
  395.  
  396.   add di,4                      ;next Poly2d entry
  397.   dec cx                        ;all corners ?
  398.   jne npoint
  399.  
  400.   mov bp,polyn                  ;copy first corner to last
  401.   shl bp,3                      ;position on first point
  402.   neg bp
  403.   mov ax,es:[di+bp]             ;and copy
  404.   mov es:[di],ax
  405.   mov ax,es:[di+bp+2]
  406.   mov es:[di+2],ax
  407.  
  408.   add di,poly3d-poly2d          ;the same for 3d-coordinates
  409.   mov ax,es:[di+bp]             ;and copy
  410.   mov es:[di],ax
  411.   mov ax,es:[di+bp+2]
  412.   mov es:[di+2],ax
  413.   mov ax,es:[di+bp+4]
  414.   mov es:[di+4],ax
  415.  
  416.   cmp fill,1                    ;fill surface ?
  417.   jne lines
  418.  
  419.   getdelta                      ;yes, then calculate Delta1 and 2
  420.   cmp b lightsrc,0              ;light source ?
  421.   jne shade
  422.   jmp no_light
  423.  
  424. shade:                          ;yes,
  425.   push bx
  426.   get_normal                    ;then normal vector
  427.   light                         ;and calculate light
  428.   pop bx
  429.  
  430. no_light:
  431.   inc polyn                     ;increment number of corners
  432.   call fillpol                  ;draw surface
  433.  
  434. next:
  435.   add bx,4                      ;locate next surface
  436.   cmp mean[bx],0                ;last ?
  437.   je _npoly_draw                ;no, then continue
  438.   jmp npoly_draw
  439.  
  440. lines:
  441.   push bx
  442.   call drawpol                  ;draw polygon
  443.   pop bx
  444.   jmp next
  445.  
  446. _npoly_draw:
  447.   pop bp                        ;finished
  448.   pop es
  449.   pop ds
  450.   ret
  451. drawworld endp
  452.  
  453.  
  454. public quicksort
  455. quicksort proc pascal down,up:word
  456. ;sorts Mean-Array according to Quicksort algorithm
  457.  
  458. local key:word
  459. local left:word
  460.   push bx
  461.   mov bx,down                  ;find middle
  462.   add bx,up
  463.   shr bx,1
  464.   and bx,not 3                  ;posit on blocks of 4
  465.   mov dx,mean[bx]               ;get key
  466.   mov key,dx
  467.   mov  ax,down                  ;initialize right and left with base values
  468.   mov si,ax
  469.   mov left,ax
  470.   mov ax,up
  471.   mov di,ax
  472.  
  473.   mov dx,key
  474. left_nearer:
  475.   cmp mean[si],dx               ;greater than key -> continue searching
  476.   jbe left_on
  477.   add si,4                      ;posit on next one
  478.   jmp left_nearer               ;and check it
  479. left_on:
  480.   cmp mean[di],dx               ;less than key -> continue searching
  481.   jae right_on
  482.   sub di,4                      ;posit on next one
  483.   jmp left_on                   ;and check it
  484. right_on:
  485.   cmp si,di                     ;left <= right ?
  486.   jg end_schl                   ;no -> subarea sorted
  487.   mov eax,dword ptr mean[si]    ;exchange mean values and positions
  488.   xchg eax,dword ptr mean[di]
  489.   mov dword ptr mean[si],eax
  490.  
  491.   add si,4                      ;continue moving pointer
  492.   sub di,4
  493. end_schl:
  494.   cmp si,di                     ;left > right, then continue
  495.   jle left_nearer
  496.   mov left,si                   ;store left, due to recursion
  497.   cmp down,di                   ;down < right -> sort left subarea
  498.   jge right_finished
  499.   call quicksort pascal,down,di ;continue sorting recursive halves
  500. right_finished:
  501.   mov si,left                   ;up > left -> sort right subarea
  502.   cmp up,si
  503.   jle left_finished
  504.   call quicksort pascal,si,up  ;continue sorting recursive halves
  505. left_finished:
  506.   pop bx
  507.   ret
  508. quicksort endp
  509.  
  510. code ends
  511. end
  512.