home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / lente / LENTE.ASM next >
Encoding:
Assembly Source File  |  1996-06-24  |  36.7 KB  |  963 lines

  1. .MODEL COMPACT, PASCAL
  2. .STACK 500h 
  3. .FARDATA Datos
  4.  
  5. S_Punto STRUC                   ; Este estructura representa un punto 
  6.         Coor_X DB ?             ; con sus tres coordenadas
  7.         Coor_Y DB ?
  8.         Coor_Z DB ?
  9. S_Punto ENDS
  10.  
  11.         NuevaLinea DB 0Dh,0Ah,'$'       ; Proboca un salto de linea
  12.  
  13.         R_circulo DB 43         ; Radio de la circunferencia
  14.         Dist_plano DB 50        ; Distancia al plano de la imagen
  15.         R_esfera DB ?           ; Radio de la esfera de la que es seccion la
  16.                                 ; lupa
  17.         Ped_Radio DB ' Introduzca el radio (menor de 45) : $'
  18.         Ped_Dist  DB ' Introduzca la distancia al plano( menor 60 ¿100?): $'
  19.         Menu      DB ' Elija una de las siguientes opciones. $'
  20.         Menu_op1  DB '  1.-   Manejo con Raton (ensucia) $'
  21.         Menu_op2  DB '  2.-   Manejo con Raton (parpadeo) $'
  22.         Menu_op3  DB '  3.-   Movimiento automatico (salva pantalla) $'
  23.         Menu_op4  DB '  4.-   Efecto de acercamiento $'
  24.         Menu_Pide DB ' Opcion : $'
  25.         Opcion    DB 1      
  26.  
  27.         Pto_Q S_Punto <0,0,0>   ; Punto Transformado
  28.         Pto_P S_Punto <0,0,0>   ; Punto a transformar
  29.         Pto_I S_Punto <0,0,0>   ; Punto de interseccion
  30.  
  31.         Pos_MX DW 0             ; Posicion X de la lupa
  32.         Pos_MY DW 0             ; Posicion Y de la lupa
  33.  
  34.         
  35.         Distancia DW ?          ; Distancia del plano a la superficie de la
  36.                                 ; esfera 
  37.  
  38.         Ventana1        EQU 0A000h      ; Segmento de memoria de video
  39.         Ancho_Pant      DW 320          ; Dimensiones de la pantalla en
  40.         Alto_Pant       DW 200          ; modo 13
  41.  
  42.         NombreTGA       DB  'LENTE.TGA',0       ;Imagen a ampliar
  43.         NombreTGA2      DB  'PRESENTA.TGA',0    ;Imagen de presentacion
  44.         NombreTGA3      DB  'LENTE2.TGA',0
  45.         BufferTGA       DB 1024 DUP(?)
  46.  
  47.         Margen          DW 5            ; Margen entre la lupa y la imagen
  48.                                         ; capturada
  49.         Desp_Mat_T      DW 0
  50.         Ancho_Img       DW 90           ; El ancho de la imagen a capturar
  51.         Area            DW 10000        ; Longitud de los buffers 
  52.         Buffer_Fuente   DB 10000 DUP(?) ; Buffer sin transformar         
  53.         Buffer_Destino  DB 10000 DUP(?) ; Buffer transformado
  54.         MatrizTrans     DW 10000 DUP(0) ; Matriz de transformacion
  55.  
  56. .FARDATA Imagen
  57.         ImagenBak       DB 64000 DUP(?) ; Aqui se almacena la imagen
  58. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  59. .CODE
  60. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  61. ; Macro para imprimir una cadena 
  62. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  63. ImprimeCad MACRO Cadena
  64.         mov ah,09h    ; Imprime cadena
  65.         mov dx, Cadena
  66.         int 21h
  67. ENDM
  68. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  69. ; Macro para activar el modo de
  70. ; video 320 x 200 x 256
  71. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  72. Modo13 MACRO
  73.         mov ax,0013h    ; Modo de video 
  74.         int 10h
  75. ENDM
  76. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  77. ; Macro para activar el modo de texto
  78. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  79. ModoTx MACRO
  80.         mov ax,0003h    ; Modo texto 
  81.         int 10h
  82. ENDM
  83. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  84. ; Macro para esperar una tecla
  85. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  86. KeyPressed MACRO
  87.         push ax
  88.         mov ah,08h      ; Lee un caracter del teclado 
  89.         int 21h
  90.         pop ax
  91. ENDM
  92.  
  93. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  94. ; Macro para salir al sistema
  95. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  96. Salir MACRO
  97.         ModoTx          ; Ponemos en modo texto
  98.         mov ax,4C00h    ; Funcion 4Ch: Salir al sistema
  99.         int 21h
  100. ENDM
  101. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  102. ; Macro para esperar el retrazo vertical
  103. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  104. RetrazoVert MACRO
  105.         mov dx,3DAh
  106. @Paso1:
  107.         in al,dx
  108.         test al,8
  109.         jnz @Paso1
  110. @Paso2:
  111.         in al,dx
  112.         test al,8
  113.         jz @Paso2
  114. ENDM
  115. ;###############################
  116. ; Este procedimiento carga una images
  117. ; en formato TGA 256 colores 
  118. ;###############################
  119.  
  120. CargaTGA PROC NEAR USES ax bx cx dx ds es di si, Nombre_TGA:WORD,Buffer:WORD,\
  121. SegDest:WORD,DespDest:WORD
  122. LOCAL Handle_TGA:WORD
  123.         mov ax,3D00h            ; Funcion 3Dh: Abrir un fichero modo lectura
  124.         mov dx,Nombre_TGA        ; Direccion de comienzo del nombre
  125.         int 21h
  126.  
  127.         mov Handle_TGA, ax      ; Al abrir el fichero se devuelve en ax el
  128.                                 ; handle del fichero
  129.  
  130.         mov ah, 3Fh             ; Funcion 3Fh: Leer los CX elementos del 
  131.         mov bx, Handle_TGA      ; fichero y escribirlos en R
  132.         mov cx, 18
  133.         mov dx, Buffer   ; Leemos la cabecera del fichero
  134.         int 21h
  135.  
  136.         mov ah, 3Fh             ; Funcion 3Fh: Leer los CX elementos del
  137.         mov bx, Handle_TGA      ; fichero y escribirlos en R
  138.         mov cx, 768
  139.         mov dx, Buffer          ; Leemos la paleta de colores
  140.         int 21h
  141.  
  142.         mov cx, 256             ; Elementos de la paleta
  143.  
  144.         mov ax, @DATA           ; Preparamos los registros de segmentos                       
  145.         mov es, ax              ; y los de desplazamiento de cadena fuente
  146.         mov si, Buffer          ; y destino para emplear las instruciones 
  147.         mov di, Buffer          ; lods_ y stos_ que son las mas comodas
  148.         cld                     ; Borra el flag de direccion
  149.  
  150. @@ModifPal:
  151.         lodsb                   ; al <- DS:SI y INC si
  152.         shr al, 1               ; dividimos el valor entre cuatro 
  153.         shr al, 1               ; tenemos la nueva componente AZUL
  154.         mov ah, al              ; situamos el nuevo valor en AH
  155.         lodsb                   ; al <- DS:SI y INC si
  156.         shr al, 1               ; dividimos el valor entre cuatro
  157.         shr al, 1               ; tenemos la nueva componente VERDE
  158.         mov bh, al              ; situamos el nuevo valor en BH
  159.         lodsb                   ; al <- DS:SI y INC si
  160.         shr al, 1               ; dividimos el valor entre cuatro
  161.         shr al, 1               ; tenemos la nueva componente ROJA
  162.         stosb                   ; ES:DI <- al y INC di , almacenamos el ROJO
  163.         mov al, bh              ; 
  164.         stosb                   ; ES:DI <- al y INC di , almacenamos el VERDE
  165.         mov al, ah       
  166.         stosb                   ; ES:DI <- al y INC di , almacenamos el AZUL
  167.         dec cx                  ; un color menos de la Paleta
  168.         jnz @@ModifPal          ; repetir hasta cero
  169.  
  170.         mov ax, 1012h           ; Funcion 10h subfuncion 12h establecer la
  171.         mov bx, 0               ; paleta de colores situada en ES:DX
  172.         mov cx, 256             ; numero de colores
  173.         mov dx, Buffer
  174.         int 10h 
  175.  
  176.         mov ah, 3Fh             ; Leer del fichero toda la imagen que esta
  177.         mov bx, Handle_TGA      ; sin comprimir y situarla en la Ventana1
  178.         mov cx, 64000           ; tamaño de la imagen
  179.         push ds                 ; Guardamos el segmento de datos actual
  180.         mov ds,SegDest          ; Ponemos el nuevo segmento
  181.         mov dx,DespDest         ; Ponemos el desplazamiento 
  182.         int 21h
  183.         pop ds                  ; Recuperamos el antiguo segmento de datos
  184.         mov ah, 3Eh             ; Funcion 3Eh: Cerrar un fichero 
  185.         mov bx, Handle_TGA      ; Identificador del fichero
  186.         int 21h
  187.         ret
  188. CargaTGA ENDP
  189.  
  190.  
  191. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  192. ; Macro que devuelve en AX el
  193. ; cuadrado del valor
  194. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  195. Cuadrado MACRO Valor
  196.         xor ax,ax       ; Limpiamos AX
  197.         mov al,Valor    ; Ponemos el valor en AL
  198.         imul al         ; multiplicamos y AX <- AL * AL 
  199. ENDM
  200. ;###############################
  201. ; Raiz devuelve en AX el valor de la raiz entera
  202. ;###############################
  203. Raiz PROC NEAR USES cx bx , Operando:WORD 
  204.         mov bx, Operando        ; Ponemos el valor en BX
  205.         jns @Continua           ; Si no es negativo saltar
  206.         neg bx                  ; Si era negativo , volver positivo
  207. @Continua:
  208.         xor cx,cx               ; Limpiar CX
  209. @bucle:
  210.         inc cl                  ; Un contador desde 0 hasta SQRT(Operando)
  211.         Cuadrado cl             ; AX <- CL * CL
  212.         cmp ax,bx               ; Comparamos Operando con AX
  213.         jle @bucle              ; Repetir hasta que AX sea mayor que Operando
  214.         dec cl                  ; Reducir en uno CL , mayor entero cuyo
  215.                                 ; cuadrado no supera Operando
  216.         xor ax,ax               ; Limpiar AX
  217.         mov al,cl               ; Devolver el resultado en AL
  218.         ret
  219. Raiz ENDP
  220.  
  221. ;###############################
  222. ; Procedimiento que calcula el valor de la variable Distancia
  223. ;###############################
  224. Calc_Dist PROC NEAR USES ax bx 
  225.         xor ax,ax
  226.         xor bx,bx
  227.         Cuadrado ds:Dist_plano          ; Obtenemos d^2
  228.         push ax
  229.         Cuadrado ds:Pto_P.Coor_X        ; Obtenemos Px^2
  230.         push ax
  231.         Cuadrado ds:Pto_P.Coor_Y        ; Obtenemos Py^2
  232.         pop bx
  233.         add ax,bx                       ; Calculamos Px^2 + Py^2
  234.         push ax
  235.         Cuadrado ds:R_circulo           ; Obtenemos Rc^2
  236.         pop bx
  237.         sub bx,ax               ; Calculamos (Px^2 + Py^2) - Rc^2
  238.         pop ax
  239.         sub ax,bx               ; Calculamos d^2 -((Px^2 + Py^2) -Rc^2)
  240.         mov ds:Distancia, ax    ; Asignamos el valor a Distancia
  241.         ret
  242. Calc_Dist ENDP
  243.  
  244. ;###############################
  245. ; Procedimiento para calcular Pto_Q.Coor_Z 
  246. ;###############################
  247. Calc_Qz PROC NEAR USES ax 
  248.         xor ax,ax
  249.         push ds:Distancia
  250.         call Raiz               ; Calculamos SQRT(D)
  251.         add al,1                ; Calculamos 1+SQRT(D)
  252.         mov ds:Pto_Q.Coor_Z, al ; Asignamos el valor a la variable
  253.         ret
  254. Calc_Qz ENDP
  255. ;###############################
  256. ; Procedimiento para calcular Pto_I.Coor_X
  257. ;###############################
  258. Calc_Ix PROC NEAR USES ax bx
  259.         xor ax,ax
  260.         mov al, ds:Pto_Q.Coor_Z
  261.         add al, ds:Dist_Plano           ; Calculamos (Qz + d)
  262.         push ax
  263.         xor ax,ax
  264.         mov al, ds:Dist_Plano      
  265.         imul ds:Pto_P.Coor_X            ; Calculamos (d * Px)
  266.         pop bx
  267.         idiv bl                         ; Calculamos (d*Px) / (Qz +d)
  268.         mov ds:Pto_I.Coor_X, al         ; Asignamos el valor a la variable
  269.         ret
  270. Calc_Ix ENDP
  271.  
  272. ;###############################
  273. ; Procedimiento para calcular Pto_I.Coor_Y
  274. ;###############################
  275. Calc_Iy PROC NEAR USES ax bx
  276.         xor ax,ax
  277.         mov al, ds:Pto_Q.Coor_Z
  278.         add al, ds:Dist_Plano           ; Calculamos (Qz + d)
  279.         push ax
  280.         xor ax,ax
  281.         mov al, ds:Dist_Plano      
  282.         imul ds:Pto_P.Coor_Y            ; Calculamos (d * Py)
  283.         pop bx
  284.         idiv bl                         ; Calculamos (d*Py) / (Qz +d)
  285.         mov ds:Pto_I.Coor_Y, al         ; Asignamos el valor a la variable
  286.         ret
  287. Calc_Iy ENDP
  288.  
  289. ;###############################
  290. ; Dar_Cateto devuelve en AX el valor del cateto
  291. ; opuesto según el Teorema de Pitagoras
  292. ;###############################
  293. Dar_Cateto PROC NEAR USES bx ,Base:BYTE, Cateto: BYTE
  294.         Cuadrado Base           
  295.         push ax
  296.         Cuadrado Cateto
  297.         pop bx
  298.         add ax,bx               ; Sumamos la Base^2 y Cateto^2
  299.         push ax
  300.         call Raiz               ; Caluculamos la raiz de la suma
  301.         ret                     ; El resultado se devuelve en AX
  302. Dar_Cateto ENDP
  303.  
  304. ;###############################
  305. ; Transformacion de un punto ,devuelve en AX
  306. ;###############################
  307. Trans_Pto PROC NEAR USES bx cx , Cnt_X :BYTE, Cnt_Y:BYTE, Ancho:BYTE
  308. LOCAL Medio_Ancho: BYTE
  309.  
  310.         mov al, Ancho
  311.         shr al,1                ; Dividimos por dos el Ancho
  312.         mov Medio_Ancho, al     ; Lo almacenamos en Medio_Ancho
  313.         xor ax,ax
  314.         call Calc_Dist          ; Calculamos el valor de D
  315.         call Calc_Qz            ; Calculamos Qz = 1 + SQRT(D)
  316.         call Calc_Ix            ; Calculamos Ix = (d * Qx )/(d + Qz)
  317.         call Calc_Iy            ; Calculamos Iy = (d * Qy )/(d + Qz)
  318.         mov ds:Pto_I.Coor_Z, 0
  319.         mov al, Medio_Ancho
  320.         add al, ds:Pto_I.Coor_Y
  321.         imul Ancho
  322.         push ax
  323.         mov al, Medio_Ancho
  324.         add al, ds:Pto_I.Coor_X
  325.         pop bx
  326.         cbw
  327.         add ax,bx
  328.         mov ds:Desp_Mat_T,ax
  329.         ret
  330. Trans_Pto ENDP
  331.  
  332. ;###############################
  333. ; Crear_Matriz modifica la matriz de transformacion
  334. ;###############################
  335. Crear_Matriz PROC NEAR USES bx cx dx, Ancho : BYTE
  336. LOCAL Cnt_X: BYTE,Cnt_Y:BYTE, Desp_Pant :WORD, Desp_Mat :WORD, \
  337. Medio_Ancho :BYTE
  338.  
  339.         mov al, Ancho       
  340.         shr al,1                ; Dividimos por dos el Ancho
  341.         mov Medio_Ancho, al     ; Lo almacenamos en Medio_Ancho
  342.         xor cx,cx
  343.         mov dx,ds
  344.         mov es,dx
  345.         mov di,OFFSET ds:MatrizTrans
  346. @Bucle_for1:                    ; Bucle FOR Cnt_X = 0 TO Ancho para 
  347.                                 ; la coordenada X
  348.         mov Cnt_Y,cl
  349.         xor cx,cx
  350.    @Bucle_for2:                 ; Bucle FOR Cnt_Y = 0 TO Ancho -1 para
  351.                                 ; la coordenada Y
  352.                 mov Cnt_X,cl  
  353.                 mov cl,Cnt_Y
  354.                 sub cl,Medio_Ancho
  355.                 xor bx,bx
  356.                 mov bl,Cnt_X
  357.                 sub bl,Medio_Ancho
  358.                 mov ds:Pto_P.Coor_X, bl    
  359.                 mov ds:Pto_P.Coor_Y, cl
  360.                 mov ds:Pto_Q.Coor_X, bl
  361.                 mov ds:Pto_Q.Coor_Y, cl
  362.                 push bx       ; Paso de parametros del procedimiento
  363.                 push cx       ; Cateto que devuelve un valor en AX 
  364.                 call Dar_Cateto
  365.                 xor bx,bx
  366.                 xchg bx,ax      ; Cambiamos el valor de sitio
  367.                 mov al,Cnt_Y    ; Calculamos el desplazamiento dentro de la
  368.                 imul Ancho      ; matriz de transformacion
  369.                 push ax
  370.                 mov al,Cnt_X    
  371.                 cbw             
  372.                 pop cx
  373.                 add ax,cx       ; Cnt_Y * Medio_Ancho + Cnt_X
  374.                 mov Desp_Mat,ax
  375.                 cmp ds:R_Circulo, bl    ; El punto esta fuera del circulo de
  376.                 jle @Es_Menor           ; corte del plano con la esfera
  377.                                         ; El punto esta en la lupa
  378.                         xor bx,bx
  379.                         mov bl,Cnt_X
  380.                         push bx
  381.                         mov bl,Cnt_Y
  382.                         push bx
  383.                         mov bl,Ancho
  384.                         push bx
  385.                         call Trans_Pto
  386.                         mov ax,ds:Desp_Mat_T
  387.               @Es_Menor:                ; corte del plano con la esfera
  388.                         ;mov bx,Desp_Mat
  389.                         ;shl bx,1
  390.                         stosw
  391.  
  392.                         ;mov ds:MatrizTrans[bx], ax     ; Asignamos el nuevo
  393.                                                         ; valor
  394.                 mov cl,Cnt_X
  395.                 inc cl
  396.                 cmp cl,Ancho
  397.                 jl @Bucle_for2
  398.         mov cl,Cnt_Y
  399.         inc cl
  400.         mov ch,Ancho
  401.         cmp cl, ch 
  402.         jl @Bucle_for1
  403.         ret
  404. Crear_Matriz ENDP
  405.  
  406. ;###############################
  407. ; Procedimiento que toma un trozo de
  408. ; la imagen y la guarda en un buffer
  409. ;###############################
  410. CargarBuffer PROC NEAR USES ax cx si di ds es , Pos_X :WORD, Pos_Y:WORD, \
  411. Dest :WORD
  412. LOCAL Ancho_I:WORD, Ancho_P:WORD
  413.  
  414.         mov ax, ds:Ancho_Pant
  415.         mov Ancho_P,ax                  ; Asignamos a las variables locales
  416.         mov ax, ds:Ancho_Img
  417.         mov Ancho_I,ax
  418.         mov dx,@data                    ; Obtenemos el segmento de datos
  419.         push dx
  420.         pop es                  ; El segemtno Extra es igual al de datos
  421.         mov ax,SEG Imagen       ; Hacemos el segmento de datos se Imagen
  422.         mov ds,ax
  423.         mov si, Pos_Y           ;  Preparamos SI para que almacene el
  424.         mov ax, Ancho_P         ; desplazamiento del primer punto de la
  425.         mul si                  ; imagen : 
  426.         mov si, ax              ;    SI <- (PosY * Ancho_Img) + PosX
  427.         add si, Pos_X
  428.         mov di, Dest            ;  Preparamos DI para que tenga el desplaza_
  429.                                 ; miento del buffer donde se almacenara
  430.         mov cx, Ancho_I         ; Las filas a leer ( es un cuadrado )
  431. @@CopiaFila:
  432.         push si                 ; Salvaguardamos SI y CX
  433.         push cx
  434.         mov cx, Ancho_I         ; Los puntos de una linea
  435.         cld                     ; Borra el flag de acarreo
  436.         rep movsb               ;  Repite Ancho_I veces ES:DI <- DS:SI hasta
  437.                                 ; que CX sea 0
  438.         pop cx                  ; Recuperamos los valores antiguos
  439.         pop si
  440.         add si, Ancho_P         ; Desplazamos SI una linea entera
  441.         dec cx                  ; Queda una linea menos que pasar
  442.         jnz @@CopiaFila
  443.         ret
  444. CargarBuffer ENDP
  445.  
  446. ;############################################################################
  447. ; Procedimiento que toma un buffer y lo muestra en pantalla
  448. ;############################################################################
  449. MostrarBuffer PROC NEAR USES ax cx si di ds es , Pos_X :WORD, Pos_Y:WORD, \
  450. Dest :WORD
  451. LOCAL Ancho_I:WORD, Ancho_P:WORD
  452.  
  453.         mov ax, ds:Ancho_Pant
  454.         mov Ancho_P,ax                  ; Asignamos a las variables locales
  455.         mov ax, ds:Ancho_Img
  456.         mov Ancho_I,ax
  457.  
  458.         mov ax, Ventana1        ; Segemento de Video
  459.         mov es, ax              ; El segemtno Extra es igual al de video
  460.  
  461.         mov di, Pos_Y           ;  Preparamos DI para que almacene el
  462.         mov ax, Ancho_P         ; desplazamiento del primer punto de la
  463.         mul di                  ; imagen : 
  464.         mov di, ax              ;    DI <- (PosY * Ancho_Img) + PosX
  465.         add di, Pos_X
  466.         mov si, Dest            ;  Preparamos SI para que tenga el desplaza_
  467.                                 ; miento del buffer donde se almacenara
  468.         mov cx, Ancho_I
  469. @@CopiaFila:
  470.         push di                 ; Salvaguardamos DI y CX
  471.         push cx
  472.         mov cx, Ancho_I         ; Los puntos de una linea
  473.         cld                     ; Borra el flag de acarreo
  474.         rep movsb               ;  Repite Ancho_I veces ES:DI <- DS:SI hasta
  475.                                 ; que CX sea 0
  476.         pop cx                  ; Recuperamos los valores antiguos
  477.         pop di
  478.         add di, Ancho_P         ; Desplazamos DI una linea entera
  479.         dec cx                  ; Queda una linea menos que pasar
  480.         jnz @@CopiaFila
  481.         ret
  482. MostrarBuffer ENDP
  483.  
  484. ;############################################################################
  485. ; Procedimiento que transforma un trozo de imagen de un buffer
  486. ;############################################################################
  487. TransfBuffer PROC NEAR USES dx es ds si di ax bx cx
  488.         mov dx, @data                   ; Actualizamos el valor del segmento      
  489.         mov es, dx                      ; extra al de datos
  490.         mov si, OFFSET ds:MatrizTrans           
  491.         mov di, OFFSET ds:Buffer_Destino
  492.         mov cx, ds:Area                 ; Contador de operaciones
  493.         cld                             ; Borra el flag de direccion
  494.         xor bh,bh
  495. @@HazPunto:
  496.         lodsw                           ; Leemos el indice de la matriz Transformada
  497.         mov bx,ax                       ; Cambiamos de sitio
  498.         mov al,OFFSET ds:[Buffer_Fuente+bx]     ; Tomamos el punto indicado
  499.                                                 ; por el indice
  500.         stosb                           ; Lo almacenamos en Buffer_Dest
  501.         dec cx                          ; Decrementamos el contador
  502.         jnz @@HazPunto
  503.         ret
  504. TransfBuffer ENDP
  505. ;###############################
  506. ; Procedimiento que mueve 64k 
  507. ;###############################
  508. Copy64k PROC USES ax cx di si ds ,SegOrg: WORD,SegDes:Word
  509.         mov ax,SegOrg           ; Actualizar DS al Segmento Origen
  510.         mov ds,ax
  511.         mov ax,SegDes           ; Actualizar ES al Segmento Destino
  512.         mov es,ax
  513.         xor di,di               ; Los puntero a cero
  514.         xor si,si
  515.         mov cx,32000            ; Contador , la mitad para leer palabras
  516.         rep movsw               ; Repite CX-veces ES:DI <- DS:SI
  517.         ret
  518. Copy64k ENDP
  519.  
  520. ;###############################
  521. ;Procedimiento que pide los parametros
  522. ;###############################
  523. Captura PROC NEAR USES bx cx dx , Cadena:WORD 
  524.         ImprimeCad Cadena
  525.         xor bx,bx               ; Aqui guardamos el valor del parametro
  526. @bucle:
  527.         mov ah, 01h
  528.         int 21h                 ; En AL esta el caracter leido
  529.  
  530.         cmp al, 0Dh             ; Salir si se pulsa ENTER
  531.         je @Fin
  532.  
  533.         sub al,30h              ; Le restamos el valor ASCII del caracter 0
  534.         cbw                     ; Combertimos AL de BYTE a WORD
  535.         mov cx,ax               ; Lo cambiamos de sitio
  536.         mov ax,10               ; Base del sistema decimal
  537.         mul bx                  ; Lo que habimos almacenado se multiplica
  538.         add ax,cx               ; Le sumamos el nuevo caracter
  539.         mov bx,ax               ; y lo situamos en BX para comenzar el bucle
  540.         jmp @bucle
  541. @Fin:
  542.         mov cx, OFFSET ds:NuevaLinea
  543.         ImprimeCad cx
  544.         mov ax,bx               ; El resultado se devuelve en AX
  545.         ret
  546. Captura ENDP
  547. ;##############################################
  548. ; Este procedimiento pide todos los parametros
  549. ; y calcula el resto
  550. ;##############################################
  551. Param PROC USES ax bx dx
  552.         mov dx, OFFSET ds:Ped_Radio     ;Vamos a pedir el radio
  553.         push dx
  554.         call Captura
  555.         mov ds:R_Circulo, al            ;Ponemos el nuevo valor
  556.         mov bx, ds:Margen               ;Puesto que es necesario que el ancho
  557.         add bx,ax                       ;sea algo superior , este sera el doble
  558.         mov ax, 2                       ;del radio + 2
  559.         mul bx
  560.         mov ds:Ancho_Img, ax
  561.         imul al                         ;Calculamos el area de la imagen a tomar
  562.         mov ds:Area,ax
  563.  
  564.         mov dx, OFFSET ds:Ped_Dist      ;Vamos a pedir la distancia al plano
  565.         push dx
  566.         call Captura
  567.         mov ds:Dist_Plano, al
  568.         ret
  569.  
  570. Param ENDP
  571.  
  572. ;##############################################
  573. ; Este procedimiento muestra un menu para seleccionar 
  574. ; las opciones del programa
  575. ;##############################################
  576. Mi_Menu PROC USES ax bx cx ds
  577. @Comienzo:
  578.         mov cx, OFFSET ds:NuevaLinea    ; Se muestran los mensajes
  579.         ImprimeCad cx
  580.         mov bx, OFFSET ds:Menu
  581.         ImprimeCad bx
  582.         ImprimeCad cx
  583.         mov bx, OFFSET ds:Menu_op1
  584.         ImprimeCad bx
  585.         ImprimeCad cx 
  586.         mov bx, OFFSET ds:Menu_op2
  587.         ImprimeCad bx
  588.         ImprimeCad cx 
  589.         mov bx, OFFSET ds:Menu_op3
  590.         ImprimeCad bx
  591.         ImprimeCad cx 
  592.         mov bx, OFFSET ds:Menu_op4
  593.         ImprimeCad bx
  594.         ImprimeCad cx 
  595.         mov bx, OFFSET ds:Menu_Pide
  596.         ImprimeCad bx
  597.         mov ah,01h                       ; Leemos el número seleccionado
  598.         int 21h
  599.         cmp al,'5'              
  600.         jg @Comienzo            ; Vuelta a empazar si es mayor de 4
  601.         cmp al,'0'
  602.         jl @Comienzo            ; Vuelta a empezar si es menor que 1
  603.         mov ds:Opcion,al        ; Guardamos la opcion elegida
  604.         ret
  605. Mi_Menu ENDP
  606. ;##############################################
  607. ; Este procedimiento seleciona el programa a ejecutar
  608. ;##############################################
  609. Seleccion PROC USES ax
  610.         mov al, ds:Opcion       ; Lee la opcion
  611.         cmp al, '1'             ; Si es 1 hacer Raton1
  612.         jne @No_Opcion1
  613.                 call Raton1
  614.                 jmp @Salir      
  615. @No_Opcion1:
  616.         cmp al, '2'             ; Si es 2 hacer Raton2
  617.         jne @No_Opcion2
  618.                 call Raton2
  619.                 jmp @Salir
  620. @No_Opcion2:
  621.         cmp al, '3'             ; Si es 3 hacer MovAuto
  622.         jne @No_Opcion3
  623.                 call MovAuto
  624.                 jmp @Salir
  625. @No_Opcion3:
  626.                 call Efecto     ; Sino hacer Efecto
  627. @Salir:
  628.         ret
  629. Seleccion ENDP
  630. ;##############################################
  631. ; Este procedimiento permite mover la lupa
  632. ; mediante el uso del ratón ( Esta versión tiene el
  633. ; problema de que cuando se mueve demasiado deprisa
  634. ; se ensucia la imagen )
  635. ;##############################################
  636. Raton1 PROC USES ax bx cx dx ds es
  637.  
  638.         mov ax, 0               ; Inicializa el raton          
  639.         int 33h
  640.         mov ax, 0007h           ; Seleccionar limites horizontales 
  641.         mov cx, 0               ; Superior
  642.         mov dx, 550              
  643.         sub dx, ds:Ancho_Img
  644.         int 33h
  645.         mov ax, 0008h           ; Seleccionar limites verticales 
  646.         mov cx, 0               ; Izquierda
  647.         mov dx, 150             ; Derecha
  648.         int 33h
  649.         mov ax, 3               ; Obtener la posicion y el estado del raton
  650.         int 33h
  651.         shr cx, 1
  652.         mov ds:Pos_MX, cx       ; En CX se devuelve la coordenada horizontal
  653.         mov ds:Pos_MY, dx       ; En DX se devuelve la coordenada vertical
  654.  
  655. @Bucle_Prin:
  656.         push ds:Pos_MX          ; Pasamos los parametros a CargarBuffer
  657.         push ds:Pos_MY
  658.         mov dx,OFFSET ds:Buffer_Fuente
  659.         push dx
  660.         call CargarBuffer       ; Leemos el trozo de imagen
  661.  
  662.         call TransfBuffer       ; Lo transformamos
  663.  
  664.         push ds:Pos_MX
  665.         push ds:Pos_MY
  666.         mov dx,OFFSET ds:Buffer_Destino
  667.         push dx
  668.  
  669. ;        RetrazoVert             ; Esperamos al retrazo vertical
  670.         call MostrarBuffer      ; Y finalmente lo mostramos
  671. @Movimiento:
  672.         mov ax, 3               ; Miramos la posicion del raton
  673.         int 33h
  674.         shr cx, 1               ; Dividimos la coordenada horizontal por 2
  675.         cmp ds:Pos_MX, cx       ; Comparamos para ver si se ha movido la X
  676.         jnz @SeMovio
  677.         cmp ds:Pos_MY, dx       ; Comparamos para ver si se ha movido la X
  678.         jnz @SeMovio
  679.         mov ah, 6               ; Miramos si se pulso alguna tecla
  680.         mov dl, 0ffh
  681.         int 21h                 ; Si se pulso se ve en el Flag Zero
  682.         jz @Movimiento
  683.         jmp @Salir
  684. @SeMovio:
  685.         mov ds:Pos_MX, cx       ; Almacenamos las nuevas coordenadas
  686.         mov ds:Pos_MY, dx
  687.         jmp @Bucle_Prin         ; Vuelta a empezar
  688. @Salir:
  689.         ret
  690. Raton1 ENDP
  691. ;##############################################
  692. ; Este procedimiento permite mover la lupa
  693. ; mediante el uso del ratón ( Esta versión tiene el
  694. ; problema de que produce un molesto parpadeo al
  695. ; mover le raton debido a tener que poner la region
  696. ;anterior antes de desplazar la nueva lupa
  697. ;##############################################
  698. Raton2 PROC USES ax bx cx dx ds es
  699.         mov ax, 0               ; Inicializa el raton          
  700.         int 33h
  701.         mov ax, 0007h           ; Seleccionar limites horizontales 
  702.         mov cx, 0               ; Superior
  703.         mov dx, 550              
  704.         sub dx, ds:Ancho_Img
  705.         int 33h
  706.         mov ax, 0008h           ; Seleccionar limites verticales 
  707.         mov cx, 0               ; Izquierda
  708.         mov dx, 150             ; Derecha
  709.         int 33h
  710.         mov ax, 3               ; Obtener la posicion y el estado del raton
  711.         int 33h
  712.         shr cx, 1
  713.         mov ds:Pos_MX, cx       ; En CX se devuelve la coordenada horizontal
  714.         mov ds:Pos_MY, dx       ; En DX se devuelve la coordenada vertical
  715.  
  716. @Bucle_Prin:
  717.         push ds:Pos_MX          ; Pasamos los parametros a CargarBuffer
  718.         push ds:Pos_MY
  719.         mov dx,OFFSET ds:Buffer_Fuente
  720.         push dx
  721.         call CargarBuffer       ; Leemos el trozo de imagen
  722.  
  723.         call TransfBuffer       ; Lo transformamos
  724.  
  725.         push ds:Pos_MX
  726.         push ds:Pos_MY
  727.         mov dx,OFFSET ds:Buffer_Destino
  728.         push dx
  729.  
  730.         call MostrarBuffer      ; Y finalmente lo mostramos
  731.  
  732. @Movimiento:
  733.         mov ax, 3               ; Miramos la posicion del raton
  734.         int 33h
  735.         shr cx, 1               ; Dividimos la coordenada horizontal por 2
  736.         cmp ds:Pos_MX, cx       ; Comparamos para ver si se ha movido la X
  737.         jnz @SeMovio
  738.         cmp ds:Pos_MY, dx       ; Comparamos para ver si se ha movido la X
  739.         jnz @SeMovio
  740.         mov ah, 6               ; Miramos si se pulso alguna tecla
  741.         mov dl, 0ffh
  742.         int 21h                 ; Si se pulso se ve en el Flag Zero
  743.         jz @Movimiento
  744.         jmp @Salir
  745. @SeMovio:
  746.         push dx                 ; Guardamos por si se modifican
  747.         push cx
  748.         push ds:Pos_MX          ; Pasamos parametros
  749.         push ds:Pos_MY
  750.         mov dx, OFFSET ds:Buffer_Fuente
  751.         push dx
  752.         RetrazoVert             ; Esperamos al retrazo vertical
  753.         call MostrarBuffer      ; Mostramos la imagen antigua
  754.         pop cx                  ; Recuperamos la nueva posicion
  755.         pop dx
  756.         mov ds:Pos_MX,cx        ; Asignamos los valores a las variables
  757.         mov ds:Pos_MY,dx
  758.         jmp @Bucle_Prin         
  759. @Salir:
  760.         ret
  761. Raton2 ENDP
  762.  
  763. ;##############################################
  764. ; Este procedimiento mueve la lupa automaticamente
  765. ; como si revotara en las paredes
  766. ;##############################################
  767. MovAuto PROC USES ax bx cx dx
  768. LOCAL Increm_X:BYTE, Increm_Y:BYTE
  769.         mov Increm_X,0fh        ; Estas veriables indican con su signo la
  770.         mov Increm_Y,0fh        ; direccion del movimiento.
  771.  
  772.         mov bx, ds:Ancho_Pant   ; Centramos la lupa en la pantalla
  773.         shr bx, 1
  774.         mov ds:Pos_MX, bx
  775.         mov cx, ds:Alto_Pant
  776.         shr cx, 1
  777.         mov ds:Pos_MY, cx
  778. @Bucle_Prin:
  779.         push bx                 ; Paso de parametros
  780.         push cx
  781.         mov dx,OFFSET ds:Buffer_Fuente
  782.         push dx
  783.         call CargarBuffer       ; Leemos una zona de pantalla
  784.  
  785.         call TransfBuffer       ; La transformamos
  786.  
  787.         push bx                 ; Paso de parametros
  788.         push cx
  789.         mov dx,OFFSET ds:Buffer_Destino
  790.         push dx
  791.         call MostrarBuffer      ; La mostramos
  792.         cmp Increm_X,0          ; Miramos el signo
  793.         jl @Derecha_X
  794.                 push bx                 ; Si es positivo
  795.                 add bx, ds:Ancho_Img    ; Sumo a la posicion el ancho 
  796.                 cmp bx, ds:Ancho_Pant   ; y miro si es mayor que la pantalla
  797.                 pop bx                  ; Recupero la posicion
  798.                 jge @Revota_Izq_X       ; Si es menor que el fin de pantalla
  799.                         inc bx          ; me acerco uno mas
  800.                         jmp @Mueve_Y
  801.         @Revota_Izq_X:                  ; Estoy fuera de la pantalla
  802.                         neg Increm_X    ; Cambio el sentido del movimiento
  803.                         inc bx          ; hago un ultimo incremento
  804.                         jmp @Mueve_Y
  805. @Derecha_X:                             ; Si era negativo el sentido del movimiento
  806.                 cmp bx,0                ; Miro si estoy al comienzo de la pantalla
  807.                 jle @Revota_Der_X       ; No he llegado al principio todavia
  808.                         dec bx          ; me acerco uno mas
  809.                         jmp @Mueve_Y
  810.         @Revota_Der_X:                  ; Estoy en el comienzo de pantalla
  811.                         neg Increm_X    ; cambio el sentido
  812.                         dec bx          ; hago un ultimo decremento
  813.                         jmp @Mueve_Y
  814. @Mueve_Y:                               ; Para el movimiento en Y es
  815.         cmp Increm_Y,0                  ; exactamente lo mismo
  816.         jl @Subir_Y
  817.                 push cx
  818.                 add cx, ds:Ancho_Img
  819.                 cmp cx, ds:Alto_Pant
  820.                 pop cx
  821.                 jge @Revota_Sub_Y
  822.                         inc cx
  823.                         jmp @Fin_Mueve
  824.         @Revota_Sub_Y:
  825.                         neg Increm_Y
  826.                         inc cx
  827.                         jmp @Fin_Mueve
  828. @Subir_Y:
  829.                 cmp cx,0
  830.                 jle @Revota_Baj_Y
  831.                         dec cx
  832.                         jmp @Fin_Mueve
  833.         @Revota_Baj_Y:
  834.                         neg Increm_Y
  835.                         dec cx
  836.                         jmp @Fin_Mueve
  837. @Fin_Mueve:
  838.  
  839.         mov ah,6                ; Miro si se ha pulsado alguna tecla
  840.         mov dl,0ffh
  841.         int 21h                 ; se ve en el Flag Zero 
  842.         jz @Bucle_Prin
  843.         ret
  844. MovAuto ENDP
  845. ;##############################################
  846. ; Este procedimiento incrementa y decrementa
  847. ; tanto el radio como la distancia al plano
  848. ;##############################################
  849. Efecto PROC USES ax bx cx dx
  850. LOCAL Separar:BYTE, Dist_Ini:BYTE 
  851.         mov Separar, 0fh        ; El signo de esta veriable indica si se 
  852.                                 ; acerca o se separa la lente
  853.         mov ax, ds:Ancho_Pant   ; Centramos la lupa en la pantalla
  854.         shr ax, 1
  855.         mov ds:Pos_MX, ax
  856.         mov ax, ds:Alto_Pant
  857.         shr ax, 1
  858.         mov ds:Pos_MY, ax
  859.  
  860.         push ds:Pos_MX
  861.         push ds:Pos_MY
  862.         mov dx,OFFSET ds:Buffer_Fuente
  863.         push dx
  864.         call CargarBuffer       ; Leemos una unica vez de la pantalla
  865.         
  866.         xor cx,cx
  867.         mov cl, ds:Dist_Plano   ; Leemos la distancia al plano
  868.         mov Dist_Ini, cl        ; Empleamos una variable local para guardar
  869.                                 ; el valor antiguo
  870. @Bucle_Prin:
  871.         mov ds:Dist_Plano, cl
  872.         push cx
  873.         mov ax, ds:Ancho_img
  874.         push ax
  875.         call Crear_Matriz       ; Creamos una nueva matriz con el nuevo valor
  876.  
  877.         call TransfBuffer       ; Transformamos la imagen
  878.  
  879.         push ds:Pos_MX
  880.         push ds:Pos_MY
  881.         mov dx,OFFSET ds:Buffer_Destino
  882.         push dx
  883.         call MostrarBuffer      ; La colocamos
  884.         pop cx
  885.         cmp cx,0                ; Miramos si hemos llegado a pagar la lente
  886.                                 ; a la imagen
  887.         jle @Modifica
  888.         cmp cl, Dist_Ini        ; O si se ha separado del todo
  889.         jge @Modifica
  890.         jmp @Modificada
  891. @Modifica:
  892.         neg Separar             ; Cambiamos la direccion
  893. @Modificada:
  894.         cmp Separar, 0          ; Vemos cual es la direccion a seguir
  895.         jge @Acercar            ; y dependiendo de esta 
  896.                 dec cx          ; se decrementa la distancia al plano
  897.                 jmp @Fin_Mov
  898. @Acercar:
  899.                 inc cx          ; o se incrementa 
  900. @Fin_Mov:
  901.         mov ah,6                ; Miramos si se ha pulsado alguna tecla
  902.         mov dl,0ffh
  903.         int 21h
  904.         jz @Bucle_Prin
  905.         ret
  906. Efecto ENDP
  907. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  908. ; ▓▓▓  ▓▓▓   ▓▓   ▓▓   ▓▓  ▓   ▓  ▓▓   ▓▓▓  ▓▓▓  ▓ ▓  ▓  ▓▓  ▓ ▓▓▓   ▓▓  ▓
  909. ; ▓  ▓ ▓  ▓ ▓  ▓ ▓    ▓  ▓ ▓▓ ▓▓ ▓  ▓  ▓  ▓ ▓  ▓ ▓ ▓  ▓ ▓  ▓ ▓ ▓  ▓ ▓  ▓ ▓   
  910. ; ▓▓▓  ▓▓▓  ▓  ▓ ▓ ▓▓ ▓  ▓ ▓ ▓ ▓ ▓  ▓  ▓▓▓  ▓▓▓  ▓ ▓▓ ▓ ▓    ▓ ▓▓▓  ▓  ▓ ▓   
  911. ; ▓    ▓ ▓  ▓  ▓ ▓  ▓ ▓▓▓▓ ▓   ▓ ▓▓▓▓  ▓    ▓ ▓  ▓ ▓ ▓▓ ▓  ▓ ▓ ▓    ▓▓▓▓ ▓   
  912. ; ▓    ▓  ▓  ▓▓   ▓▓  ▓  ▓ ▓   ▓ ▓  ▓  ▓    ▓  ▓ ▓ ▓  ▓ ▓▓▓  ▓ ▓    ▓  ▓ ▓▓▓▓
  913. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  914. Codigo PROC  
  915.         mov dx,@DATA            ; Actualizar al valor del segemto de datos
  916.         mov ds,dx
  917.  
  918.         Modo13                  ; Establecer el modo de video 320x200x256
  919.  
  920.         mov dx, OFFSET ds:NombreTGA2    ; Pantalla de presentacion
  921.         push dx
  922.         mov dx, OFFSET ds:BufferTGA
  923.         push dx
  924.         mov dx, Ventana1                ; Directamente a pantalla
  925.         push dx
  926.         mov dx,0
  927.         push dx
  928.         call CargaTGA                   ; Mostrar la imagen de presentacion
  929.  
  930.         KeyPressed                      ; Hasta pulsar una tecla
  931.         ModoTx                  ; Modo de texto para pedir los parametros
  932.  
  933.         call Param              ; Pedir parametros
  934.         call Mi_Menu            ; Mostrar el menu de seleccion
  935.  
  936.         mov ax, ds:Ancho_img
  937.         push ax
  938.         call Crear_Matriz       ; Crea la matriz de transformacion
  939.  
  940.         Modo13                  ; Activa el modo de video
  941.  
  942.  
  943.         mov dx, OFFSET ds:NombreTGA     ; Imagen para el programa
  944.         push dx
  945.         mov dx, OFFSET ds:BufferTGA
  946.         push dx
  947.         mov dx, SEG Imagen              ; A un segemento aparate
  948.         push dx
  949.         mov dx,0
  950.         push dx
  951.         call CargaTGA                   ; Mueve la imagen al segmento
  952.  
  953.         mov dx, SEG Imagen              ; De donde voy a mover la imagen
  954.         push dx
  955.         mov dx,Ventana1                 ; Donde la voy a colocar
  956.         push dx
  957.         call copy64k                    ; Mueve 64000 bytes de uno a otro
  958.  
  959.         call Seleccion                  ; Realizar la operacion deseada
  960.         Salir
  961. Codigo ENDP
  962.        END Codigo
  963.