/*--------------------------------------------------------------------
 * FICHERO:  ZonBloq.c
 * OBJETIVO: Definir la funcin Zon_Bloque()
 * AUTOR:    Pedro Reina
 * FECHA:    S.5.8.1995
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Funciones privadas PC
 *
 *   Zon_BloqueVGA()
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Ficheros de cabecera
 *------------------------------------------------------------------*/

#include "Zona.h"

#ifdef OLIMPO_PC
#include <dos.h>    /* MK_FP() */
#endif

/*--------------------------------------------------------------------
 * Declaracin de funciones
 *------------------------------------------------------------------*/

#ifdef OLIMPO_PC
static void Zon_BloqueVGA();
#endif

/*--------------------------------------------------------------------
 * Definicin de funciones
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Zon_Bloque()
 * OBJETIVO: Dibujar un bloque rectangular
 * ENTRADAS: Una zona, las coordenadas de dos puntos
 *           diagonalmente opuestos del bloque y el color
 * SALIDAS:  La zona
 * EJEMPLO:  Zon_Bloque ( Imagen, 20.4, 15.8, 59.0, 12.7, ROJO )
 *------------------------------------------------------------------*/
zona Zon_Bloque (Zona, X1, Y1, X2, Y2, Color)
zona   Zona;
real   X1, Y1, X2, Y2;
octeto Color;
  {
  contador Xf1, Xf2, Yf1, Yf2;

  Xf1 = Zon_Abscisa (Zona, X1);
  Xf2 = Zon_Abscisa (Zona, X2);
  Yf1 = Zon_Ordenada (Zona, Y1);
  Yf2 = Zon_Ordenada (Zona, Y2);

  Xf1 = Max (0, Xf1); Xf1 = Min (Zon_AnchoFisico(Zona)-1, Xf1);
  Xf2 = Max (0, Xf2); Xf2 = Min (Zon_AnchoFisico(Zona)-1, Xf2);
  Yf1 = Max (0, Yf1); Yf1 = Min (Zon_AltoFisico(Zona)-1, Yf1);
  Yf2 = Max (0, Yf2); Yf2 = Min (Zon_AltoFisico(Zona)-1, Yf2);

#ifdef OLIMPO_PC
  Zon_BloqueVGA (Zon_MargenIzquierdo(Zona) + Min(Xf1,Xf2),
                 Zon_MargenSuperior(Zona)  + Min(Yf1,Yf2),
                 Zon_MargenIzquierdo(Zona) + Max(Xf1,Xf2),
                 Zon_MargenSuperior(Zona)  + Max(Yf1,Yf2), Color);
#endif

#ifdef OLIMPO_QL
  Pan_Bloque (Color, Abs(Xf2-Xf1)+1, Abs(Yf2-Yf1)+1,
             Zon_MargenIzquierdo(Zona) + Min(Xf1,Xf2) - Pan_MargenIzquierdo(),
             Zon_MargenSuperior(Zona)  + Min(Yf1,Yf2) - Pan_MargenSuperior());
#endif

  return ( Zona );
  }

#ifdef OLIMPO_PC
/*--------------------------------------------------------------------
 * FUNCION:  Zon_BloqueVGA()
 * OBJETIVO: Dibujar un bloque rectangular en una pantalla VGA
 * ENTRADAS: Las coordenadas de la esquina superior izquierda y la
 *           inferior derecha y el color
 * SALIDAS:  Ninguna
 * EJEMPLO:  Zon_BloqueVGA ( 20, 15, 59, 80, ROJO )
 *------------------------------------------------------------------*/
#pragma warn -aus
static void Zon_BloqueVGA (X1, Y1, X2, Y2, Color)
contador X1, Y1, X2, Y2;
octeto   Color;
  {
  octeto   MascaraInicial, MascaraFinal;
  contador Columna, Primero, Ultimo, Comienzo, Final, Inutil;
  entero   FilaSup, FilaInf, Fila;
  char far * Direccion;

  FilaSup = Y1 * 80L;
  FilaInf = Y2 * 80L;
  Comienzo = X1/8;
  Final = X2/8;
  Primero = X1 - Comienzo*8;
  Ultimo = X2 - Final*8 + 1;
  MascaraInicial = 0xFF >> Primero;
  MascaraFinal = 0xFF << (8-Ultimo);

  if ( Comienzo != Final )
    {
    for (Fila=FilaSup; Fila<=FilaInf; Fila+=80)
      {
      Direccion = MK_FP (0xA000, Fila+Comienzo);
      Pan_MandaOrden (0x3CE,8,MascaraInicial);
      Pan_MandaOrden (0x3C4,2,0x0F);
      Inutil = *Direccion;
      *Direccion = 0;
      Pan_MandaOrden (0x3C4,2,Color);
      *Direccion = MascaraInicial;

      Pan_MandaOrden (0x3CE,8,0xFF);
      for (Columna=Comienzo+1; Columna<Final; Columna++)
        {
        Direccion++;
        Pan_MandaOrden (0x3C4,2,0x0F);
        Inutil = *Direccion;
        *Direccion = 0;
        Pan_MandaOrden (0x3C4,2,Color);
        *Direccion = 0xFF;
        }

      Direccion++;
      Pan_MandaOrden (0x3CE,8,MascaraFinal);
      Pan_MandaOrden (0x3C4,2,0x0F);
      Inutil = *Direccion;
      *Direccion = 0;
      Pan_MandaOrden (0x3C4,2,Color);
      *Direccion = MascaraFinal;
      }  /* Fin for Fila */
    }
    
  else  /* Comienzo == Final */
    {
    MascaraInicial &= MascaraFinal;
    for (Fila=FilaSup; Fila<=FilaInf; Fila+=80)
      {
      Direccion = MK_FP (0xA000, Fila+Comienzo);
      Pan_MandaOrden (0x3CE,8,MascaraInicial);
      Pan_MandaOrden (0x3C4,2,0x0F);
      Inutil = *Direccion;
      *Direccion = 0;
      Pan_MandaOrden (0x3C4,2,Color);
      *Direccion = MascaraInicial;
      }
    }

  Pan_MandaOrden (0x3C4,2,0x0F);
  Pan_MandaOrden (0x3CE,3,0);
  Pan_MandaOrden (0x3CE,8,0xFF);
  }
#pragma warn +aus
#endif
