 /*************************************************************************\
|*                                                                         *|
|* Nombre de Fichero:  FREC_M .CPP                                         *|
|*                                                                         *|
|* Nombre de Programa: Generador/Capturador de formas de ondas.            *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              M¢dulo principal.                                          *|
|*                                                                         *|
|* Entradas: (ninguna)                Creaci¢n:                            *|
|* Salidas:  (ninguna)                          25-04-95   20:05    23:30  *|
|*                                                 ...      ...      ...   *|
|*                                              11-05-96   12:30    17:15  *|
|*                                              12-05-96   18:26    20:05  *|
|*                                                 ...      ...      ...   *|
|*                                              28-05-96   15:50    17:26  *|
|*                                              29-05-96   15:45    16:30  *|
|*                                              31-05-96   11:15    13:00  *|
|*                                               1-06-96   16:00    19:05  *|
|*                                               2-06-96   18:54    20:20  *|
|*                                                                         *|
 \*************************************************************************/

#include <dos.h>
#include <dir.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <alloc.h>
#include <graphics.h>

#include "..\..\libs\make_bot\make_bot.h"
#include "frec.h"
#include "dibujos.h"
#include "frec_f.h"

//////////////////////////////////////////////////////////////////////////////
void MenuPupUp( int Px, int Py );
//////////////////////////////////////////////////////////////////////////////
int Sensibilidad = 0;
/****//****//****//****//****//****//****//****//****//****//****//****/
typedef struct
{
 int Ex, Ey, Ez;
 char Ecolor;
} CAMPO_de_ESTRELLAS;

char START_3D = ON;

extern CAMPO_de_ESTRELLAS *Cestrellas, *o;

extern void deinit_star(void);
extern void init_star(void);
extern void Actualiza(CAMPO_de_ESTRELLAS *Cest);
/****//****//****//****//****//****//****//****//****//****//****//****/
extern void JuegoTRON(void);


char count=0, intvect = OFF;
char CheckBoton_Linkers( int statusBoton, int BPush );
void SalvarCargar_Onda( char _SalvarCargar );

void interrupt handler(__CPPARGS);
void interrupt ( *oldhandler)(__CPPARGS);

int Espera_TelcaRaton_FREC(void);
int far Select_Mouse_Action(void);
char GeneraOnda(void);
void InitScreen(void);

char tipoOnda = 0;

CFG_FREC cfgFREC = {
                    // N§'s grandes
                    EGA_RED,
                    EGA_BLACK,
                    EGA_DARKGRAY,
                    // Letras Digitales
                    EGA_WHITE,
                    EGA_RED,
                    // Onda Osciloscopio
                    EGA_LIGHTGRAY,
                    EGA_GREEN,
                    EGA_BLUE,
                    // Onda Generada
                    EGA_RED,//LIGHTGRAY,
                    EGA_GREEN,
                    // Cuadro MiniOnda
                    EGA_GREEN,
                    EGA_BLUE,
                    EGA_RED + 11,
                    // Texto
                    EGA_YELLOW,
                    EGA_YELLOW,
                    EGA_RED
                   };



int statusBoton=-1;

  p_graphics Numeros = { 15,  15,  6, 3, 3, cfgFREC.nBorde, cfgFREC.nRelleno, cfgFREC.nFondo };
  p_graphics Letras  = { 17,  92, 13, 1, 1, cfgFREC.lFondo, cfgFREC.lLetra,                0 };

int main(void){

 char Buffer[80];
 int numero=0, xM;
 int BPush;
 Dispersion = 5;

 InitScreen();

 setrgbpalette(EGA_WHITE,     56, 58, 59 );
 setrgbpalette(EGA_LIGHTGRAY, 30, 37, 43 );
 setrgbpalette(EGA_DARKGRAY,   24, 27, 30 );


/****//****//****//****//****//****//****//****//****//****//****//****/
init_star();
/****//****//****//****//****//****//****//****//****//****//****//****/



  	Numero_Digital( numero,  &Numeros );

  	sprintf( Buffer, "1996 (c) JD. " );

     	Fuente_Amplia( Buffer, &Letras );

while(1){				  // Bucle infinito
 BPush = Comprueba_Secuencia( 1, Select_Mouse_Action );
 desactiva_raton();
 // Chequea los linkers a botones de un boton pulsado con linkers
 if ( statusBoton != -1 && CheckBoton_Linkers( statusBoton, BPush ) != OK )
                                                                            BPush = statusBoton;
 switch( BPush ) {     // Iniciamos comprobacion

       case  0:				  // No se pulso ningun BOTON
	       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
                                          // El raton todav¡a sigue pulsado
	       break;
       case -2:
               while( kbhit() ) getch();
                                          // Tecla Normal
       case -1:				  // Hay una tecla especial en BUFFER
	               			  // La eliminamos
               while( kbhit() ) getch();
	       break;
       // Boton Selecci¢n GENERADOR/OSCILOSCOPIO
       case  1:
               SeleccionaControles();
	       break;
       // Enviar/Recibir onda SI / NO
       case  2:
               EnviaRecibe();
               break;
       case  3:
               // Sin uso Actualmente.
               break;
       case  4:
               // Sin uso Actualmente.
               break;
       case  5:
               // Salvar
               SalvarCargar_Onda( Salvar );
               break;
       case  6:
               // Cargar
               if ( GenOsc == GENERADOR )
                                          SalvarCargar_Onda( Cargar );
               break;
       case  7:
              /* reset the old interrupt handler */
              if ( intvect == ON )
                            setvect(INTR, oldhandler);

              free( OndaGenerada  );
              free( oOndaGenerada );
              free( cOndaGenerada );
              free( mOndaGenerada );

              /****//****//****//****//****//****//****//****//****//****//****//****/
              deinit_star();
              /****//****//****//****//****//****//****//****//****//****//****//****/

              restorecrtmode();
              printf( "\n Bueno, ya habe¡s visto algunas de las posibilidades de este                 ");
              printf( "\n programa. Si de verdad estais interesados en el, esperad a                  ");
              printf( "\n verlo funcionar junto a su Hardward.                                        ");
              printf( "\n                                                                             ");
              printf( "\n Para obtener mas informacion sobre el hardware:                             ");
              printf( "\n                                                 infomundo@arrakis.es        ");
              printf( "\n Para obtener informacion del software o su creador:                         ");
              printf( "\n                                                 Jose-David.Guillen@cs.us.es ");
              printf( "\n                                                 guill@cs.us.es              ");
              printf( "\n                                                 infomundo@arrakis.es        ");
              printf( "\n                                                                             ");
              printf( "\n                                                                             ");
              printf( "\nFuTuRe ViSiOn: Jos‚ David Guill‚n, %s", Buffer );

              printf( "\nFuTuRe ViSiOn: Jos‚ David Guill‚n, %s", Buffer );

	      return 0;
       case  8:
              // Ayuda on-line
              break;
       case  9:
              // Creditos
              break;
       case 10:
              // Sin uso Actualmente
              break;
       case 11:
              // Cuadro Amplitud
              break;
       case 12:
              // Cuadro unidades Amplitud
              break;
       case 13:
              // Cuadro Periodo
              break;
       case 14:
              // Cuadro unidades Periodo
              break;
       case 15:
              // Sin uso Actualmente
              // Bloque de cursores 9
              break;
       case 16:
              // Bloque de cursores  Flecha derecha
              switch( statusBoton )
              {
               case  25:
                        // Crea Tipo de Onda
                        ReajustaTipoOnda( DERECHA );
                        break;
               case  17:
                        // MRK
                        DesplazaMarca( IncrementoMarca, INICIO );
                        break;
               default:
                        DesplazaOnda( DERECHA );
                        break;
              }
              break;
       case 17:
              // Bloque de cursores  Marcar parte de la onda
              // Marca o desmarca la parte de onda seleccionada
              Dibuja_OndaSeleccionada(PINTA);
              if ( statusBoton == BPush )
              {
                   ponicono( 623, 100, led_off, 1 );
                   statusBoton = -1;
              } else {
                   statusBoton = BPush;
                   ponicono( 623, 100, led_on,  1 );
                   Numero_Digital( -1*OndaGenerada[x_raton+5 * Desplazamiento],  &Numeros );
              }
              break;
       case 18:
              // Bloque de cursores  Flecha Arriba
              switch( statusBoton )
              {
               case  25:
                        // Crea Tipo de Onda
                        ReajustaTipoOnda( ARRIBA );
                        break;
               case  23:
                        // Tierra
                        ReajusteTierra( ARRIBA );
                        break;
               case  17:
                        DesplazaMarca( -1*IncrementoMarca, FIN );
                        break;
               default:
                        DesplazaOnda( ARRIBA );
                        break;
              }
              break;
       case 19:
              // Bloque de cursores  Centrar Cero
              switch( statusBoton )
              {
               case  17:
                        DesplazaMarca( 0, TODO );
                        break;
               default:
                        DesplazaOnda( CENTRAR );
                        break;
              }
              break;
       case 20:
              // Bloque de cursores  Flecha Abajo
              switch( statusBoton )
              {
               case  25:
                        // Crea Tipo de Onda
                        ReajustaTipoOnda( ABAJO );
                        break;
               case  23:
                        // Tierra
                        ReajusteTierra( ABAJO );
                        break;
               case  17:
                        DesplazaMarca( IncrementoMarca, FIN );
                        break;
               default:
                        DesplazaOnda( ABAJO );
                        break;
              }
              break;
       case 21:
              // Sin uso Actualmente
              // Bloque de cursores 7
              JuegoTRON();
              break;
       case 22:
              // Bloque de cursores  Flecha izquierda
              switch( statusBoton )
              {
               case  25:
                        // Crea Tipo de Onda
                        ReajustaTipoOnda( IZQUIERDA );
                        break;
               case  17:
                        // MRK
                        DesplazaMarca( -1*IncrementoMarca, INICIO );
                        break;
               default:
                        DesplazaOnda( IZQUIERDA  );
                        break;
              }
              break;
       case 23:
              // Bloque de cursores  Tierra ( ajuste )
              if ( statusBoton == BPush )
              {
                   ponicono( 572, 100, led_off, 1 );
                   statusBoton = -1;
              } else {
                   statusBoton = BPush;
                   ponicono( 572, 100, led_on, 1 );
              }
              break;
       case 24:
              // Selecciona toda la onda
              break;
       case 25:
              // Estancar proceso de crear tipo de onda
              if ( statusBoton == BPush )
              {
                   // Apagamos la luz de marcar onda
                   ponicono( 623, 100, led_off, 1 );
                   // Led Off ( para anclar onda )
                   ponicono( 369,   7, led_off, 1 );
                   statusBoton = -1;
                   Tonda = -1;
                   Redibuja_MiniOnda();
              } else {
                   Dibuja_OndaSeleccionada(PINTA);
                   statusBoton = BPush;
                   ponicono( 369,   7, led_on, 1 );
              }
              break;
       case 26:
              // Retroceder tipo de onda
              tipoOnda --;
              if ( tipoOnda < 0 )
                                   tipoOnda = 0;
              setwritemode( COPY_PUT );
              setfillstyle( SOLID_FILL, EGA_LIGHTGRAY );
              bar( 427, 3, 450, 21 );
              bar( 456, 3, 479, 21 );
              bar( 485, 3, 508, 21 );
              ponicono( 430,   3, TipoOnda[ tipoOnda     ], 1 );
              ponicono( 459,   3, TipoOnda[ tipoOnda + 1 ], 1 );
              ponicono( 488,   3, TipoOnda[ tipoOnda + 2 ], 1 );
              break;
       case 27:
       case 28:
       case 29:
              if ( statusBoton == 25 )
              {
               // Genera onda
               Tonda = (BPush-27)+tipoOnda+1;
               // Crea Tipo de Onda
               ReajustaTipoOnda( CENTRAR );
              }
              break;
       case 30:
              // Avanzar tipo de onda
              tipoOnda ++;
              if ( tipoOnda > 7 )
                                   tipoOnda = 7;
              setwritemode( COPY_PUT );
              setfillstyle( SOLID_FILL, EGA_LIGHTGRAY );
              bar( 427, 3, 450, 21 );
              bar( 456, 3, 479, 21 );
              bar( 485, 3, 508, 21 );
              ponicono( 430,   3, TipoOnda[ tipoOnda     ], 1 );
              ponicono( 459,   3, TipoOnda[ tipoOnda + 1 ], 1 );
              ponicono( 488,   3, TipoOnda[ tipoOnda + 2 ], 1 );
              break;
       case 31:
              // Sin uso Actualmente
              break;
       case 32:
              // Sin uso Actualmente
              break;
       case 33:
              // Sin uso Actualmente
              break;
       default:
               while( kbhit() ) getch();
	       break;
 }
 activa_raton();
}

}

/***************************************************************************\
|*                                                                         *|
|* InitScreen                                                              *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              Inicializa la pantalla y el entorno completo               *|
|*                                                                         *|
|* Entradas: (ninguna)                                                     *|
|*                                                                         *|
|*                                                                         *|
|*                                                                         *|
|* Salidas:  (ninguna)                                                     *|
|*                                                                         *|
\***************************************************************************/
void InitScreen(void)
 {
    Initialize( 9, 2 );         	   // Inicializa el Modo Gr fico

    Imprime_Estaticos( 1, "Frec.img");     // Imprime botones estaticos 'Seccion 1'

    if ( carga_botones( "Frec.img" ) != 0 )
                                        exit ( 1 );

    Imprime_Secuencia( 1 );

    Imprime_Estaticos( 2, "Frec.img");     // Imprime botones estaticos 'Seccion 1'

    // Cursores   << /\ \/ >>
                    ponicono( 593,  51, flecha, 4 );
    ponicono( 569,  75, flecha, 1 ); ponicono( 620,  75, flecha, 3 );
                    ponicono( 593, 100, flecha, 2 );
    // Cursores tipo de onda << >>
    ponicono( 401,   3, flecha, 1 ); ponicono( 517,   3, flecha, 3 );
    // Flecha funcionar GENERADOR / OSCILOSCOPIO
    ponicono( 319,   3, flecha, 3 );
    // Dibujo cargar
    ponicono( 245,  52, cargar, 1 );
    // Dibujo salvar
    ponicono( 245,  76, salvar, 1 );
    // Dibujo salir
    ponicono( 245,  99, salir, 1 );
    // Led Off ( no enviar onda )
    ponicono( 245,   7, led_off, 1 );
    // Led Off ( para anclar onda )
    ponicono( 369,   7, led_off, 1 );
    // Led Off ( para marcar la onda )
    ponicono( 623, 100, led_off, 1 );
    // Led Off ( para colocar la linea del cero )
    ponicono( 572, 100, led_off, 1 );
    // Ayuda on-Line
    ponicono( 345,   6, help, 1 );
    // Creditos
    ponicono( 345,  37, CREDITS, 1 );
    // Iconos con los tipos de ondas
              ponicono( 430,   3, TipoOnda[ tipoOnda     ], 1 );
              ponicono( 459,   3, TipoOnda[ tipoOnda + 1 ], 1 );
              ponicono( 488,   3, TipoOnda[ tipoOnda + 2 ], 1 );


    // Inicializamos la GranOnda y la MiniOnda
    if ( GeneraOnda() != OK )
    {
     restorecrtmode();
     printf("\n Memoria insuficiente para la representaci¢n lineal de la onda\n");
     exit(-1);
    }

    True_Push = ON;
    PunteroRaton = 1;
    inicializa_raton_grafico( 0, 0, alcanceRatonX, alcanceRatonY );

    /* save the old interrupt vector */
    oldhandler = getvect(INTR);
    /* install the new interrupt handler */

    intvect = ON;
    setvect(INTR, handler);


 }

/***************************************************************************\
|*                                                                         *|
|* GeneraOnda                                                              *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              Inicializa la memoria y dibuja una onda por defecto        *|
|*                                                                         *|
|* Entradas: (ninguna)                                                     *|
|*                                                                         *|
|*                                                                         *|
|*                                                                         *|
|* Salidas:  Estado de la inicializaci¢n                                   *|
|*                                                                         *|
\***************************************************************************/
char GeneraOnda(void)
{
 int xM, yM;

 // Pedimos memoria e inicializamos la onda a una onda nula.
 if ( ( OndaGenerada   = (int *)calloc( oAnchoVentana * oVentanas + 20, sizeof(int) ) ) == NULL )
 									return ERROR;
 // Memoria para el contenido anterior a los puntos de la GRANDEo
 if ( ( oOndaGenerada  = (int *)calloc( oAnchoVentana     +     20, sizeof(int ) ) ) == NULL )
                                                                        return ERROR;
 if ( ( cOndaGenerada  = (char*)calloc( oAnchoVentana     +     20, sizeof(char) ) ) == NULL )
                                                                        return ERROR;
 if ( ( mOndaGenerada  = (int *)calloc( oAnchoVentana     +     20, sizeof(int ) ) ) == NULL )
                                                                        return ERROR;


 for ( int x = 0; x <= (oAnchoVentana * oVentanas) / 3;     x++ )
                                         OndaGenerada[ x ] = (int)(sin( x * 0.05 ) * 50);
 int a, i=1;

 a = OndaGenerada[ x-1 ];
 for (         x; x <= ((oAnchoVentana * oVentanas) / 3)*2; x++ )
  {
   if ( a ==  50 ) i = 1;
   if ( a == -50 ) i = 0;
   if ( i ==   0 ) a ++; else a--;
                                     OndaGenerada[ x ] = a;
  }
 for (         x; x < (oAnchoVentana * oVentanas)       ; x++ )
                                         OndaGenerada[ x ] = (int)(sin( (x+23) * 0.07) * 60);

 // Dibujamos matrix, linea del cero y Gran Onda
 for ( xM = 0;  ( xM + inicioMGx ) < ( oAnchoVentana + inicioMGx ); xM += SaltosMatrixX )
  for ( yM = 0; ( yM + inicioMGy ) < ( oAltoVentana + inicioMGy  ); yM += SaltosMatrixY )
   putpixel( xM + inicioMGx, yM + inicioMGy, cfgFREC.gMatrix );
 // Linea del cero
 setcolor( cfgFREC.gMatrix );
 setwritemode( XOR_PUT );
 line( inicioMGx, inicioMGy+ceroOGenerada, inicioMGx + oAnchoVentana, inicioMGy + ceroOGenerada );
 setwritemode( COPY_PUT );
 DibujaOnda(oDesde + 5 * Desplazamiento, oHasta + 5 * Desplazamiento,  oAnchoVentana, oAltoVentana, GRANDEo );


 // Fondo y MiniOnda
 setfillstyle( SOLID_FILL, cfgFREC.mFondo );
 bar(  8, inicioMmGy, 633, inicioMmGy + mAltoCuadro );
 DibujaOnda(     0, oFinalOnda, oAnchoVentana,   mAltoCuadro, MINIo   );
 // Cuadro onda visible
 setcolor( cfgFREC.mMarco );
 setwritemode( XOR_PUT );
 rectangle( 8, inicioMmGy, 8 + mAnchoMarco, inicioMmGy + mAltoCuadro );
 setwritemode( COPY_PUT );


 return OK;
}



/***************************************************************************\
|*                                                                         *|
|* Select_Mouse_Action                                                     *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              Control interactivo del raton.                             *|
|*                                                                         *|
|* Entradas: (ninguna)                                                     *|
|*                                                                         *|
|*                                                                         *|
|*                                                                         *|
|* Salidas:  (ninguna)                                                     *|
|*                                                                         *|
\***************************************************************************/
int far Select_Mouse_Action(void)
{
  int ox_raton = -1, oy_raton = -1;

  activa_raton();

  union REGS io;
  io.x.ax = 3;

  do{
      int86(0x33, &io, &io);    // lee posici¢n y estados del bot¢n

      x_raton = io.x.cx;
      y_raton = io.x.dx;
/***************************************************************************/
if ( START_3D == ON )
      Actualiza(Cestrellas);
/***************************************************************************/
//      boton_izq = io.x.bx & 1;
//      boton_der = (io.x.bx >> 1) & 1;




    if ( y_raton >=  (inicioMGy + oAltoVentana + factorCorreccionRatonY) )
       {
           if ( y_raton >= inicioMmGy && x_raton >= ( 8 + Desplazamiento) && x_raton <= (8 + mAnchoMarco + Desplazamiento)  )
           {
             if ( PunteroRaton != 3 )
                                {
                                 PunteroRaton = 3;
                                 Carga_Puntero ();
                                }
           } else {
             if ( PunteroRaton != 1 )
                                {
                                 PunteroRaton = 1;
                                 Carga_Puntero ();
                                }
           }
       } else

    if ( PunteroRaton != 2 && y_raton >= ( inicioMGy - 8 )  && y_raton < ( inicioMGy + oAltoVentana + factorCorreccionRatonY ) )
       {
         PunteroRaton = 2;
         Carga_Puntero ();
       } else
    if ( PunteroRaton != 1 && y_raton <  ( inicioMGy - 8 ) )
       {
         PunteroRaton = 1;
         Carga_Puntero ();
       }

    // BARRA DE LA ONDA REDUCIDA
    if ( y_raton >= (inicioMGy + oAltoVentana + factorCorreccionRatonY) &&
         x_raton >= (8 + Desplazamiento) && x_raton <= (8 + mAnchoMarco + Desplazamiento)
       )
     if ( (io.x.bx & 1) )
     {

      // Desplazamiento normal del cuadro actual ( tama¤o actual tambien )
      ox_raton = x_raton;
      setwritemode( XOR_PUT );
      setcolor( cfgFREC.mMarco );

      do {
            int86(0x33, &io, &io);    // lee posici¢n y estados del bot¢n

            x_raton = io.x.cx;
            y_raton = io.x.dx;
            if ( ox_raton != x_raton && ( mAnchoMarco + Desplazamiento ) <= oAnchoVentana && Desplazamiento >= 0 )
            {
                        desactiva_raton();
                        // Limpiamos la zona antigua
                        rectangle( 8 + Desplazamiento, inicioMmGy, 8 + mAnchoMarco + Desplazamiento, inicioMmGy + mAltoCuadro );

                        Desplazamiento+= x_raton - ox_raton;

                        if ( Desplazamiento < 0 ) Desplazamiento = 0; else
                        if ( ( mAnchoMarco + Desplazamiento ) > oAnchoVentana )
                              Desplazamiento = oAnchoVentana - mAnchoMarco;

                        rectangle( 8 + Desplazamiento, inicioMmGy, 8 + mAnchoMarco + Desplazamiento, inicioMmGy + mAltoCuadro );

                        activa_raton();
            }
            ox_raton = x_raton;

/***************************************************************************/
if ( START_3D == ON )
      Actualiza(Cestrellas);
/***************************************************************************/
      } while( (io.x.bx & 1) || ((io.x.bx >> 1) & 1) );

      desactiva_raton();
      setwritemode( COPY_PUT );
      // Tras desplazar redibujamos la onda
      DibujaOnda(oDesde +  5 * Desplazamiento, oHasta +  5 * Desplazamiento,  oAnchoVentana, oAltoVentana, GRANDEo );

      activa_raton();

     } else if ( ((io.x.bx >> 1) & 1) )
     {
      // Selecci¢n de la posicion y tama¤o del cuadro

     }

     if ( y_raton >= inicioMGy && y_raton <= (inicioMGy + oAltoVentana) &&
         x_raton >= 0 && x_raton <= (inicioMGx + oAnchoVentana)  )
     {
      if ( (io.x.bx & 1) || ((io.x.bx >> 1) & 1) )
      {
       if ( statusBoton == 17 )
       {
              desactiva_raton();

              if (io.x.bx & 1)
              {
                            MRK_begin = x_raton*((float)( oHasta - oDesde ) / (float)oAnchoVentana) + 5 * Desplazamiento;
                            while ( MRK_begin > MRK_end ) MRK_begin--;
              } else {
                            MRK_end   = x_raton*((float)( oHasta - oDesde ) / (float)oAnchoVentana) + 5 * Desplazamiento;
                            while ( MRK_end < MRK_begin ) MRK_end++;
              }
              Dibuja_OndaSeleccionada( !PINTA );
              Numero_Digital( -1*OndaGenerada[(int)(x_raton*((float)( oHasta - oDesde ) / (float)oAnchoVentana) + 5 * Desplazamiento)],  &Numeros );
              activa_raton();
              Anclar_Raton();
       } else {

         if ( ((io.x.bx >> 1) & 1) )
         {
                Anclar_Raton();
                desactiva_raton();
                MenuPupUp( x_raton , y_raton );
                activa_raton();
         } else {

              // Retoque manual de la onda + proceso de perfilado autom tico
              desactiva_raton();
              do{
               if ( oy_raton != y_raton || ox_raton != x_raton )
                if ( y_raton >= inicioMGy && y_raton <= (inicioMGy + oAltoVentana) &&
                            x_raton >= 0 && x_raton <= (inicioMGx + oAnchoVentana)  )
                {

                 oy_raton = y_raton; ox_raton = x_raton;

                 Retoca_Punto( x_raton*((float)( oHasta - oDesde ) / (float)oAnchoVentana) + 5 * Desplazamiento,
                           (y_raton - inicioMGy - ceroOGenerada)/*ReduccionY*/ );
                } else break;
               int86(0x33, &io, &io);    // lee posici¢n y estados del bot¢n
               x_raton = io.x.cx;
               y_raton = io.x.dx;

/***************************************************************************/
if ( START_3D == ON )
      Actualiza(Cestrellas);
/***************************************************************************/
              }while( (io.x.bx & 1) || ((io.x.bx >> 1) & 1));
              Redibuja_MiniOnda();
              activa_raton();

         }


       }

       int86(0x33, &io, &io);    // lee posici¢n y estados del bot¢n

      }
     }

  }while( (io.x.bx & 1) == 0 && ((io.x.bx >> 1) & 1) == 0 && !kbhit()/*!MB_TeclaPulsada()*/ );


  /////////////////////////////////////////
  //     RETURN    Derecho   Izquierdo   //
  //                                     //
  //       0         0           0       //
  //       1         1           0       //
  //       2         0           1       //
  //       3         1           1       //
  //                                     //
  /////////////////////////////////////////

  desactiva_raton();

  if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==0 ) return 0;
  if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==0 ) return 1;
  if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==1 ) return 2;
  if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==1 ) return 3;

  return 0;
}



/***************************************************************************\
|*                                                                         *|
|* INT CLK                                                                 *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              interrupci¢n para el parpadeo de los led's                 *|
|*                                                                         *|
|* Entradas: (indeterminadas)                                              *|
|*                                                                         *|
|*                                                                         *|
|*                                                                         *|
|* Salidas:  (ninguna)                                                     *|
|*                                                                         *|
\***************************************************************************/
void interrupt handler(__CPPARGS)
{
/* increase the global counter */
   count = (count++)%16;
   if ( count == 1 )
   {
         setpalette( 11,  EGA_GREEN      );
         setpalette( 13,  EGA_LIGHTGREEN );
   }
   else if ( count == 8 )
   {
         setpalette( 11, EGA_RED        );
         setpalette( 13, EGA_LIGHTRED   );

   }

/* call the old routine */
   oldhandler();
}

/***************************************************************************\
|*                                                                         *|
|* SalvarCargar_Onda                                                       *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              Salva o carga una forma de onda.                           *|
|*                                                                         *|
|* Entradas:                                                               *|
|*           Salvar/Cargar                                                 *|
|*                                                                         *|
|*                                                                         *|
|* Salidas:  (ninguna)                                                     *|
|*                                                                         *|
\***************************************************************************/
void SalvarCargar_Onda( char _SalvarCargar )
{
 char Buffer[500] = "*.OND";
 char Buffer2[13];

	union   REGS ent, sal;
	ent.x.ax =    8;	ent.x.cx =    0;	ent.x.dx =  480;
	int86(0x33, &ent, &sal);    /* fija la posici¢n m x. y m¡n. vertical */
        activa_raton();


if ( _SalvarCargar == Salvar )
{
  if ( file_browser( Buffer, "Salvar Forma de Onda", 1 ) )
 {

    char drive[MAXDRIVE];
    char dir[MAXDIR];
    char file[MAXFILE];
    char ext[MAXEXT];
    int flags;

    flags=fnsplit(Buffer,drive,dir,file,ext);
    if( !(flags & EXTENSION) )
                 strcpy( ext, ".OND" );
    fnmerge(Buffer ,drive,dir,file,ext);


  // Buffer contiene el path completo para el archivo a salvar.
 }
} else {

  if ( file_browser( Buffer, "Cargar Forma de Onda", 0 ) ) {

  // Buffer contiene el path completo para el archivo a cargar...
  while( kbhit() ) getch();
  // A cargar la onda
 }

}

	ent.x.ax =    8;	ent.x.cx =    0;	ent.x.dx =  alcanceRatonY;
	int86(0x33, &ent, &sal);    /* fija la posici¢n m x. y m¡n. vertical */

}


/***************************************************************************\
|*                                                                         *|
|* CheckBoton_Linkers                                                      *|
|*                                                                         *|
|* Descripci¢n:                                                            *|
|*              Chequea que el boton pulsado, tiene un LINK con el activo  *|
|*                                                                         *|
|* Entradas:                                                               *|
|*           Boton activo                                                  *|
|*           Boton pulsado                                                 *|
|*                                                                         *|
|* Salidas:                                                                *|
|*           OK   Linker definido correctamente                            *|
|*           ERROR                                                         *|
|*                                                                         *|
\***************************************************************************/
char CheckBoton_Linkers( int statusBoton, int BPush )
{
 switch( BPush ) {     // Iniciamos comprobacion

       case  0:
       case -2:
       case -1:
            return OK;
               break;
       // Boton Selecci¢n GENERADOR/OSCILOSCOPIO
       case  1:
	       break;
       case  2:
               // Enviar/Recibir onda SI / NO
               break;
       case  3:
               // Sin uso Actualmente.
               break;
       case  4:
               // Sin uso Actualmente.
               break;
       case  5:
               // Salvar
               break;
       case  6:
               // Cargar
               break;
       case  8:
              // Ayuda on-line
              break;
       case  9:
              // Creditos
              break;
       case 10:
              // Sin uso Actualmente
              break;
       case 11:
              // Cuadro Amplitud
              break;
       case 12:
              // Cuadro unidades Amplitud
              break;
       case 13:
              // Cuadro Periodo
              break;
       case 14:
              // Cuadro unidades Periodo
              break;
       case 15:
              // Sin uso Actualmente
              // Bloque de cursores 9
              break;

       case 20:
              // Bloque de cursores  Centrar Cero
       case 18:
       case 19:
       case 22:
       case 16:
              // Bloque de cursores  Flecha Arriba
              // Bloque de cursores  Flecha Abajo
              // Bloque de cursores  Flecha izquierda
              // Bloque de cursores  Flecha derecha
              if ( statusBoton == 23/*GND*/ ) return OK;
              if ( statusBoton == 17/*MRK*/ ) return OK;
              if ( statusBoton == 25/*CPY*/ ) return OK;
              break;

       case 17:
              // Bloque de cursores  Marcar parte de la onda
              break;
       case 21:
              // Sin uso Actualmente
              // Bloque de cursores 7
              break;
       case 23:
              // Bloque de cursores  Tierra ( ajuste )
              break;
       case 24:
              // Selecciona toda la onda
              break;
       case 25:
              // Estancar proceso de copiar tipo de onda
              if ( statusBoton == 17/*MRK*/ ) return OK;
              break;
       case 26:
       case 30:
              // Avanzar tipo de onda
              // Retroceder tipo de onda
       case 27:
       case 28:
       case 29:
              // Genera onda
              if ( statusBoton == 25/*CPY*/ ) return OK;
              break;
       case 31:
              // Sin uso Actualmente
              break;
       case 32:
              // Sin uso Actualmente
              break;
       case 33:
              // Sin uso Actualmente
              break;
       default:
               return ERROR;
 }
 return ERROR;
}




//                  M_PI_2                    M_PI_2
//              ___³___                     _____
//            /    ³    \                 /       \
//          /      ³      \             /           \
//  _______|_______³_______|______0____|_____________|____________________
//   PI    |       ³       |     2*PI                | PI          | 2*PI
//          \      ³      /                           \           /
//            \ ___³___ /                               \ _____ /
//                 ³                                        3*M_PI_4
//                  3 * M_PI_4
//                                                * *
//
//                                              *     *
//                    . .                         . .
//                  .     .                   * .     . *
//                .         .                 .         .
//   -----------.-------------.-------------.------------.-----------------
//             .                .         .               .
//     .     .                    .     .                  .
//       . .                        . .
//
//




void MenuPupUp( int Px, int Py )
{
 #define DISPERCION   1
 #define SENSIBILIDAD 0
 char Buffer[80];
 void far *Fondo;
 int i, end = OFF; int SeCa;
 char DispSenc = DISPERCION;
 extern int *n_Botones_Secuencia;

 struct Make_Boton                              //
 {                                              //  Estas variables son externas
	         int  Up,  Left, Down, Right;   //
	unsigned char Cdf, Cb1,  Cb2;           //  a todo el programa, y no
	unsigned char Ab,  Pb;                  //
	unsigned char Isc, Sc;                  //  deberian ser visibles ni a
 };                                             //
                                                //  esta funci¢n...
 extern struct Make_Boton far *Botones;		//

 // Corregimos el factor de posici¢n
 while( Px+135 > 639 ) Px --;
 while( Py+52 > inicioMmGy ) Py --;

 // 1§ asignamos memoria y guardamos el contenido de la pantalla a superponer
 if (  ( Fondo = (void far *)farmalloc( imagesize(0, 0, 135, 52) ) ) == NULL ) return;
 getimage( 0+Px, 0+Py, 135+Px, 52+Py, Fondo );

 // Re-posiciono los botones din micos a las nuevas posiciones
 // todos se encuentran en D5. ==>> Sec_n = 5 - 1 = 4.
 SeCa = n_Botones_Secuencia[0] + n_Botones_Secuencia[1] + n_Botones_Secuencia[2] + n_Botones_Secuencia[3];
 for ( i = 0; i < n_Botones_Secuencia[4]; i++ )
 {
    Botones[SeCa+i].Left  += Px; Botones[SeCa+i].Up    += Py;
    Botones[SeCa+i].Right += Px; Botones[SeCa+i].Down  += Py;
 }
 // Dibujamos el men£
 Imprime_Secuencia( 5 );
 // Dibujamos las Led's y las flechas.
    // LED    Dispersi¢n/Sensibilidad
    ponicono(  36+Px,   7+Py,  led_on, 1 );
    ponicono(  36+Px,  36+Py, led_off, 1 );
    // Flechas +- Dispersi¢n/Sensibilidad
    ponicono( 114+Px,   3+Py, flecha, 4 );
    ponicono( 114+Px,  32+Py, flecha, 2 );

 setfillstyle( SOLID_FILL, EGA_BLACK );
 settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
 setcolor( cfgFREC.Texto );
 // Comenzamos el Chequeo del nuevo men£
do{

 bar( 52+Px,   5+Py, 101+Px,  19+Py );
 bar( 52+Px,  34+Py, 101+Px,  47+Py );
 setcolor( cfgFREC.Texto );
 sprintf( Buffer, "%8d", Dispersion );
 outtextxy( 52+Px,  5+Py, Buffer );
 sprintf( Buffer, "%8d", Sensibilidad );
 outtextxy( 52+Px, 34+Py, Buffer );


 switch( Comprueba_Secuencia( 5, NULL ) )
 {
  case  0:			  // No se pulso ningun BOTON
       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
                                  // El raton todav¡a sigue pulsado
       break;
  case -2:
       while( kbhit() ) getch();
       break;
                                  // Tecla Normal
  case -1:			  // Hay una tecla especial en BUFFER
	       			  // La eliminamos
       while( kbhit() ) getch();
       break;
  case  1:
       end = ON;
       break;
  case  2:
  case  3:
       DispSenc = DISPERCION;
       ponicono(  36+Px,   7+Py,  led_on, 1 );
       ponicono(  36+Px,  36+Py, led_off, 1 );
       break;
  case  4:
  case  5:
       DispSenc = SENSIBILIDAD;
       ponicono(  36+Px,   7+Py, led_off, 1 );
       ponicono(  36+Px,  36+Py,  led_on, 1 );
       break;
  case  6:
       if ( DispSenc == SENSIBILIDAD )
              Sensibilidad++;
       else
              Dispersion++;
       break;
  case  7:
       if ( DispSenc == SENSIBILIDAD )
       {
              Sensibilidad--; if ( Sensibilidad < 0 ) Sensibilidad = 0;
       } else {
              Dispersion--; if ( Dispersion < 1 ) Dispersion = 1;
       }
       break;
 }

}while( end == OFF );

 // Restauramos los valores por defecto del menu PopUp
 for ( i = 0; i < n_Botones_Secuencia[4]; i++ )
 {
    Botones[SeCa+i].Left  -= Px; Botones[SeCa+i].Up    -= Py;
    Botones[SeCa+i].Right -= Px; Botones[SeCa+i].Down  -= Py;
 }
 // Restauramos el contenido anterior
 putimage( 0+Px, 0+Py, Fondo, COPY_PUT );
 // Liberamos la memoria requerida anteriormente
 farfree( Fondo );
}


