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

  1. .286
  2. w equ word ptr
  3. b equ byte ptr
  4.  
  5. include texture.inc             ;inclut les macros de texture
  6.  
  7. setnewlinel macro               ;n'utiliser ici que ax et bx!
  8. local dylpos,dxlpos,dxlgrand,macro_fini
  9.   mov bx,4043h                  ;code pour inc ax (en bh) et inc bx (en bl)
  10.   mov bp,gauche
  11.   mov ax,poly2d[bp+8]           ;sauvegarde les coordonnées de destination
  12.   mov xl1,ax
  13.   mov ax,poly2d[bp+10d]
  14.   mov yl1,ax
  15.  
  16.   mov ax,poly2d[bp]             ;x,y début gauche dans var glob
  17.   mov xl0,ax
  18.   sub ax,xl1                    ;forme delta x 
  19.   inc xl1                       ;pour la condition d'arrêt
  20.   neg ax                        ;xl1-xl0
  21.   jns dxlpos                    ;dxl négatif ?
  22.   neg ax                        ;alors valeur absolue
  23.   mov bh,48h                    ;code pour dec ax (dec xl0)
  24.   sub xl1,2                ;extension négative des coordonnées de destination
  25. dxlpos:
  26.   mov dxl,ax                    ;sauvegarde glob. 
  27.   mov incflagl,ax               ;mémorise dans l'indicateur d'incrémentation
  28.   mov ax,poly2d[bp+2]
  29.   mov yl0,ax
  30.   sub ax,yl1                    ;forme |delta y|
  31.   inc yl1                       ;pour la condition d'arrêt
  32.   neg ax
  33.   jns dylpos                    ;négatif ?
  34.   neg ax                        ;alors valeur absolue
  35.   mov bl,4bh                    ;code pour dec bx (dec yl1)
  36.   sub yl1,2                ;extension négative des coordonnées de destination
  37. dylpos:
  38.   mov dyl,ax                    ;sauvegarde glob.
  39.   cmp dxl,ax                    ;dx < dy
  40.   jae dxlgrand
  41.   neg incflagl        ;changement de signe pour l'indicateur d'incrémentation
  42. dxlgrand:
  43.   mov cs:byte ptr incxl,bh      ;effectuer l'automodification
  44.   mov cs:byte ptr incyl,bl
  45.  
  46.   cmp texture,1                 ;besoin de texture  ?
  47.   jne macro_fini                ;non, on passe
  48.  
  49.   txt_makevarl                  ;sinon calcule les variables de texture
  50.  
  51. macro_fini:
  52.   mov ax,xl0                    
  53.   mov bx,yl0
  54.   mov si,incflagl
  55. endm
  56.  
  57. setnewliner macro               ;n'utiliser ici que cx et dx!
  58. local dyrpos,dxrpos,dxrgrand,macro_fini
  59.   mov cx,4142h                  ;code pour inc cx (en ch) et inc dx (en cl)
  60.   mov bp,droite
  61.   mov dx,poly2d[bp]             ;lit les coordonnées de destination
  62.   mov xr1,dx
  63.   mov dx,poly2d[bp+2]
  64.   mov yr1,dx
  65.   mov dx,poly2d[bp+8]           ;x,y à droite dans var glob. 
  66.   mov xr0,dx
  67.   sub dx,xr1                    ;forme |delta x| 
  68.   inc xr1                       ;pour la condition d'arrêt
  69.   neg dx
  70.   jns dxrpos                    ;négatif ?
  71.   neg dx                        ;opposé
  72.   mov ch,49h                    ;code pour dec cx
  73.   sub xr1,2                ;extension négative des coordonnées de destination
  74. dxrpos:
  75.   mov dxr,dx                    ;sauvegarde en var glob
  76.   mov incflagr,dx
  77.   mov dx,poly2d[bp+10d]         ;forme |delta y|
  78.   mov yr0,dx
  79.   sub dx,yr1
  80.   inc yr1                       ;pour la condition d'arrêt
  81.   neg dx
  82.   jns dyrpos                    ;négatif ?
  83.   neg dx                        ;opposé
  84.   mov cl,4ah                    ;code pour dec dx
  85.   sub yr1,2               ;extension négative des coordonnnées de destination
  86. dyrpos:
  87.   mov dyr,dx                    ;sauvegarde en var glob
  88.   cmp dxr,dx                    ;dx < dy ?
  89.   jae dxrgrand
  90.   neg incflagr  ;alors changement de signe pour l'indicateur d'incrémentation
  91. dxrgrand:
  92.   mov cs:byte ptr incxr,ch      ;automodification
  93.   mov cs:byte ptr incyr,cl
  94.  
  95.   cmp texture,1                 ;besoin de texture ?
  96.   jne macro_fini                ;non, on passe
  97.  
  98.   txt_makevarr                  ;sinon calcule variables de texture
  99.  
  100. macro_fini:
  101.   mov cx,xr0                    ;charge les registres
  102.   mov dx,yr0
  103.   mov di,incflagr
  104. endm
  105.  
  106. data segment public
  107.   extrn vpage:word              ;page d'écran courante
  108.   extrn su_cacher               ;indicateur pour dessin des faces cachées
  109.   extrn verre:Byte;             ;indicateur pour surfaces en verre
  110.  
  111. ;variables de texture :
  112.   extrn Texture:Byte            ;besoin de texture ?
  113.   extrn Txt_Data:DataPtr        ;tableau de pointeurs sur données graphiques
  114.   extrn Txt_Offs:DataPtr        ;tableau d'offsets à l'intérieur de l'image de texture
  115.   extrn Txt_Taille:DataPtr   ;tableau avec indications de dimensions 
  116.  
  117. d_x  dd 0                       ;abscisse relative 
  118. d_y dd 0                        ;ordonnée relative
  119. D    dd 0                       ;déterminant principal
  120. Colonne1 dd 0                   ;composants du déterminant principal
  121.         dd 0
  122. Colonne2 dd 0
  123.         dd 0
  124. ligne_sup dw 0                  ;quelles sont les coordonnées utilisées ?
  125. Ligne_inf dw 0
  126.  
  127. xl_3d dd 0    ;valeurs courantes des coordonnées 3d pendant le remplissage
  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                     ;valeurs à ajouter aux coordonnées courantes
  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 pour l'algorithme de remplissage
  142. point_haut   dw 0               ;maintenu en dx pendant la recherche
  143. y_haut      dw 0                ;maintenu en bx
  144.  
  145. gauche        dw 0              ;point du côté gauche
  146. droite      dw 0                ;point du côté droit
  147.  
  148. xl0  dw 0      ;valeurs courantes des points de début et de fin à gauche
  149. yl0 dw 0
  150. xl1 dw 0
  151. yl1 dw 0
  152. xr0 dw 0                        ;idem à droite
  153. yr0 dw 0
  154. xr1 dw 0
  155. yr1 dw 0
  156. dxl dw 0                        ;Delta X, Y pour les deux côtés
  157. dyl dw 0
  158. dxr dw 0
  159. dyr dw 0
  160. incflagl dw 0           ;indicateurs pour savoir quand y doit être incrémenté
  161. incflagr dw 0                   ;sorte de "pente"
  162.  
  163. data ends
  164.  
  165. code segment public
  166. assume cs:code,ds:data
  167. extrn polycol:word              ;couleur de surface
  168. extrn polyn:word                ;nombre de sommets
  169. extrn poly2d:word               ;tableau de coordonnées 2D
  170. extrn poly3d:word               ;tableau de coordonnées 3-D
  171. extrn delta1,delta2:word        ;vecteurs de plan
  172. extrn bline:near                ;dessine un segment
  173.  
  174. lambda1 dd 0                    ;coordonnées affines
  175. lambda2 dd 0
  176.  
  177. inc_lambda1 dd 0                ;pas d'incrémentation
  178. inc_lambda2 dd 0
  179.  
  180. plane dw 0002h                  ;plan courant à fixer
  181. x0 dw 0                         ;coordonnées de segment
  182. y0 dw 0
  183. x1 dw 0
  184. zz dw 0                         ;points restant à tracer
  185.  
  186. extrn Txt_Nr:Word               ;numéro de la texture à dessiner
  187.  
  188. public drawpol
  189. ;dessine un modèle en fil de fer des faces en Poly2d
  190. drawpol proc near
  191.   push es
  192.   pusha
  193.   xor si,si                     ;indice sur première entrée
  194.   mov bp,polyn                  ;lit le nombre de sommets
  195. @nline:
  196.   mov ax,poly2d[si]             ;lit les coordonnées dans la 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                    ;dessine un segment
  203.   pop si
  204.   pop bp
  205.   add si,8                      ;segment suivant
  206.   dec bp                        ;décrémente le nombre
  207.   jne @nline
  208.   popa
  209.   pop es
  210.   ret
  211. drawpol endp
  212.  
  213. hline proc near                 ;trace un segment horizontal ax,bx -> cx,bx
  214.   pusha
  215.   push es
  216.   mov x0,ax                     ;sauve les coordonnées pour usage ultérieur
  217.   mov y0,bx
  218.   mov x1,cx
  219.   sub cx,ax                     ;calcule le nombre de points à dessiner
  220.   jne zzok
  221.   inc cx
  222.  
  223. zzok:
  224.   mov zz,cx
  225.                                                   
  226.   cmp verre,1                   ;surface de verre ?
  227.   jne Solid1
  228.   push ax                       ;oui alors mode GDC : OR
  229.   mov dx,3ceh
  230.   mov ax,1003h                  ;registre 3: Function Select
  231.   out dx,ax
  232.   pop ax
  233.  
  234. Solid1:
  235.   mov dx,3c4h                   ;port du Timing Sequencer
  236.   mov di,0a000h
  237.   mov es,di                     ;sélectionne le segment VGA
  238.   mov di,ax                     ;calcule l'offset
  239.   shr di,2                      ;(x div 4) + y*80
  240.   add di,vpage                  ;ajoute la page courante
  241.   mov bx,y0
  242.   imul bx,80d
  243.   add di,bx                     ;le tout dans di
  244.   cmp zz,4
  245.   jl no_moyen                   ;< 4 points à dessiner -> pas de groupe de 4
  246.   and ax,11b                    ;les deux bits inférieurs sont importants
  247.   je milieu                     ;si 0 fixe immédiatement des groupes de 4
  248. no_moyen:
  249.   mov bx,0f02h                  ;si no_shift, utiliser ce masque
  250.   mov cx,zz                     ;fixe le nombre de points dans masque
  251.   cmp cx,20h                    ;à partir de 20h le 386 dérape au décalage !
  252.   jae no_shift
  253.   mov bx,0102h                  ;prépare le masque
  254.   shl bh,cl                  ;nombre de points = nombre de bits à mettre à 1
  255.   dec bh
  256.   and bh,0fh
  257. no_shift:
  258.   mov cx,ax                     ;le bon décalage selon le plan de début
  259.   and cl,3
  260.   shl bh,cl
  261.   mov ax,bx                     ;le masque est fini
  262.   sub zz,4                      ;décrémente le nombre de points à dessiner
  263.   add zz,cx
  264. start:
  265.   out dx,ax                     ;installe le masque d'écriture calculé
  266.   mov al,b polycol              ;lit la couleur
  267.  
  268.   mov ah,es:[di]                ;charge les bascules, uniqt objets en verre
  269.  
  270.   stosb                         ;installe un octet
  271. milieu:
  272.   cmp zz,4
  273.   jl termine                    ;plus de groupe de 4 -> terminus 
  274.  
  275.   mov ax,0f02h                  ;prend tous les plans
  276.   out dx,ax                     ;(zz div 4) calcule les groupes de 4
  277.   mov cx,zz
  278.   shr cx,2
  279.   mov al,b polycol
  280.  
  281.   cmp verre,1                    ;face en verre ?
  282.   jne Solid
  283.  
  284. @lp:
  285.   mov ah,es:[di]                ;charge les bascules, uniqmt objets en verre
  286.   stosb                         ;et réécrit un octet
  287.   dec cx
  288.   jne @lp
  289.   jmp termine
  290.  
  291. Solid:
  292.   rep stosb                     ;dessine la partie du milieu
  293.  
  294. termine:
  295.   mov cx,x1                     ;dessine les pixels restants
  296.   and cx,3h
  297.   dec zz
  298.   js hline_fini                 ;si plus rien -> c'est fini
  299.   mov ax,0102h
  300.   shl ah,cl                     ;crée le masque
  301.   dec ah
  302.   out dx,ax
  303.   mov al,b polycol              ;lit la couleur 
  304.  
  305.   mov ah,es:[di]                ;charge les bascules, uniqmt objets en verre 
  306.  
  307.   stosb                         ;et dessine les points
  308. hline_fini:
  309.   mov dx,3ceh                   ;GDC Mode en position MOVE
  310.   mov ax,0003h
  311.   out dx,ax
  312.   pop es
  313.   popa
  314.   ret
  315. hline endp
  316.  
  317. txt_hline                       ;macro contenant la procédure  "hline_texture"
  318.  
  319. public fillpol
  320. fillpol proc near               ;remplit un polygone en mode X
  321.   push bp
  322.   pusha
  323.  
  324.   cmp texture,1                 ;utilise-t-on des textures?
  325.   jne Remplir                   ;non, remplissage simple
  326.  
  327.   txt_Detprinc                  ;sinon calcule le déterminant principal 
  328.  
  329. Remplir:
  330.   xor si,si             ;recherche le point le plus haut, sél première entrée
  331.   mov cx,polyn                  ;nombre de sommets
  332.   sub cx,2
  333.   mov bx,0ffffh                 ;valeur extrême, interdite
  334. npoint:
  335.   mov ax,poly2d[si+2]           ;lit y 
  336.   cmp ax,bx                     ;compare au minimum courant
  337.   ja  no_min
  338.   mov bx,ax                     ;fixe un nouveau minimum
  339.   mov dx,si
  340. no_min:
  341.   add si,8
  342.   dec cx                        ;sommet suivant, si pas 0ffffh
  343.   jns npoint
  344.   mov point_haut,dx             ;sauve en variable globale
  345.   mov y_haut,bx                 ;recherche du point le plus haut achevée
  346.  
  347.   or dx,dx                      ;gauche = 0 ?
  348.   jne dec_valid
  349.   mov bx,polyn                  ;oui : positionner à droite
  350.   sub bx,2
  351.   shl bx,3
  352.   jmp lr_fini                   ;à l'autre extrémité
  353. dec_valid:
  354.   mov bx,dx                     ;sinon un de moins
  355.   sub bx,8
  356. lr_fini:
  357.   mov gauche,dx                 ;sauve en variable globale
  358.   mov droite,bx
  359.  
  360. ; ax,bx : coordonnées de départ gauche (xl0,yl0)
  361. ; cx/dx : coordonnées de départ droite (xr0,yr0)
  362. ; si    : indicateur de débordement gauche
  363. ; di    : indicateur de débordement droite
  364. ; bp    : pointeur sur point courant
  365.  
  366.   setnewlinel                   ;charges les variables des segments
  367.   setnewliner
  368.  
  369. boucleg:
  370.   cmp ax,xl1
  371.   je nouv_ligneg                ;si fini -> nouveau segment
  372.   cmp bx,yl1
  373.   je nouv_ligneg                ;sinon poursuite du dessin
  374.  
  375.   or si,si                      ;indicateur d'incrémentation <= 0
  376.   jg flaglgrand
  377. incyl:                          ;ce passage va être modifié !
  378.   inc bx                        ;y suivant
  379.   add si,dxl                    ;incrémente l'indicateur IncFlag 
  380.  
  381.   txt_incl                      ;coordonnées 3D suivantes
  382.  
  383.   cmp bx,yl1                    ;destination atteinte ?
  384.   je nouv_ligneg                ;alors nouveau segment
  385.   jmp gauche_plus               ;y augmenté à gauche -> maintenant à droite
  386. flaglgrand:
  387.   sub si,dyl                    ;décrémente Incflag 
  388. incxl:                          ;ce passage va être modifié  !
  389.   inc ax                        ;x suivant 
  390.   jmp boucleg
  391.  
  392. fini__:
  393.   jmp fini
  394.  
  395. nouv_ligneg:
  396.   mov bx,gauche                 ;prépare l'augmentation
  397.   cmp bx,droite
  398.   je fini__                     ;identique, alors fini
  399.   add bx,8                      ;gauche suivant
  400.   mov ax,polyn                  ;gauche en fin de liste ?
  401.   shl ax,3
  402.   sub ax,8                      ;détermine la fin
  403.   cmp bx,ax                     ;comparaison
  404.   jb fixer_gauche
  405.   xor bx,bx                     ;si oui, alors mise à 0
  406. fixer_gauche:
  407.   mov gauche,bx
  408.   setnewlinel                   ;recharge les variables
  409.   jmp boucleg
  410. fini_:
  411.   jmp fini
  412. gauche_plus:
  413.  
  414. boucled:
  415.   cmp cx,xr1
  416.   je nouv_ligned                ;si fin -> fixe un nouveau segment
  417.   cmp dx,yr1
  418.   je nouv_ligned                ;sinon poursuit
  419.  
  420.   or di,di                      ;indicateur d'incrémentation <= 0
  421.   jg flagrgrand
  422. incyr:                          ;ce passage va être modifié !
  423.   inc dx                        ;y suivant
  424.   add di,dxr                    ;incrémente IncFlag 
  425.  
  426.   txt_incr
  427.  
  428.   cmp dx,yr1                    ;destination atteinte ?
  429.   je nouv_ligned                ;alors nouveau segment
  430.   jmp droite_plus       ;à droite y a été augmenté -> trace le segment horiz
  431. flagrgrand:
  432.   sub di,dyr                    ;décrémente Incflag
  433. incxr:
  434.   inc cx                        ;ce passage va être modifié!
  435.   jmp boucled
  436.  
  437. nouv_ligned:
  438.   mov dx,droite                 ;prépare la diminution
  439.   cmp dx,gauche
  440.   je fini_                      ;si égal, alors fini
  441.   sub dx,8                      ;si précédmt à 0 -> passe à l'autre extrémité
  442.   jns fixer_droite
  443.   mov dx,polyn
  444.   sub dx,2
  445.   shl dx,3                      ;se positionne à l'extrémité
  446. fixer_droite:
  447.   mov droite,dx
  448.  
  449.   setnewliner                   ;recharge les variables 
  450.   jmp boucled
  451.  
  452. droite_plus:
  453.   push ax
  454.   push cx
  455.   cmp cx,ax                     ;ordre correct ?
  456.   jae direct_ok                 ;alors ok, sinon:
  457.   cmp w su_cacher,0             ;dissimuler les faces cachées?
  458.   je dessiner                   ;non, alors on dessine quand même
  459.   pop cx
  460.   pop ax
  461.   jmp fini                      ;polygone non dessiné
  462. dessiner:
  463.   xchg ax,cx                    ;coordonnées dans le bon ordre
  464. direct_ok:
  465.  
  466.   cmp texture,1                 ;a-t-on une texture ?
  467.   jne remp_norm                 ;non, alors remplissage normal
  468.   call hline_texture            ;dessine segment de texture horizontal
  469.   pop cx
  470.   pop ax
  471.   jmp boucleg                   ;et on continue 
  472. remp_norm:
  473.   call hline                    ;dessine segment horizontal
  474.   pop cx
  475.   pop ax
  476.   jmp boucleg                   ;et on continue
  477. fini:
  478.   popa
  479.   pop bp
  480.   ret
  481. fillpol endp
  482. code ends
  483. end
  484.  
  485.