home *** CD-ROM | disk | FTP | other *** search
/ PC Interdit / pc-interdit.iso / graph / 3dasm.asm < prev    next >
Assembly Source File  |  1994-10-17  |  15KB  |  513 lines

  1. w equ word ptr
  2. b equ byte ptr
  3. surfclen equ 200        ;longueur maximale de la définition des faces
  4. PointsT equ 4*100       ;taille du tableau des points
  5. nb_su equ 30            ;nombre maximal de faces
  6. nb_som equ 10           ;nombre maximal de sommets
  7. data segment            ;variables externes de la partie Pascal
  8.   extrn vz:word         ;profondeur général
  9.   extrn rotx:Word       ;angles de rotation
  10.   extrn roty:Word
  11.   extrn rotz:word
  12.   extrn worldconst:dataptr      ;tableau des points
  13.   extrn surfcconst:dataptr      ;tableau des définitions des faces 
  14.   extrn lightsrc:word           ;indicateur pour effet de lumière
  15.   extrn su_sort:word            ;indicateur pour tri des faces
  16.   extrn su_cacher:word          ;indicateur pour traitement des faces cachées
  17.   extrn Texture:Byte            ;indicateur pour textures
  18.   extrn Remplir:Byte            ;indicateur pour remplissage/fil de fer
  19.  
  20. crotx dw 0          ;angle x, y et z comme offset
  21. croty dw 0          ;sur la valeur du sinus
  22. crotz dw 0
  23.  
  24. rotx_x dw 0         ;x, y, z après rotation x
  25. rotx_y dw 0
  26. rotx_z dw 0
  27. roty_x dw 0         ;après rotation y
  28. roty_y dw 0
  29. roty_z dw 0
  30. rotz_x dw 0         ;après rotation z, définitif
  31. rotz_y dw 0
  32. rotz_z dw 0
  33.  
  34. startpoly dw 0      ;début de la déf de la face courante
  35.  
  36. Points      dw PointsT dup (0)  ;mémorise les coordonnées calculées
  37. Pointsptr   dw 0                ;pointe sur le tableau de points
  38. Points3d    dw PointsT dup (0)  ;mémorise les coordonnées 3D (texture)
  39. moyen      dw nb_su*2 dup (0)   ;répertoire des valeurs moyennes de z
  40. moyenptr   dw 0                 ;pointeur dans le tableau "moyen"
  41. n           dw 0,0,0,0,0,0      ;vecteur normal 32 bits
  42. n_long      dw 0                ;longueur du vecteur normal
  43.  
  44. extrn sinus:dataptr
  45.  
  46. data ends
  47.  
  48. extrn drawpol:near  ;dessine une face en fil de fer
  49. extrn fillpol:near  ;remplit une face
  50. extrn racine:near   ;calcule la racine de ax
  51.  
  52. getdelta macro      ;calcule les deux vecteurs compris dans le plan de la face
  53.   mov ax,poly3d[0]  ;x: sommet de départ
  54.   mov delta2[0],ax  ;sauvegarde temporaire en delta2
  55.   sub ax,poly3d[8]  ;différence avec le premier point
  56.   mov delta1[0],ax  ; delta1 terminé
  57.  
  58.   mov ax,poly3d[2]  ;y: sommet de départ
  59.   mov delta2[2],ax  ;sauvegarde temporaire en delta2
  60.   sub ax,poly3d[10d];différence avec le premier point
  61.   mov delta1[2],ax  ; delta1 terminé 
  62.  
  63.   mov ax,poly3d[4]  ;z: sommet de départ
  64.   mov delta2[4],ax  ;sauvegarde temporaire en delta2
  65.   sub ax,poly3d[12d];différence avec le premier point
  66.   mov delta1[4],ax  ; delta1 terminé
  67.  
  68.   mov bp,polyn          ;sélectionne le dernier point
  69.   dec bp
  70.   shl bp,3              ; 8 octets à chaque fois
  71.   mov ax,poly3d[bp]     ;lit x 
  72.   sub delta2[0],ax      ;forme la différence
  73.   mov ax,poly3d[bp+2]   ;lit y 
  74.  
  75.   sub delta2[2],ax      ;forme la différence
  76.   mov ax,poly3d[bp+4]   ;lit z
  77.   sub delta2[4],ax      ;forme la différence
  78. endm
  79.  
  80. setcoord macro source,offst     ;fixe les coord d'écran calculées
  81. .386
  82.   mov ax,source                 ;projette les coordonnées
  83.   cwd
  84.   shld dx,ax,7
  85.   shl ax,7
  86.   idiv cx
  87.    add ax,offst         ;centre de l'écran = 0,0,0
  88.   mov bx,Pointsptr      ;report dans le tableau des points
  89.   mov Points[bx],ax
  90.   add Pointsptr,2       ;déplace le pointeur sur le tableau
  91. endm
  92.  
  93. z2cx macro tabofs       ;lit en cx la coordonnée z
  94.   mov cx,tabofs + 4
  95.   add cx,vz             ;ajoute la translation z
  96.   mov bx,moyenptr       ;report dans le tableau moyen
  97.   add moyen[bx],cx
  98. endm
  99.  
  100. xrot macro dcoord,scoord   ;rotation de scoord autour de x, résultat en dcoord
  101. .386
  102.   mov bp,crotx             ;charge l'angle
  103.   mov bx,[scoord]
  104.   shl bx,3                 ;x8, pour alignemt sur entrée de points
  105.   mov Pointsptr,bx
  106.  
  107.   sub bx,[scoord]   ;en tout x6, pour alignement sur entrées espace
  108.   sub bx,[scoord]
  109.   add bx,offset worldconst
  110.   mov ax,[bx]       ;lit x
  111.   mov dcoord,ax     ;qui reste inchangé 
  112.  
  113.   mov ax,[bx+2]     ;lit y 
  114.   imul w ds:[bp+60d];*cos rotx
  115.   shrd ax,dx,14d
  116.   mov cx,ax         ;mémorise en cx 
  117.   mov ax,[bx+4]     ;lit z 
  118.   imul w ds:[bp]    ;*-sin rotx
  119.   shrd ax,dx,14d
  120.   sub cx,ax
  121.   mov dcoord+2,cx   ;y terminé et stocké
  122.  
  123.   mov ax,[bx+2]     ;lit y 
  124.   imul w ds:[bp]    ;*sin rotx
  125.   shrd ax,dx,14d
  126.   mov cx,ax         ;mémorise en cx
  127.   mov ax,[bx+4]       ;lit z 
  128.   imul w ds:[bp+60d]  ;*cos rotx
  129.   shrd ax,dx,14d
  130.   add cx,ax
  131.   mov dcoord+4,cx
  132. endm
  133.  
  134. yrot macro dcoord,scoord  ;rotation de scoord autour de y, résultat en dcoord
  135.   mov bp,croty            ;lit l'angle
  136.   mov ax,scoord+2         ;et y
  137.   mov dcoord+2,ax         ;y reste inchangé
  138.  
  139.   mov ax,scoord         ;lit x 
  140.   imul w ds:[bp+60d]    ;*cos roty
  141.   shrd ax,dx,14d
  142.   mov cx,ax             ;mémorise en cx 
  143.   mov ax,scoord+4       ;lit z 
  144.   imul w ds:[bp]        ;*sin roty
  145.   shrd ax,dx,14d
  146.   add cx,ax
  147.   mov dcoord,cx         ;x terminé et stocké
  148.  
  149.   mov ax,scoord     ;lit x 
  150.   imul w ds:[bp]    ;*-sin roty
  151.   shrd ax,dx,14d
  152.   mov cx,ax         ;mémorise en cx
  153.   mov ax,scoord+4   ;lit z 
  154.   imul w ds:[bp+60d];*cos roty
  155.   shrd ax,dx,14d
  156.   sub ax,cx
  157.   mov dcoord+4,ax
  158. endm
  159.  
  160. zrot macro dcoord,scoord  ;rotation de scoord autour de z, résultat en dcoord
  161.   mov bx,Pointsptr        ;prépare le report dans le tableau de points 3D
  162.  
  163.   mov bp,crotz          ;lit l'angle
  164.   mov ax,scoord+4       ;lit z
  165.   mov dcoord+4,ax       ;et le laisse inchangé
  166.   mov Points3d[bx+4],ax ;report également dans tableau 3D
  167.  
  168.   mov ax,scoord     ;lit x 
  169.   imul w ds:[bp+60d];*cos rotz
  170.   shrd ax,dx,14d
  171.   mov cx,ax         ;mémorise en cx 
  172.   mov ax,scoord+2   ;lit y 
  173.   imul w ds:[bp]    ;*-sin rotz
  174.   shrd ax,dx,14d
  175.   sub cx,ax
  176.   mov dcoord,cx     ;x terminé et stocké
  177.   mov Points3d[bx],cx
  178.  
  179.   mov ax,scoord     ;lit x 
  180.   imul w ds:[bp]    ;*sin rotz
  181.   shrd ax,dx,14d
  182.   mov cx,ax         ;mémorise en cx
  183.   mov ax,scoord+2   ;lit y 
  184.   imul w ds:[bp+60d];*cos rotz
  185.   shrd ax,dx,14d
  186.   add cx,ax
  187.   mov dcoord+2,cx
  188.   mov Points3d[bx+2],cx
  189.  
  190. endm
  191.  
  192. get_normal macro    ;calcule le vecteur normal d'une face
  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       ; produit vectoriel (=vecteur normal) calculé
  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         ;somme en dx:ax
  230.   push si
  231.   call racine       ;racine en ax
  232.   pop si
  233.   mov n_long,ax     ;longueur du vecteur normal calculée
  234. endm
  235.  
  236. light macro         ;détermine la luminosité d'une face
  237.   mov ax,n[0]
  238.   imul l[0]         ;vecteur de la lumière * vecteur normal
  239.   mov bx,ax         ;somme en 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         ;produit scalaire en dx:ax
  248.   adc dx,cx
  249.   idiv l_long       ;division par l_long 
  250.  
  251.   mov bx,n_long     ;et par n_long
  252.   cwd
  253.   shld dx,ax,5      ;valeurs de -32 à +32
  254.   shl ax,5d
  255.   mov bp,startpoly  ;prépare l'adressage de la couleur de surface
  256.   idiv bx           ;division par numérateur
  257.   inc ax
  258.   or ax,ax
  259.   js danslumiere    ;si cos A positif -> lumière partante
  260.   xor ax,ax         ;donc pas d'éclairage
  261. danslumiere:
  262.   sub b polycol,al  ;cos<0 -> addition à la couleur de base
  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                    ;couleur de face courante
  277. polyn   dw 0                    ;nombre de sommets effectivement présents
  278. poly2d dw nb_som*4 dup (0)      ;sommets du polygone à desssiner
  279. poly3d dw nb_som*4 dup (0)      ;sommets 3D
  280.  
  281. public Txt_Nr
  282. Txt_Nr dw 0                     ;numéro de la texture courante
  283.  
  284. public delta1,delta2
  285. delta1       dw 0,0,0           ;vecteurs de plans
  286. delta2      dw 0,0,0
  287.  
  288. l            dw 11d,11d,11d     ;vecteur lumière
  289. l_long      dw 19d              ;longueur du vecteur lumière
  290.  
  291.  
  292. drawworld proc pascal           ;dessine un espace tridimensionnel
  293.   push ds
  294.   push es
  295.   push bp
  296.   lea si,surfcconst             ;faces adressées par si
  297.   mov moyenptr,0                ;on commence par 0 dans le tableau moyen
  298.   mov ax,ds:[rotx]              ;lit l'angle,
  299.   shl ax,1                      ;convertit en offset mémoire
  300.   add ax,offset sinus
  301.   mov crotx,ax                  ;et stocke dans variables auxiliaires
  302.   mov ax,ds:[roty]              ;idem pour y
  303.   shl ax,1
  304.   add ax,offset sinus
  305.   mov croty,ax
  306.   mov ax,ds:[rotz]              ;et z
  307.   shl ax,1
  308.   add ax,offset sinus
  309.   mov crotz,ax
  310. npoly:              ;boucle des polygones
  311.   mov startpoly,si  ;sauve pour usage ultérieur
  312.   add si,2          ;passe par-dessus la couleur
  313.   mov cx,[si]       ;lit le nombre de sommets
  314.   mov linecount,cx  ;charge le compteur
  315.   inc cx            ;à cause des faces fermées
  316.   mov w polyn,cx    ;report dans le tableau des points
  317.   add si,2          ;on continue par les coordonnées proprement dites
  318.  
  319. nline:
  320.   xrot rotx_x,si    ;rotation des coordonnées autour de x
  321.   yrot roty_x,rotx_x;autour de y
  322.   zrot rotz_x,roty_x;et de z
  323.   z2cx rotz_x       ;lit début z 
  324.  
  325.   setcoord rotz_x,160           ;enregistre les coordonnées
  326.   setcoord rotz_y,100
  327.  
  328.   add si,2          ;sommet suivant 
  329.   dec linecount     ;diminue le compteur de ligne 
  330.   je polyok         ;tout dessiné ? -> fini
  331.   jmp nline         ;sinon ligne suivante
  332.  
  333. polyok:
  334.   mov bx,moyenptr  ;calcule la valeur moyenne :
  335.   mov ax,moyen[bx] ;lit la somme
  336.   mov cx,polyn
  337.   dec cx
  338.   cwd
  339.   div cx                ;et la divise par le nombre de sommets
  340.   mov moyen[bx],ax      ;puis enregistre le résultat
  341.   mov ax,startpoly      ;avec le "numéro" de la face
  342.   mov moyen[bx+2],ax
  343.   add moyenptr,4        ;on continue
  344.   cmp w [si+2],0        ;tous les polygones traités ?
  345.   je fini
  346.   jmp npoly
  347.  
  348. fini:
  349.   cmp b su_sort,0       ;trier les faces ?
  350.   je no_quicksort
  351.   call quicksort pascal,0,bx    ;trie le champ de 0 à la position actuelle
  352.  
  353. no_quicksort:
  354.   mov moyen[bx+4],0     ;terminaison
  355.   mov ax,cs             ;segment de destination
  356.   mov es,ax
  357.   xor bx,bx             ;on commence par la première face
  358. npoly_draw:
  359.   lea di,poly2d         ;destination : tableau Poly
  360.   mov bp,moyen[bx+2]    ;lit pointeur sur couleur et points de la face
  361.   mov ax,ds:[bp]        ;lit et fixe la couleur
  362.   mov polycol,ax
  363.  
  364.   mov texture,0         ;a priori : pas de texture
  365.   cmp ah,0ffh           ;texture ?
  366.   jne no_textur
  367.   mov texture,1         ;oui, on la fixe
  368.   mov b txt_nr,al       ;prend note du n°
  369.  
  370. no_textur:
  371.   mov b lightsrc,0      ;a priori : pas d'ombre
  372.   cmp ah,0feh           ;ombre ?
  373.   jne no_sourcelum
  374.   mov b lightsrc,1      ;oui, on la fixe
  375.  
  376. no_sourcelum:
  377.   add bp,2              ;se positionne sur le nombre
  378.   mov cx,ds:[bp]        ;lit le nombre de sommets
  379.   mov polyn,cx          ;l'enregistre dans le tableau Poly
  380. npoint:
  381.   add bp,2
  382.   mov si,ds:[bp]        ;pointe sur les points effectifs
  383.   shl si,3              ;3 entrées Word !
  384.   add si,offset Points  ;et x,y du tableau des points en coord Poly
  385.  
  386.   mov ax,[si+Points3d-Points]   ;lit 3d-x 
  387.   mov es:[di+poly3d-poly2d],ax  ;fixe 3d-x 
  388.   mov ax,[si+Points3d-Points+2] ;lit 3d-y 
  389.   mov es:[di+poly3d-poly2d+2],ax;fixe 3d-y 
  390.   mov ax,[si+Points3d-Points+4] ;lit 3d-z
  391.   mov es:[di+poly3d-poly2d+4],ax;fixe 3d-z
  392.  
  393.   movsw             ;fixe les coordonnées 2D
  394.   movsw
  395.  
  396.   add di,4          ;entrée suivante Poly2d
  397.   dec cx            ;tous les sommets ?
  398.   jne npoint
  399.  
  400.   mov bp,polyn      ;copie le premier sommet sur le dernier
  401.   shl bp,3          ;se positionne sur le premier point
  402.   neg bp
  403.   mov ax,es:[di+bp] ;et effectue la copie
  404.   mov es:[di],ax
  405.   mov ax,es:[di+bp+2]
  406.   mov es:[di+2],ax
  407.  
  408.   add di,poly3d-poly2d          ;idem pour les coordonnées 3d
  409.   mov ax,es:[di+bp]             ;effectue la copie 
  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 Remplir,1                 ;remplir la face ?
  417.   jne lines
  418.  
  419.   getdelta                      ;oui alors on calcule Delta1 et 2 
  420.   cmp b lightsrc,0              ;source de lumière ?
  421.   jne delombre
  422.   jmp no_lumiere
  423.  
  424. delombre:                       ;oui
  425.   push bx
  426.   get_normal                    ;alos calcule le vecteur normal
  427.   light                         ;et la luminosité
  428.   pop bx
  429.  
  430. no_lumiere:
  431.   inc polyn                     ;incrémente le nombre de sommets
  432.   call fillpol                  ;dessine la face
  433.  
  434. next:
  435.   add bx,4                      ;cap sur la face suivante
  436.   cmp moyen[bx],0               ;est-ce la dernière ?
  437.   je _npoly_draw                ;non on continue
  438.   jmp npoly_draw
  439.  
  440. lines:
  441.   push bx
  442.   call drawpol                  ;dessine le polygone
  443.   pop bx
  444.   jmp next
  445.  
  446. _npoly_draw:
  447.   pop bp                        ;c'est terminé
  448.   pop es
  449.   pop ds
  450.   ret
  451. drawworld endp
  452.  
  453.  
  454. public quicksort
  455. quicksort proc pascal bas,haut:word
  456. ;trie le tableau moyen avec l'algorithme Quicksort
  457.  
  458. local cle:word
  459. local gauche:word
  460.   push bx
  461.   mov bx,bas                    ;trouve le milieu
  462.   add bx,haut
  463.   shr bx,1
  464.   and bx,not 3                  ;positionnement sur groupe de 4 
  465.   mov dx,moyen[bx]              ;lit la clé
  466.   mov cle,dx
  467.   mov  ax,bas               ;initialise droite et gauche avec valeurs de base
  468.   mov si,ax
  469.   mov gauche,ax
  470.   mov ax,haut
  471.   mov di,ax
  472.  
  473.   mov dx,cle
  474. gauche_pluspres:
  475.   cmp moyen[si],dx           ;plus grand que clé -> on continue la recherche
  476.   jbe a_gauche
  477.   add si,4                      ;position suivante
  478.   jmp gauche_pluspres           ;on la teste
  479. a_gauche:
  480.   cmp moyen[di],dx         ;plus petit que la clé -> on continue la recherche
  481.   jae a_droite
  482.   sub di,4                      ;position suivante
  483.   jmp a_gauche                  ;on la teste
  484. a_droite:
  485.   cmp si,di                     ;gauche <= droite ?
  486.   jg finbou                     ;non -> partie triée
  487.   mov eax,dword ptr moyen[si]   ;échange les valeurs moyennes et les positions
  488.   xchg eax,dword ptr moyen[di]
  489.   mov dword ptr moyen[si],eax
  490.  
  491.   add si,4                      ;avance le pointeur
  492.   sub di,4
  493. finbou:
  494.   cmp si,di                     ;gauche > droite , alors on continue
  495.   jle gauche_pluspres
  496.   mov gauche,si                 ;sauve gauche à cause récursion
  497.   cmp bas,di                    ;bas < droite -> partie gauche triée
  498.   jge droite_fini
  499.   call quicksort pascal,bas,di;diviser par deux récursivt, poursuivre le tri
  500. droite_fini:
  501.   mov si,gauche                 ;haut > gauche -> partie droite triée
  502.   cmp haut,si
  503.   jle gauche_fini
  504.   call quicksort pascal,si,haut ;diviser par deux récursivt, poursuivre le tri
  505. gauche_fini:
  506.   pop bx
  507.   ret
  508. quicksort endp
  509.  
  510. code ends
  511. end
  512.  
  513.