/***********************************************/
/*                                             */
/*  cons.c - v. 1.0 - 8.88 - Antonio Ferrillo  */
/*                                             */
/*  funzioni di gestione del console device    */
/*                                             */ 
/*    versione Aztec 3.4  -   Lattice 3.10     */
/*                                             */
/***********************************************/ 

  #include <functions.h>   /* rimuovere questa 
linea se si usano i compilatori Lattice V. 3.xx */

  #include <exec/types.h>
  #include <intuition/intuition.h> 

/* sequenze di controllo                       */

  UBYTE escdata[] =
 {
  0x9b, 'J', '\0',/* reset fino a fine display */
  0x9b, 'K', '\0', /* reset fino a fine linea */
  0x9b, 'S', '\0', /* scroll up */
  0x9b, 'T', '\0', /* scroll down */
  0x9b, ' ', 'p', '\0',       /* cursor on */
  0x9b, '0', ' ', 'p', '\0',   /* cursor off */
  0x0c, '\0'                /* clear schermo  */
 };

  UBYTE rigdata[]=         /* riga e colonna */
         { 0x9B,'0','0',';','0','0',0x48,'\0' };

  UBYTE stildata[]=        /* stile e colore */ 
 { 0x9B,'0',';','3','0',';','4','0',0x6D,'\0' };            


  #define ERASEEODSTRING        &escdata[0] 
  #define ERASEEOLSTRING 	&escdata[3] 
  #define SCROLLUPSTRING 	&escdata[6] 
  #define SCROLLDOWNSTRING     	&escdata[9]
  #define CURSONSTRING 		&escdata[12] 
  #define CURSOFFSTRING		&escdata[16]
  #define CLEARSTRING  		&escdata[21] 
  #define RIGACOL               &rigdata[0]
  #define STILCOL               &stildata[0]

/* definizione macro richiamate in seguito   */  

  #define CLEARSCREEN(r) ConPutStr(r,CLEARSTRING)
#define SCROLLDOWN(r)ConPutStr(r,SCROLLDOWNSTRING)
  #define ERASEEOD(r) ConPutStr(r,ERASEEODSTRING)
  #define ERASEEOL(r) ConPutStr(r,ERASEEOLSTRING)
  #define SCROLLUP(r) ConPutStr(r,SCROLLUPSTRING)
  #define CURSORON(r) ConPutStr(r,CURSONSTRING)
  #define CURSOROFF(r) ConPutStr(r,CURSOFFSTRING)
  #define RIGACOLONNA(r)     ConPutStr(r,RIGACOL)
  #define STILCOLOR(r)       ConPutStr(r,STILCOL) 

  struct IOStdReq *consoleWriteMsg;
             /*  I/O request block scrittura   */
  struct MsgPort *consoleWritePort;
        /*porto di ricezione messaggi scrittura*/	
  struct IOStdReq *consoleReadMsg;
             /*  I/O request block lettura     */
  struct MsgPort *consoleReadPort;
        /* porto di ricezione messaggi lettura */	

/*   tabella caratteri consentiti              */

  UBYTE key[100] =
 {
   'a','b','c','d','e','f','g','h','i','j','k',
   'l','m','n','o','p','q','r','s','t','u','v',
   'w','x','y','z','A','B','C','D','E','F','G',
   'H','I','J','K','L','M','N','O','P','Q','R',
   'S','T','U','V','W','X','Y','Z',' ','1','2',
   '3','4','5','6','7','8','9','0',',','.',';',
   ':','-','+','*','/','=','_','<','>','(',')',
   '[',']','{','}','#','£','$','%','&','!','?',
   '|','\\','"','@','§','\'','ì','è','é','ò',
   'à','ù'
 };

  void Con_Poscur();
  void ConSticol();
  void ConPutStr();

/*-----------------------------------------------
|  int
|  Con_Open(wn)
| 
|     FUNZIONE  : apertura di console device.
| 
|     ARGOMENTI : int wn; - (valore = da 1 a 4) 
|                         numero della  finestra 
|                         cui associare il device.
|
|     RITORNO   : TRUE se l'apertura e' andata a 
|                 buon fine, FALSE se e' 
|                 sopravvenuto un errore.
| 
|     NOTE      : ricordarsi di chiudere il 
|                 device a fine lavoro mediante 
|                 la Con_Close.
|_____________________________________________*/ 

  int
  Con_Open(wn)
  int wn;
  {
   int error;
   struct  Window   *Window_Addr(), *win_ptr;

   if(wn < 1 || wn > 4) return(FALSE);

   consoleWritePort = (struct MsgPort *)
                   CreatePort("my.con.write",0L);
   if(consoleWritePort == 0)  return (FALSE);

   consoleWriteMsg =  (struct IOStdReq *)
                   CreateStdIO(consoleWritePort);
   if(consoleWriteMsg == 0)  return(FALSE);

   consoleReadPort = (struct MsgPort *)
                    CreatePort("my.con.read",0L);
   if(consoleReadPort == 0)  return(FALSE);

   consoleReadMsg = (struct IOStdReq *)
                    CreateStdIO(consoleReadPort);
   if(consoleReadMsg == 0) return(FALSE);

   win_ptr = Window_Addr(wn);

   consoleWriteMsg->io_Data = (APTR) win_ptr;
   consoleWriteMsg->io_Length = sizeof(*win_ptr);
 
   error = OpenDevice
        ("console.device",0L,consoleWriteMsg,0L);
   if(error != 0)  return(FALSE);

/* nel blocco di lettura vengono copiati alcuni 
   campi settati dalla OpenDevice nel blocco di 
   scrittura, in modo tale che sia l'input che 
   l'output vengano diretti sullo stesso  
   device.                          */   
 
   consoleReadMsg->io_Device = 
                      consoleWriteMsg->io_Device;
   consoleReadMsg->io_Unit  = 
                        consoleWriteMsg->io_Unit;

   return(TRUE);
  }


/*----------------------------------------------
|  void
|  Con_Close()
| 
|     FUNZIONE  : effettua la Close del device.
|______________________________________________*/

  void
  Con_Close()
  {
   CloseDevice(consoleWriteMsg);
   DeleteStdIO(consoleReadMsg);
   DeletePort(consoleReadPort);
   DeleteStdIO(consoleWriteMsg);
   DeletePort(consoleWritePort);
  }


/*----------------------------------------------
|  void
|  Con_Clescr(colbg)
| 
|     FUNZIONE  : abblenca la finestra e la 
|                 setta col colore colbg.
| 
|     ARGOMENTI : int colbg;   - 
|           (valore = da 0 a 7) codice colore di
|                               background. 
|______________________________________________*/

  void
  Con_Clescr(colbg)
  int colbg;
  {
   ConSticol(0,colbg,colbg);
   CLEARSCREEN(consoleWriteMsg);
  }
	

/*----------------------------------------------
|  void
|  Con_Clecur(colbg)
| 
|     FUNZIONE  : abblenca la finestra dalla 
|                 posizione del cursore
|                 e la setta col colore colbg.
| 
|     ARGOMENTI : int colbg;   - 
|          (valore = da 0 a 7)  codice colore di
|                               background. 
|_____________________________________________*/

  void
  Con_Clecur(colbg)
  int colbg;
  {
   ConSticol(0,colbg,colbg);
   ERASEEOD(consoleWriteMsg);
  }


/*----------------------------------------------
|  void
|  Con_Clelin(colbg)
| 
|     FUNZIONE  : abblenca la linea dalla 
|                 posizione del cursore
|                 e la setta col colore colbg.
| 
|     ARGOMENTI : int colbg;   - 
|         (valore = da 0 a 7)  codice colore di
|                              background. 
|_____________________________________________*/

  void
  Con_Clelin(colbg)
  int colbg;
  {
   ConSticol(0,colbg,colbg);
   ERASEEOL(consoleWriteMsg); 
  }


/*---------------------------------------------
|  void
|  Con_Scrollup()
| 
|     FUNZIONE  : effettua lo scroll in alto 
|                 di una linea.
|_____________________________________________*/

  void
  Con_Scrollup()
  {
   SCROLLUP(consoleWriteMsg);
  }


/*----------------------------------------------
|  void
|  Con_Scrolldown()
| 
|     FUNZIONE  : effettua lo scroll in basso
|                 di una linea.
|_____________________________________________*/

  void
  Con_Scrolldown()
  {
   SCROLLDOWN(consoleWriteMsg);
  }


/*----------------------------------------------
|  void
|  Con_Curson()
| 
|     FUNZIONE  : fa apparire il cursore.
|_____________________________________________*/

  void
  Con_Curson()
  {
   CURSORON(consoleWriteMsg);
  }


/*----------------------------------------------
|  void
|  Con_Cursoff()
| 
|     FUNZIONE  : fa sparire il cursore.
|______________________________________________*/

  void
  Con_Cursoff()
  {
   CURSOROFF(consoleWriteMsg);
  }


/*----------------------------------------------
|  void
|  Con_Write(riga,col,stile,colfg,colbg,testo)
| 
|     FUNZIONE  : scrive nella finestra una 
|                 stringa NULL-terminata.
| 
|     ARGOMENTI : int riga;  - 
|       (valore > 0  dipendente dalla risoluzione 
|        dello schermo, dalla Font prescelta,
|        dalle dimensioni della finestra)
|        numero di riga sulla quale va 
|        visualizzato il testo.
|                 
|                 int col;   - 
|       (valore > 0  dipendente dalla risoluzione
|        dello schermo, dalla Font prescelta,
|        dalle dimensioni della finestra) 
|        numero della colonna a partire dalla 
|        quale va visualizzato il testo.
|
|                 int stile; - stile di scrittura,
|       valore :  0 = plain,  1 = boldface,
|       3 = italic, 4 = underscore, 7 = inverse
|                                                    
|                 int colfg; - 
|      (valore da 0 a 7) colore di foreground.
|
|                 int colbg; - 
|      (valore da 0 a 7)colore di background
|           
|                 char *testo- 
|      stringa da visualizzare terminata con '\0'.
|_______________________________________________*/

  void
  Con_Write(riga,col,stile,colfg,colbg,testo)
  int riga;
  int col;
  int stile;
  int colfg;
  int colbg;
  char  *testo;
  {
   Con_Poscur(riga,col);
   ConSticol(stile,colfg,colbg);
   ConPutStr(consoleWriteMsg,testo);
  }


/*-----------------------------------------------
|  int
|  Con_Read(riga,col,stile,colfg,colbg,area,len)
| 
|     FUNZIONE  : accetta da tastiera e visualizza
|                 nella finestra una stringa di 
|                 lunghezza massima = len 
|                 terminata col tasto  'return',
|                 ritorna in area la stringa 
|                 digitata.  
| 
|     ARGOMENTI : int riga;  - 
|        (valore > 0 dipendente dalla risoluzione
|        dello schermo, dalla Font prescelta,
|        dalle dimensioni della finestra)
|        numero di riga sulla quale va 
|        visualizzato il testo digitato.
|                 
|                 int col;   - 
|        (valore > 0  dipendente dalla risoluzione 
|        dello schermo, dalla Font prescelta,
|        dalle dimensioni della finestra)  
|        numero della colonna a partire dalla 
|        quale va visualizzato il testo digitato.
|
|                 int stile; - 
|        stile di scrittura, valore :
|        0 = plain,  1 = boldface,
|        3 = italic, 4 = underscore, 7 = inverse
|                                                    
|                 int colfg; - 
|        (valore da 0 a 7) colore di foreground.
|
|                 int colbg; - 
|        (valore da 0 a 7) colore di background.
|
|                 char *area - 
|        buffer di destinazione della stringa 
|        digitata di dimensioni = a len + 1, 
|        viene terminato con il carattere '\0'. 
|
|                 int len    - 
|        numero massimo di caratteri da accettare. 
| 
|     RITORNO   : se l'operazione e' andata a 
|                 buon fine : il numero dei 
|                 caratteri digitati ed, in area,
|                 la stringa digitata. 
|                 FALSE se e' sopravvenuto un 
|                 errore.
|______________________________________________*/

  int
  Con_Read(riga,col,stile,colfg,colbg,area,len)
  int riga;
  int col;
  int stile;
  int colfg;
  int colbg;
  UBYTE *area;
  int len;
  {
   UBYTE ConGetChar();
   UBYTE car; 
   int nlet;
   int nkey;
   char blanks[80];

   switch (stile)
    {
     case 0 : 
     case 1 :
     case 3 :
     case 4 :
     case 7 : break;
     default : return (FALSE);
    }
 
   if (colfg < 0 || colfg > 7) return (FALSE);   
   if (colbg < 0 || colbg > 7) return (FALSE);
   Con_Poscur(riga,col);
   ConSticol(stile,colfg,colbg);
  
   for(nlet = 0; nlet < len; 
                      blanks[nlet] = ' ',nlet++);
   blanks[nlet] = '\0';
   ConPutStr(consoleWriteMsg,blanks);
   Con_Poscur(riga,col);  

   for(nlet = 0;; nlet++)
   {
     car= 
      ConGetChar(consoleReadPort,consoleReadMsg);
     if (car == '\r') break;  
    /* se e' stato premuto il tasto 'return'   */
    
     if (car == '\b') 
   /* se e' stato premuto il tasto 'backspace' */                                              
     {
       if (nlet <= 0)
        { DisplayBeep(NULL); nlet--;  continue; } 
       nlet -= 2 ;
       ConPutStr(consoleWriteMsg,&car);
       continue;
     }
 
/*se e' stato raggiunto il massimo dei caratteri*/    
     if (nlet >= len)
         { DisplayBeep(NULL); nlet-- ;continue; }
 
     for(nkey = 0; nkey < 100; nkey++)
                /* controllo caratteri ammessi */ 
          if(car == key[nkey]) goto bypass; 
    
     DisplayBeep(NULL);
  /* lampeggia lo schermo per segnalare errore */
     nlet-- ; 
     continue; 

     bypass: 
     ConPutStr(consoleWriteMsg,&car);
             /* scrittura carattere digitato  */
     area[nlet] = car; 
              /* carattere digitato in buffer */
   } 
   area[nlet] = '\0'; 
      /* carattere terminatore a fine stringa */
   return(nlet);
  }


/*----------------------------------------------
|  void
|  Con_Poscur(riga,colonna)
| 
|     FUNZIONE  : posiziona il cursore a riga
|                 e colonna.
| 
|     ARGOMENTI : int riga;  - 
|      (valore > 0  dipendente dalla risoluzione 
|      dello schermo, dalla Font prescelta,
|      dalle dimensioni della finestra)
|      numero di riga sulla quale va posizionato 
|      il cursore.
|                 
|                 int colonna; - 
|      (valore > 0 dipendente dalla risoluzione
|      dello schermo, dalla Font prescelta,
|      dalle dimensioni della finestra)
|      numero della colonna sulla quale va 
|      posizionato il cursore.
|_____________________________________________*/

  void
  Con_Poscur(riga,colonna)
  int riga;
  int colonna;
  {
   rigdata[1] =  riga / 10 | 48;
   rigdata[2] =  riga % 10 | 48;
   rigdata[4] =  colonna / 10 | 48;
   rigdata[5] =  colonna % 10 | 48;
   RIGACOLONNA(consoleWriteMsg);
  }


/*.............................................
|  void
|  ConSticol(stile,colfg,colbg)
|     FUNZIONE  : determina stile e colore 
|                 prima di una visualizzazione.
|     ARGOMENTI : int stile; - 
|       stile di scrittura, valore :
|       0 = plain,  1 = boldface,
|       3 = italic, 4 = underscore,
|       7 = inverse
|                 int colfg; - 
|      (valore da 0 a 7) colore di foreground.
|                 int colbg; - 
|      (valore da 0 a 7) colore di background.
|     NOTE : destinata ad utilizzo interno al 
|            sorgente. 
|............................................*/

  void
  ConSticol(stile,colfg,colbg)
  int stile;
  int colfg;
  int colbg;
  {	
   stildata[1] = stile | 48;
   stildata[4] = colfg | 48;
   stildata[7] = colbg | 48;
   STILCOLOR(consoleWriteMsg);
  }


/*.............................................
|  void
|  ConPutStr(request,string)
|     FUNZIONE  : scrive una stringa 
|                 NULL-terminata.
|     ARGOMENTI : struct IOStdReq *request; - 
|                 I/O request block.
|                 char *string; - 
|                 stringa NULL-terminata.
|     NOTE : destinata ad utilizzo interno al 
|            sorgente.
|.............................................*/

  void
  ConPutStr(request,string)
  struct IOStdReq *request;
  char *string;
  {
   request->io_Command = CMD_WRITE;
   request->io_Data = (APTR)string;
   request->io_Length = -1; 
   DoIO(request);
  }
	

/*..............................................
|  UBYTE
|  ConGetChar(consolePort,request)
|     FUNZIONE  : accetta da tastiera un carattere
|     ARGOMENTI : struct MsgPort *consolePort; - 
|                 struttura porto di arrivo dei 
|                 messaggi del device.
|                 struct IOStdReq *request; - 
|                 I/O request block.
|     RITORNO   : carattere digitato.
|     NOTE : destinata ad utilizzo interno al 
|            sorgente. 
|..............................................*/

  UBYTE
  ConGetChar(consolePort,request)
  struct IOStdReq *request; 
  struct MsgPort *consolePort;   
  {
   UBYTE temp[5];
   request->io_Command = CMD_READ;
   request->io_Data = (APTR)&temp;
   request->io_Length = 5;  
   SendIO(request);
   while((GetMsg(consolePort) == NULL)) 
                          WaitPort(consolePort);
   return(temp[0]);
  }

