Ncurses problema output

di il
8 risposte

Ncurses problema output

Salve a tutti..

Ho qualche problema con la gestione dell'output nel mio programma, qualcuno può darmi qualche consiglio a riguardo?


Il problema è che non riesco a visualizzare bene l'output all'interno delle finestre generate con newwin(), i caratteri lampeggiano e si visualizzano solo quando si muovono.


ringrazio chiunque possa darmi qualche buon consiglio.

8 Risposte

  • Re: Ncurses problema output

    Dovresti dare un'informazione più dettagliata per l'analisi per problema.
    1)Sistema Operativo
    2)Versione della lib
    3)Font e terminale utilizzato

    Riesci a vedere correttamente questo?
    
    #include <ncurses.h>
    int main()
    {
      static char s[]="Hello World";
      int h=3,w=sizeof(s)+1,y,x;
      WINDOW *win;
      
      initscr();
      x=(COLS/2)-(w/2); y=LINES/2;
      refresh();
      
      win=newwin(h,w,y,x);
      box(win,0,0);
      mvwprintw(win,1,1,s);
      wrefresh(win);
    
      getch();
      
      delwin(win);
      endwin();
      
      return 0;
    }
    
  • Re: Ncurses problema output

    Ciao e grazie per la risposta, si visualizzo bene il tuo codice, e sulla funzione box() non sapevo si potessero inserire interi, io mettevo sempre un carattere, e ho già imparato una cosa nuova.

    sistema operativo ho una debian,
    la versione delle lib dovrebbe essere la 5,
    font e terminale sono quelli standard.

    Ho scoperto inoltre che il mio problema era dato dal fatto che inserivo newwin() dentro il ciclo infinito che legge i dati degli altri processi, quindi, suppongo andasse a ridisegnare sopra i caratteri.

    se posso, vorrei farti un altra domanda:
    ho bisogno di creare un effetto simile ad una esplosione e, apparte la scelta dei caratteri, non riesco a far visualizzare, con una piccola pausa, i caratteri a monitor. I caratteri vengono disegnati ma troppo velocemente. Usando la funzione usleep() mette in pausa tutto il programma e i caratteri vengono comunque disegnati tutti all'istante.

    questa è la parte di codice dove disegno:
    
    void destroy(struct solid alien)
    {
    	if(alien.health<=-3)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " ._. ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1," \\O/ ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"  *** ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    		alien.health--;
    	}
    
    	if(alien.health<=-2)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " ._. ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1," *** ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    		alien.health--;
    	}
    
    	if(alien.health<=-1)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " *** ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    		alien.health--;
    	}
    
    	if(alien.health<=0)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  "     ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    		alien.health--;
    	}
    
    	if(alien.health<=-4) kill(alien.pid,1);
    }
    
    Ho usato gli if pensando che scrivesse ad ogni ciclo con la condizione corrispondente, ma non funziona così.
  • Re: Ncurses problema output

    Usando la funzione usleep() mette in pausa tutto il programma e i caratteri vengono comunque disegnati tutti all'istante.
    Si, perché ncurses utilizza dei buffer(*) che vengono travasati nel terminale dalle funzioni di refresh. In PHP esiste una funzione sperimentale int ncurses_delay_output ( int $milliseconds ) che rallenta il baudrate. Provo a cercare qualcosa in rete...

    (*) Non ho mai capito come ncurses gestisce la memoria. Mi risultano numerosi memory leaks derivanti dalla initscr()
  • Re: Ncurses problema output

    Quello che ho trovato:
    int delay_output(int ms);
    http://pubs.opengroup.org/onlinepubs/7908799/xcurses/delay_output.html
  • Re: Ncurses problema output

    Et voilà
    
    void delay_print (WINDOW *win,int y,int x,char s[],int ms)
    {
      int i,l;
      if (s && (l=strlen(s)))
      {
    	for (i=0;i<l;i++)
    	{
    	  mvwprintw(win,y,x++,"%c",s[i]);
    	  delay_output(ms);
    	  wrefresh(win);
    	}
      }
    }
    
  • Re: Ncurses problema output

    Ti ringrazio per la ricerca, ma non ha risolto il problema, perché, avendo più processi che comunicano tra loro, appena entro nella funzione e come arrivo al comando delat_output(), l'attesa è subita da tutto ill programma quindi tutti i processi si muovo con il ritardo del delay.

    ciò che serve a me è un comando che mette in pausa l'output, ma non i processi, deve agire in totale indipendenza dai processi.

    Non so se esiste una funzione che faccia questo. quindi ho sviluppato questo sistema:
    praticamente sfrutto il ciclo infinito che legge i dati dai processi, che dovrebbe essere equivalente al ritardo del movimento del processo "alieni". Al momento della distruzione dell'alieno richiamo la funzione destroy che ha come parametri la struttura alieno e una variabile explosion, explosion prende il ritorno della funzione destroy che si incrementa ad ogni chiamata e come arriva ad un certo valore (4) uccido il proccesso.
    non funziona però perché non ho trovato ancora un metodo per chiudere questo ciclo, risulta come se fosse un ciclo infinito.

    questa è la chiamata alla funzione:
    if(aliens.health<=0) explosion=destroy(aliens,explosion);
    questa è la funzione destroy:
    int destroy(struct solid alien,int explosion)
    {
    	if(explosion==0)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " ._. ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1," \\O/ ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1," *** ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    	}
    
    	if(explosion==1)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " ._. ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1," *** ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    	}
    
    	if(explosion==2)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  " *** ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    		}
    
    	if(explosion==3)
    	{
    		mvwaddstr(wBattlefield,alien.y-1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//-1
    		mvwaddstr(wBattlefield,alien.y,alien.x-1,  "     ");//wnoutrefresh(wBattlefield);	//0
    		mvwaddstr(wBattlefield,alien.y+1,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//1
    		mvwaddstr(wBattlefield,alien.y+2,alien.x-1,"     ");//wnoutrefresh(wBattlefield);	//2
    		mvwaddstr(wBattlefield,alien.y+3,alien.x-1,"     ");wnoutrefresh(wBattlefield);	//3
    	}
    
    	if(explosion==4)
    	{
    		kill(alien.pid,1);
    		return 0;  // anche con return -1 accade esattamente lo stesso...
    	}
    
    	return explosion+1;
    }
  • Re: Ncurses problema output

    ciò che serve a me è un comando che mette in pausa l'output, ma non i processi, deve agire in totale indipendenza dai processi.
    fonte: $man delay_output
    The delay_output routine inserts an ms millisecond pause in output. This routine should not be used extensively because padding characters are used rather than a CPU pause. If no padding character is specified, this uses napms to perform the delay.
    ...
    fonte: $man napms
    The napms routine is used to sleep for ms milliseconds
    ...
    Problema di padding, altro non so dirti. Posta un aiuto nei forum specifici
  • Re: Ncurses problema output

    Grazie mille...
Devi accedere o registrarti per scrivere nel forum
8 risposte