home *** CD-ROM | disk | FTP | other *** search
/ Hot Shareware 32 / hot34.iso / ficheros / VDOC / NOME6.ZIP / REGALOS / VECTFIRE.ARJ / VECTFIRE / VECTFIRE.PAS < prev   
Pascal/Delphi Source File  |  1997-07-23  |  24KB  |  730 lines

  1. {$F-,O-,A+,G+,Q-,R-,S+,I+,V+,B-,X+,P-,T-,D+,L+,N+,E-}
  2. {ESTA ES LA 2º VERSION DEL EFECTO FUEGO. EL PROCEDIMIENTO HA SIDO MEJORADO
  3. POR SANTIAGO ROMERO AKA [NoP]. Pues sean para el todos los meritos!!!.
  4.  
  5. -Nombre del programa:VECTFIRE.EXE
  6. -Lenguaje:Pascal.
  7. -Compilador:Turbo Pascal v7.0 (16 bits)
  8. -Librerias que se usan:ninguna.
  9. -Archivos externos:BLUR.SCR:imagen de fondo en formato crudo.
  10.                    BLUR.PAL:paleta de dicha imagen.
  11. -Autor:Jose Antonio Dieguez Alonso. AKA [Se7eN]. Miembro de Capsule Corporation.
  12. -Direccion@:Rambla Marina nº 366-8º-1º. CP:08907 Hospitalet del Llobregat (BARNA)
  13. -Que hace?:Pues bien, chicos y chicas. Aqui teneis el famoso efecto llamado
  14.  BlurMotion. Y vosotros direis BLUR que?. Sinceramente, creo que es uno de
  15.  los efectos mas impresionantes para el poco codigo que ocupa, ya que no
  16.  hay enormes trozos en ensamblador (grrr!!! ensamblador, que chungo!!! ;-)
  17.  y la velocidad es tremendamente suave. Dicho efecto esta basado en una pa-
  18.  leta especialmete preparada. El efecto en cuestion realiza un degradado
  19.  descendente de la paleta. Bien, y vosotros direis, pues que bien, y que
  20.  puedo hacer con esto?. Pues aqui estoy yo para daros ideas!!! ;-). Segu-
  21.  ramente abreis visto alguna vez un cubo o un toroide rotando, hecho a base
  22.  de lineas (modo wireframe). Seguramente abreis visto que dicho cubo o
  23.  toroide empezaba a arder. Pues bien, ese efecto de fuego sobre el cubo
  24.  es nada mas y nada menos que aplicar el efecto BlurMotion a dicho poliedro.
  25.  Y vosotros estareis pensando,.....si que debe ser dificil hacer ese efecto..
  26.  Pues nada mas lejos de la realidad. El efecto en cuestion son unas 20 lineas
  27.  en ASM, pero el truco esta en la paleta preparada. Mira al final de este
  28.  fichero y encontraras mas informacion. ;-)
  29. -Posibles mejoras:Rotar un poligono con el mismo efecto pero sobre una
  30. imagen de fondo dentro de la zona donde arde el poligono y no como en este
  31. ejemplo, donde el poligono arde pero con un fondo siempre del mismo color
  32. (en este caso negro).
  33. -Nota:la rutina de rotacion del poliedro es la que se incluyo en la revista
  34. PCmania, aunque los procedimientos que dibujan las lineas estan hechas en
  35. ASM para una mayor velocidad.
  36. ///////////////////////////////////////////////////////////////////////////}
  37. PROGRAM VECTFIRE;
  38. {//////////////////////////////////////////////////////////////////////////}
  39. {///////////// definicion de constantes, variables y tipos ////////////////}
  40. CONST
  41.     VIDEO:WORD=$0A000;     {segmento de video de la VGA}
  42.     velx=4;                {velocidad de giro en las coordenadas x,y,z}
  43.     vely=2;
  44.     velz=3;
  45. TYPE
  46.     est_puntos = ARRAY [1..500,0..2] of integer;  {coordenadas X,Y,Z de los puntos}
  47.     est_lineas = ARRAY [1..1000,0..1] of integer;
  48.  
  49. VAR
  50.     Total_puntos   : integer;
  51.     Total_lineas   : integer;
  52.     donut          : est_puntos;
  53.     Rotado         : est_puntos;
  54.     lineas         : est_lineas;
  55.     xdeg,ydeg,zdeg : word;            {incrementos en los ejes}
  56.     xoff,yoff,zoff : integer;         {posiciones relativas}
  57.     sen,cosen      : ARRAY [0..360] of integer;  {tablas para los senos y cosenos}
  58.     Mezclas        : Pointer;         {puntero donde se ''QEMARA'' el donut}
  59.     segm           : word;            {segmento para el puntero anterior}
  60.  
  61. {//////////// fin de declaracion de constantes,variables y tipos///////////}
  62. {//////////////////////////////////////////////////////////////////////////}
  63. function keypressed : boolean; assembler;
  64. {//////////////////////////////////////////////////////////////////////////}
  65. {devuelve TRUE si se ha pulsado una tecla. Asi nos ahorramos tener que
  66. incluir la unit CRT}
  67. asm
  68.   mov ah,0bh
  69.   int 21h
  70.   and al,0feh
  71. end;
  72. {//////////////////////////////////////////////////////////////////////////}
  73. PROCEDURE Set_vga; ASSEMBLER;
  74. {//////////////////////////////////////////////////////////////////////////}
  75. {pasa a modo13h, es decir a 320 x 200 a 256 colores}
  76. ASM
  77.    mov ax,13h
  78.    int 10h
  79. END;
  80. {//////////////////////////////////////////////////////////////////////////}
  81. PROCEDURE Set_text; ASSEMBLER;
  82. {//////////////////////////////////////////////////////////////////////////}
  83. {pasa a modo texto, 80 x 25 columnas}
  84. ASM
  85.    mov ax,3h
  86.    int 10h
  87. END;
  88. {//////////////////////////////////////////////////////////////////////////}
  89. PROCEDURE SetColor(Nr,R,G,B:Byte);
  90. {//////////////////////////////////////////////////////////////////////////}
  91. {Actualiza el color Nr, con las componentes R (ROJA), G (VERDE) y B (AZUL)
  92. indicadas}
  93. BEGIN
  94.      Port[$3C8]:=Nr;
  95.      Port[$3C9]:=R;
  96.      Port[$3C9]:=G;
  97.      Port[$3C9]:=B;
  98. END;
  99. {//////////////////////////////////////////////////////////////////////////}
  100. PROCEDURE CargaPaleta(Fichero_Pal:String);
  101. {//////////////////////////////////////////////////////////////////////////}
  102. {carga y establece la paleta que se encuentra en el fichero *.PAL}
  103. VAR
  104.    FichPal:File;
  105.    RGB:ARRAY[0..255,1..3] OF Byte;
  106.    I:Byte;
  107. BEGIN
  108.      Assign(FichPal,Fichero_Pal+'.PAL');
  109.      Reset(FichPal,1);
  110.      BlockRead(FichPal,RGB,768);
  111.      FOR I:=0 TO 255 DO SetColor(I,RGB[I,1],RGB[I,2],RGB[I,3]);
  112.      Close(FichPal);
  113. END;
  114. {//////////////////////////////////////////////////////////////////////////}
  115. PROCEDURE CargaCrudo(nombre:string);
  116. {//////////////////////////////////////////////////////////////////////////}
  117. {carga el dibujo de formato lineal.Se  aprovecha el mismo puntero Mezclas
  118. para cargar el dibujo, ya que no se va almacenar para nada y solamente se
  119. va ha volcar a video}
  120. VAR
  121.    FichCrudo:File;
  122. BEGIN
  123.      Assign(FichCrudo,nombre+'.SCR');
  124.      Reset(FichCrudo,1);
  125.      BlockRead(FichCrudo,mezclas^,64000);
  126.      move(mezclas^,mem[Video:0],64000);    {muestra la imagen en pantalla}
  127.      Close(FichCrudo);
  128. END;
  129. {//////////////////////////////////////////////////////////////////////////}
  130. PROCEDURE WaitRetrace; ASSEMBLER;
  131. {//////////////////////////////////////////////////////////////////////////}
  132. {espera al retrazado vertical del monitor. Se usa para eliminar el parpadeo
  133. y sincronizar el volcado a video}
  134. ASM
  135.     mov dx,3DAh
  136. @l1:
  137.     in al,dx
  138.     and al,08h
  139.     jnz @l1
  140. @l2:
  141.     in al,dx
  142.     and al,08h
  143.     jz  @l2
  144. END;
  145. {//////////////////////////////////////////////////////////////////////////}
  146. PROCEDURE PutPixel   (SegDes:Word;X,Y:Integer;Color:byte);assembler;
  147. {//////////////////////////////////////////////////////////////////////////}
  148. {se pone un pixel en el segmento (SegDes) indicado. si el  segmento es $A000
  149. lo colocamos directamente en la pantalla}
  150. Asm
  151.   cmp  X,0                   {si los valores estan fuera de los limites}
  152.   jl   @@End                 {de 320 x 200 no se pinta el pixel}
  153.   cmp  Y,0
  154.   jl   @@End
  155.   cmp  X,319
  156.   jg   @@End
  157.   cmp  Y,199
  158.   jg   @@End
  159.   mov  ax,SegDes
  160.   mov  es,ax
  161.   mov  al,Color
  162.   mov  di,Y
  163.   mov  bx,X
  164.   mov  dx,di
  165.   xchg dh,dl
  166.   shl  di,6
  167.   add  di,dx
  168.   add  di,bx
  169.   mov  es:[di],al
  170. @@End:
  171. End;
  172. {//////////////////////////////////////////////////////////////////////////}
  173. PROCEDURE DrawLineH(SegDes,X1,X2,Y1:Word; Color:Byte);assembler;
  174. {//////////////////////////////////////////////////////////////////////////}
  175. {se dibuja una linea horizontal en segmento indicado}
  176. Asm
  177.   mov  ax,SegDes
  178.   mov  es,ax
  179.   mov  ax,y1
  180.   mov  di,ax
  181.   shl  di,1
  182.   shl  di,1
  183.   add  di,ax
  184.   mov  cl,6
  185.   shl  di,cl
  186.   mov  bx,x1
  187.   mov  dx,x2
  188.   cmp  bx,dx
  189.   jl   @@1
  190.   xchg bx,dx
  191. @@1:
  192.   inc  dx
  193.   add  di,bx
  194.   mov  cx,dx
  195.   sub  cx,bx
  196.   shr  cx,1
  197.   mov  al,Color
  198.   mov  ah,al
  199.   ror  bx,1
  200.   jnb  @@2
  201.   mov  es:[di],al
  202.   inc  di
  203.   ror  dx,1
  204.   jnb  @@3
  205.   dec  cx
  206. @@3:
  207.   rol  dx,1
  208. @@2:
  209.   rep  stosw
  210.   ror  dx,1
  211.   jnb  @@4
  212.   mov  es:[di],al
  213.   inc  di
  214. @@4:
  215. End;
  216. {//////////////////////////////////////////////////////////////////////////}
  217. PROCEDURE DrawLineV(SegDes,X1,Y1,Y2:Word; Color:Byte);assembler;
  218. {//////////////////////////////////////////////////////////////////////////}
  219. {se dibuja una.....SI..una linea vertical en el segmento indicado :-) }
  220. Asm
  221.   mov  ax,x1
  222.   mov  bx,y1
  223.   mov  dx,y2
  224.   cmp  bx,dx
  225.   jl   @@1
  226.   xchg bx,dx
  227. @@1:
  228.   mov  di,bx
  229.   shl  di,1
  230.   shl  di,1
  231.   add  di,bx
  232.   mov  cl,6
  233.   shl  di,cl
  234.   add  di,ax
  235.   mov  cx,SegDes
  236.   mov  es,cx
  237.   mov  cx,dx
  238.   sub  cx,bx
  239.   inc  cx
  240.   mov  al,Color
  241.   mov  bx,319
  242. @@2:
  243.   mov  es:[di],al
  244.   inc  di
  245.   add  di,bx
  246.   loop @@2
  247. End;
  248. {//////////////////////////////////////////////////////////////////////////}
  249. Procedure DrawLine(SegDes:Word;X1,Y1,X2,Y2:Integer; Color:Byte);assembler;
  250. {//////////////////////////////////////////////////////////////////////////}
  251. {se dibuja una linea en el segemnto indicado. Se usan los procedimientos
  252. Putpixel, drawlineH y drawlineV.}
  253. Asm
  254.   mov  al,Color
  255.   xor  ah,ah
  256.   mov  si,ax
  257.   mov  ax,x1
  258.   cmp  ax,319
  259.   ja  @@TheEnd
  260.   mov  bx,x2
  261.   cmp  bx,319
  262.   ja   @@TheEnd
  263.   mov  cx,y1
  264.   cmp  cx,199
  265.   ja   @@TheEnd
  266.   mov  dx,y2
  267.   cmp  dx,199
  268.   ja   @@TheEnd
  269.   cmp  ax,bx
  270.   jnz  @@Horizontal
  271.   cmp  cx,dx
  272.   jnz  @@vertical
  273.   push SegDes
  274.   push ax
  275.   push cx
  276.   push si
  277.   call Putpixel
  278.   jmp  @@TheEnd
  279. @@Horizontal:
  280.   cmp  cx,dx
  281.   jnz  @@Horizontal2
  282.   push SegDes
  283.   push ax
  284.   push bx
  285.   push cx
  286.   push si
  287.   call DrawLineH
  288.   jmp  @@TheEnd
  289. @@Vertical:
  290.   push SegDes
  291.   push ax
  292.   push cx
  293.   push dx
  294.   push si
  295.   call DrawLineV
  296.   jmp @@TheEnd
  297. @@Horizontal2:
  298.   cmp  cx,dx
  299.   jbe  @@1
  300.   xchg cx,dx
  301.   xchg ax,bx
  302. @@1:
  303.   mov  di,cx
  304.   shl  di,1
  305.   shl  di,1
  306.   add  di,cx
  307.   push si
  308.   mov  si,bx
  309.   mov  bx,dx
  310.   sub  bx,cx
  311.   mov  cl,06
  312.   shl  di,cl
  313.   add  di,ax
  314.   mov  dx,si
  315.   pop  si
  316.   sub  dx,ax
  317.   mov  ax,SegDes
  318.   mov  es,ax
  319.   mov  ax,si
  320.   push bp
  321.   or   dx,0
  322.   jge  @@Jmp1
  323.   neg  dx
  324.   cmp  dx,bx
  325.   jbe  @@Jmp3
  326.   mov  cx,dx
  327.   inc  cx
  328.   mov  si,dx
  329.   shr  si,1
  330.   std
  331.   mov  bp,320
  332. @@1c:
  333.   stosb
  334. @@1b:
  335.   or   si,si
  336.   jge  @@1a
  337.   add  di,bp
  338.   add  si,dx
  339.   jmp  @@1b
  340. @@1a:
  341.   sub  si,bx
  342.   loop @@1c
  343.   jmp  @@TheEnd2
  344. @@Jmp3:
  345.   mov  cx,bx
  346.   inc  cx
  347.   mov  si,bx
  348.   neg  si
  349.   sar  si,1
  350.   cld
  351.   mov  bp,319
  352. @@2c:
  353.   stosb
  354. @@2b:
  355.   or   si,si
  356.   jl   @@2a
  357.   sub  si,bx
  358.   dec  di
  359.   jmp  @@2b
  360. @@2a:
  361.   add  di,bp
  362.   add  si,dx
  363.   loop @@2c
  364.   jmp  @@TheEnd2
  365. @@Jmp1:
  366.   cmp  dx,bx
  367.   jbe  @@Jmp4
  368.   mov  cx,dx
  369.   inc  cx
  370.   mov  si,dx
  371.   shr  si,1
  372.   cld
  373.   mov  bp,320
  374. @@3c:
  375.   stosb
  376. @@3b:
  377.   or   si,si
  378.   jge  @@3a
  379.   add  di,bp
  380.   add  si,dx
  381.   jmp  @@3b
  382. @@3a:
  383.   sub  si,bx
  384.   loop @@3c
  385.   jmp  @@TheEnd2
  386. @@Jmp4:
  387.   mov  cx,bx
  388.   inc  cx
  389.   mov  si,bx
  390.   neg  si
  391.   sar  si,1
  392.   std
  393.   mov  bp,321
  394. @@4c:
  395.   stosb
  396. @@4b:
  397.   or   si,si
  398.   jl   @@4a
  399.   sub  si,bx
  400.   inc  di
  401.   jmp  @@4b
  402. @@4a:
  403.   add  di,bp
  404.   add  si,dx
  405.   loop @@4c
  406. @@TheEnd2:
  407.   pop  bp
  408.   cld
  409. @@TheEnd:
  410. End;
  411. {//////////////////////////////////////////////////////////////////////////}
  412. procedure Quemar_fuego; assembler;
  413. {//////////////////////////////////////////////////////////////////////////}
  414. {aqui esta la primera parte del efecto BlurMotion}
  415. asm
  416.  
  417.         mov ax, SEGM        {realizamos los cambios en la pantalla virtual}
  418.         mov es, ax
  419.  
  420.         mov     di, 95      {origen desde la zona izquierda de la pantalla}
  421.         mov     dx, 130     {ancho del buffer}
  422.         mov     cx, 165     {alto del buffer}
  423.  
  424. @FireLoop :
  425.         xor     ax,ax
  426.         mov     al,es:[di]
  427.         add     al,es:[di+1]          {1er pixel de la izq}
  428.         adc     ah,0
  429.         add     al,es:[di-1]          {1er pixel de la dch}
  430.         adc     ah,0
  431.         add     al,es:[di+320]        {pixel de abajo}
  432.         adc     ah,0
  433.         shr     ax,2
  434.         jz      @zero
  435.         dec     ax
  436. @Zero :
  437.  
  438.         mov     es:[di-320],al
  439.         inc     di
  440.  
  441.         dec     dx
  442.         jnz     @FireLoop
  443.  
  444.         mov dx,130
  445.         add di, 320-130
  446.         dec cx
  447.         jnz @FireLoop
  448.  
  449. end;
  450. {//////////////////////////////////////////////////////////////////////////}
  451. PROCEDURE Poner_Fuego(SegOrg,SegDes:Word);assembler;
  452. {//////////////////////////////////////////////////////////////////////////}
  453. {y aqui esta el efecto BlurMotion en cuestion. Se ha de indicar en que
  454. pantalla se quema (SegOrg) y en que pantalla se van a visualizar los
  455. cambios (SegDes)}
  456. Asm
  457.  
  458.         PUSH DS
  459.         MOV AX, SegOrg
  460.         MOV DS, AX                      { El segmento origen y el segmento destino}
  461.         MOV AX, SegDes                  { destino para copiar desde DS:SI   }
  462.         MOV ES, AX                      { a ES:DI con MOVSx                 }
  463.  
  464.  
  465.         mov     dx, 165                 { nº de veces a repetir el bucle    }
  466.  
  467.         Mov     si, 95                  {origen del buffer}
  468.         Mov     Di, 95
  469.  
  470.  
  471.   @bucle:
  472.          Mov cx, 130/2                  {El fuego se hace en 130 pixels de ancho}
  473.                                         { y se divide / 2 por el MOVSW          }
  474.          Rep movsw
  475.          ADD DI, 190
  476.          ADD SI, 190                    {320-130=190}
  477.   dec  dx
  478.   jnz @bucle                            { repetir el bucle DX veces (165).  }
  479.  
  480.         pop ds
  481. end;
  482. {//////////////////////////////////////////////////////////////////////////}
  483. PROCEDURE Crea_donut(radio1,radio2,partes1,partes2:integer);
  484. {//////////////////////////////////////////////////////////////////////////}
  485. {crea un donut (u otra figura en funcion de los parametros pasados)}
  486. var
  487.    cont1,cont2 : integer;
  488.    circulo     : array[1..25,0..2] of integer;
  489.    xtemp       : longint;
  490.  
  491. begin
  492.      if partes1*partes2>500 then exit; {si hay demasiados puntos,sale}
  493.      total_lineas:=0;
  494.      total_puntos:=partes1*partes2;
  495.  
  496.      for cont1:=1 to partes1 do begin
  497.          circulo[cont1,0]:=radio1*sen[360*cont1 div partes1]+radio2*256;
  498.          circulo[cont1,1]:=radio1*cosen[360*cont1 div partes1];
  499.          end;
  500.  
  501.      for cont2:=1 to partes2 do
  502.          for cont1:=1 to partes1 do begin
  503.          xtemp:=circulo[cont1,0];
  504.          donut[(cont2-1)*partes1+cont1,0]:=xtemp*cosen[360*cont2 div partes2] div 256;
  505.          donut[(cont2-1)*partes1+cont1,1]:=circulo[cont1,1];
  506.          donut[(cont2-1)*partes1+cont1,2]:=xtemp*sen[360*cont2 div partes2] div 256;
  507.          inc(total_lineas);
  508.          lineas[total_lineas,0]:=(cont2-1)*partes1+cont1;
  509.          lineas[total_lineas,1]:=(cont2-1)*partes1+(cont1 mod partes1)+1;
  510.          inc(total_lineas);
  511.          lineas[total_lineas,0]:=(cont2-1)*partes1+cont1;
  512.          lineas[total_lineas,1]:=(((cont2-1)*partes1+(cont1)+partes1-1)mod (total_puntos))+1;
  513.          end;
  514. end;
  515. {//////////////////////////////////////////////////////////////////////////}
  516. PROCEDURE Crea_tablas;
  517. {//////////////////////////////////////////////////////////////////////////}
  518. {crea las tablas necesarias para la rotacion}
  519. VAR
  520.    xpos,ypos : integer;
  521.    cont      : integer;
  522.  
  523. BEGIN
  524.      xoff:=160; {centro de giro en el eje X (la mitad de la pantalla}
  525.      yoff:=100; {centro de giro en el eje Y (la mitad de la pantalla}
  526.      zoff:=64;  {distancia, alejamiento,}
  527.      total_puntos:=0;
  528.      for cont:=0 to 360 do
  529.          BEGIN
  530.               sen[cont]:=round(256*sin(pi*2*cont/360));
  531.               cosen[cont]:=round(256*cos(pi*2*cont/360));
  532.          END;
  533.  
  534. END;
  535. {//////////////////////////////////////////////////////////////////////////}
  536. PROCEDURE Gira_Donut(Xrot,Yrot,Zrot:integer);
  537. {//////////////////////////////////////////////////////////////////////////}
  538. {gira el donut segun los incrementos pasados}
  539. VAR
  540.    cont      : integer;
  541.    xtemp,
  542.    ytemp,
  543.    ztemp     : longint;
  544.  
  545. BEGIN
  546.      for cont:=1 to total_puntos do
  547.          BEGIN
  548.               rotado[cont,0]:=Donut[cont,0];
  549.               rotado[cont,1]:=Donut[cont,1];
  550.               rotado[cont,2]:=Donut[cont,2];
  551.               if xrot<>0 then
  552.               BEGIN
  553.                    ytemp:=rotado[cont,1];
  554.                    ztemp:=rotado[cont,2];
  555.                    rotado[cont,1]:=(ytemp*cosen[xrot]-ztemp*sen[xrot])div 256;
  556.                    rotado[cont,2]:=(ytemp*sen[xrot]+ztemp*cosen[xrot])div 256;
  557.               END;
  558.               if yrot<>0 then
  559.               BEGIN
  560.                    xtemp:=rotado[cont,0];
  561.                    ztemp:=rotado[cont,2];
  562.                    rotado[cont,0]:=(ztemp*sen[yrot]+xtemp*cosen[yrot])div 256;
  563.                    rotado[cont,2]:=(ztemp*cosen[yrot]-xtemp*sen[yrot])div 256;
  564.               END;
  565.               if zrot<>0 then
  566.               BEGIN
  567.                    xtemp:=rotado[cont,0];
  568.                    ytemp:=rotado[cont,1];
  569.                    rotado[cont,0]:=(xtemp*cosen[zrot]-ytemp*sen[zrot])div 256;
  570.                    rotado[cont,1]:=(xtemp*sen[zrot]+ytemp*cosen[zrot])div 256;
  571.               END;
  572.          END;
  573. END;
  574. {//////////////////////////////////////////////////////////////////////////}
  575. PROCEDURE Pon_lineas;
  576. {//////////////////////////////////////////////////////////////////////////}
  577. {dibuja el donut en modo wireframe, es decir, pinta las lineas del donut}
  578. VAR
  579.    cont          : integer;
  580.    punto1,punto2 : integer;
  581.    xfin1,yfin1   : integer;
  582.    xfin2,yfin2   : integer;
  583.    zz: integer;
  584.    col :byte;
  585. BEGIN
  586.      for cont:=1 to total_lineas do
  587.          BEGIN
  588.          punto1:=lineas[cont,0];
  589.          punto2:=lineas[cont,1];
  590.          xfin1:=xoff+rotado[punto1,0]div (zoff+rotado[punto1,2]div 256);
  591.          yfin1:=yoff+rotado[punto1,1]div (zoff+rotado[punto1,2]div 256);
  592.          xfin2:=xoff+rotado[punto2,0]div (zoff+rotado[punto2,2]div 256);
  593.          yfin2:=yoff+rotado[punto2,1]div (zoff+rotado[punto2,2]div 256);
  594.          zz := zoff-rotado[punto2,2] div 64;
  595.          Col := round (zz/2); {el color maximo de la paleta de fuego es
  596.          el 63, aqui se hace un difuminado para que las lineas de fondo
  597.          se pinten con un color mas bajo, asi parece que arden menos}
  598.          DrawLine(Segm,xfin1,yfin1,xfin2,yfin2,col);
  599. {        DrawLine(Segm,xfin1,yfin1,xfin2,yfin2,63); {si pones esta linea
  600. en lugar de la anterior todas las aristas arderan con el maximo color de
  601. la paleta}
  602.  
  603.          END;
  604. END;
  605. {//////////////////////////////////////////////////////////////////////////}
  606. PROCEDURE Fill64K    (SegDes:Word;Data:Byte);assembler;
  607. {//////////////////////////////////////////////////////////////////////////}
  608. {borra (o mejor dicho), rellena un segmento con el byte especificado. Se usa
  609. para ''borrar'' el segmento ocupado por el puntero mezclas}
  610. Asm
  611.   mov  ax,SegDes
  612.   mov  es,ax
  613.   xor  di,di
  614.   mov  al,Data
  615.   mov  ah,al
  616.   mov  cx,32000
  617.   rep  stosw
  618. End;
  619. {//////////////////////////////////////////////////////////////////////////}
  620. {//////////////////////////////////////////////////////////////////////////}
  621. {//////////////////////////////////////////////////////////////////////////}
  622. {//////////////////////////// PROGRAMA PRINCIPAL //////////////////////////}
  623.  
  624.  
  625. BEGIN
  626.      crea_tablas;                 {crea las tablas con senos y cosenos
  627.                                   necesarios para la rotacion}
  628.      crea_donut(5,9,10,10);       {nos genera el poliedro}
  629.      set_vga;                     {pasa a modo13h}
  630.  
  631.      GetMem(Mezclas, 64000);      {reserva memoria para el puntero}
  632.      segm:=seg(mezclas^);         {obtiene su segmento}
  633.  
  634.      Fill64k(segm,0);             {borro el contenido del segmento}
  635.  
  636.      cargaPaleta('fondo');        {cargo la paleta}
  637.      cargaCrudo('fondo');         {cargo el dibujo de fondo}
  638.  
  639.  
  640.      REPEAT                       {************* Bucle principal ***********}
  641.  
  642.            gira_Donut(xdeg,ydeg,zdeg);
  643.            waitretrace;
  644.            pon_lineas;                   {dibuja el donut}
  645.  
  646.            quemar_fuego;                 {aplica el efecto BlurMotion}
  647.            poner_fuego( segM, VIDEO );   {visualiza el efecto}
  648.  
  649.  
  650.            xdeg:=(xdeg+velx)mod 360;      {incrementa las coordenadas de
  651.                                           giro del donut}
  652.            ydeg:=(ydeg+vely)mod 360;
  653.            zdeg:=(zdeg+velz)mod 360;
  654.  
  655.      UNTIL keypressed;            {************ fin bucle principal ********}
  656.  
  657. {como puedes ver NO se borra la pantalla virtual (segM) ya que si se
  658. hace un FILL64K(segm,0) no se acumularia el fuego y el efecto no saldria}
  659.  
  660.      set_text;                       {vuelve a modo texto}
  661.      FreeMem(Mezclas, 64000);        {libera la memoria ocupada por el
  662.                                      puntero}
  663.  
  664. END.      {fin del codigo fuente}
  665. {//////////////////////////////////////////////////////////////////////////}
  666. {//////////////////////////////////////////////////////////////////////////}
  667.  
  668. Para realizar este efecto tienes que utilizar una paleta adecuada. Mira el
  669. archivo BLUR.PAL y veras como son los primeros 64 valores.
  670. Si no tienes un visualizador de paletas puedes cargar el archivo PALETA.PCX
  671. y mirar su paleta. Dicha paleta es la que contiene el archivo BLUR.PAL.
  672. Los primeros 64 valores valores forman la paleta del fuego
  673. (comienza con el negro, luego pasa al rojo y finalmente al amarillo}.
  674. **** Pues bien, para hacer este efecto tienes que pintar las
  675. lineas del poligono con un color entre el 0 y 63, si el color esta mas cercano
  676. a 63 el difuminado sera mayor (parece que arde mas) y si el color es mas cerca-
  677. no a 0 el difuminado sera menor (arde menos).****
  678.  
  679.     Bueno, para optimizar se ha usado un buffer, en lugar de toda la pantalla.
  680. mira este dibujo y lo entenderas mejor:
  681.  
  682.           ------------------------------------   *
  683.           |           |          |   *       |   *
  684.           |           | aqui se  |   *       |   *
  685.           |           |  mueve   |  165      |   *
  686.           |*** 95 *** | el poli- |   *       |   *
  687.           |           | gono.    |   *       |  200
  688.           |           ------------   *       |   *
  689.           |           ****130****            |   *
  690.           |                                  |   *
  691.           ------------------------------------   *
  692.           ****************320*****************
  693.  
  694.           Es decir es un buffer de 130 x 165 pixels y comienza a partir
  695.           de la columna 95. Si usas un poligono mas grande solo tendras
  696.           que ajustar el buffer a tus necesidades.
  697.           Pero lo mejor de usar un buffer, aparte de que ganas en velocidad,
  698.           es que muestras una imagen en pantalla en la zona donde no actua
  699.           el buffer (p.e.mostrando un dibujo) y ya se queda en pantalla y
  700.           no necesitas copiarlo (COPY64k) ni nada por el estilo.
  701.  
  702.           Bueno, espero que que lo hayaIs pillado. Pues nada, a QUEMAR!!!!
  703.  
  704.           nota:la rutina de rotacion es de la PCmania, aunque yo he incluido
  705.           las rutinas para dibujar lineas en ASM, para que vaya mas rapido
  706.           aun.
  707.  
  708.           nota2:OLVIDAD LA 1ª version!!!!!!!
  709.  
  710.           nota3:Si al ejecutar el archivo VECTFIRE.EXE da error y no se
  711.           ejecuta es debido a que los archivos que usa (el BLUR.SCR y el
  712.           BLUR.PAL) estan con el atributo de solo lectura, (+R), para so-
  713.           lucionar este problema debes quitar este atributo a todos los
  714.           archivos (ya que por defecto todos los archivos contenidos en el
  715.           CD-ROM tienen el atributo de solo lectura) meditante la orden
  716.           ATTRIB -R +A *.*
  717.  
  718.  
  719. Si tienes fuentes de Pascal o Assembler y te gustaria intercambiar conocimientos
  720. puedes tambien ponerte en contacto conmigo.....Espero vuestras cartas....;-D
  721.        Mi direccion es la siguiente:
  722.  
  723.           Jose Antonio DIEGUEZ ALONSO
  724.           Rambla Marina nº 366-8º-1ª
  725.           08907 Hospitalet del Llobregat
  726.           BARCELONA
  727.  
  728.  
  729.                                                 UN SALUDO. Hasta pronto
  730.