Question

Je travaille sur un jeu basé faire ASCII, et partout où je regarde les gens disent utiliser Console.Write () à partir de MSDN, qui est dandy et tout si vous utilisez Windows, mais je ne suis pas.

Et donc, je suis en train d'écrire une fonction ou un groupe de fonctions C qui peuvent alterner entre deux tampons d'écran, et les écrire à l'écran, semblable à ce que les pages de manuel serait comme, ainsi que pico, vim et emacs.

Je le travail de mémoire tampon, et a trouvé un vieux jeu ASCII appelé linux 0verkill qui utilise pour placer chaque personnage à l'écran C et putchar (), mais toutes mes tentatives pour recréer ce, résultat dans un flux continu du texte, et non un panneau de taille de la fenêtre de texte statique. Je ne veux vraiment pas utiliser des bibliothèques externes comme malédictions (car cela réduirait la portabilité) et voudraient garder ansi normes si possible.

Merci!

Était-ce utile?

La solution

  

Je ne veux pas vraiment utiliser des bibliothèques externes comme malédictions (car cela réduirait la portabilité)

Quoi? Les bibliothèques comme malédictions et ncurses sont conçus pour faire ce genre de chose plus portable, parce que ...

  

et souhaite maintenir les normes ansi si possible.

... il n'y a pas de norme ANSI (C au moins) pour ce que vous voulez. Chaque système d'exploitation met en œuvre ce type de comportement différent, donc si vous voulez un moyen portable pour le faire, vous avez besoin d'utiliser une bibliothèque. Honnêtement, je ne voudrais pas avoir à développer un système qui ne pas ont ncurses portés à elle. Imaginez tous les programmes que vous ne seriez pas en mesure d'utiliser sans elle.

Autres conseils

Je pense que ce que vous cherchez est le caractère de contrôle ANSI ESC[2J qui efface l'écran. Vous appelleriez que, après tout changement d'état de « rafraîchir » l'écran de la console.

Voir cette page pour en apprendre davantage sur le reste d'entre eux. L'utilisation de ces codes, vous pouvez définir des couleurs et la mise en forme (espacement, alignement, etc. indenter) sur la console.

Il y a une X3.64 norme ANSI, également ISO / CEI 6429 qui décrit le terminal DEC VT100. La norme décrit certains séquences d'échappement pour le positionnement des couleurs et un curseur conforme Terminal- émulateur reconnaîtra, qui sera essentiellement tous les terminaux X, mais pas nécessairement de Windows (peut-être vous avez besoin à l'utilisateur de charger ansi.sys ). Il est cette dernière incohérence laid qui illustre pourquoi vous devriez utiliser ncurses qui fait abstraction de tels détails.

Un en-tête par exemple et le fichier source illustrant une façon de malédictions abstraites de l'application. Collecte de la poussière; écrit il y a plus de 15 ans. caveat emptor.

cursemu.h

/***************************************************************************
 *                                                                          
 *  DO NOT CHANGE ANYTHING BETWEEN THIS LINE AND THE NEXT LINE THAT HAS THE 
 *  WORDS "KLAATU BARRATA NIKTO" ON IT                                      
 *                                                                          
 ***************************************************************************/
#ifndef X__CURSEMU__H                                                        
#define X__CURSEMU__H                                                        

#include <stdio.h>

#ifdef  linux
#define _POSIX_VERSION
#endif                

#ifndef _POSIX_VERSION
#include <sgtty.h>    
#define  USE_OLD_TTY  
#include <sys/ioctl.h>
#undef  USE_OLD_TTY   

#ifndef  CBREAK
#define CBREAK RAW
#endif            

#if !defined(sun) && !defined(sequent) && !defined(hpux) && \
    !defined(_AIX) && !defined(aix)                          
#include <strings.h>                                         
#define strchr index                                         
#else                                                        
#include <string.h>                                          
#endif                                                       
#else                                                        
#include <string.h>                                          
#include <termios.h>                                         
#endif                                                       

#include <errno.h>
#include <sys/types.h>
#include <pwd.h>      
#include <sys/time.h> 
#include <sys/file.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>     
#include <signal.h>    

/* Keep looking ... */

int _tty_ch;

#ifdef  _POSIX_VERSION
struct termios _tty;  
tcflag_t _res_iflg,   
    _res_lflg;        

#define cbreak()(_tty.c_lflag&=~ICANON, \
  tcsetattr( _tty_ch, TCSANOW, &_tty ))  

#define noecho()(_tty.c_lflag &= ~(ECHO|ICRNL), \
  tcsetattr( _tty_ch, TCSADRAIN, &_tty ))        

#define savetty()((void) tcgetattr(_tty_ch, &_tty), \
  _res_iflg = _tty.c_iflag, _res_lflg = _tty.c_lflag )

#define resetty()(_tty.c_iflag = _res_iflg, _tty.c_lflag = _res_lflg,\
  (void) tcsetattr(_tty_ch, TCSADRAIN, &_tty))                        

#define erasechar()(_tty.c_cc[VERASE])
#else                                 
struct sgttyb _tty;                   
int _res_flg;                         

#define cbreak()(_tty.sg_flags|=CBREAK, ioctl(_tty_ch, TIOCSETP, &_tty))

#define noecho()(_tty.sg_flags &= ~(ECHO|CRMOD), \
  ioctl( _tty_ch, TIOCSETP, &_tty ))              

#define savetty()((void) ioctl(_tty_ch, TIOCGETP, &_tty), \
  _res_flg = _tty.sg_flags )                               

#define resetty()(_tty.sg_flags = _res_flg, \
  (void) ioctl(_tty_ch, TIOCSETP, &_tty))    
#define erasechar()(_tty.sg_erase)           
#endif                                       

/* KLAATU BARRATA NIKTO */

#define  TERMCAP_LENGTH 1024

struct CtrlSeq
{             
  char termcap[ TERMCAP_LENGTH ];

  int numRows, numCols;

  /*  These pointers are indexes into the termcap buffer, and represent the
   *  control sequences neccessary to send to the terminal window to perform
   *  their appropriately named feature.
   */
  char *highlight,
       *endMode,            /* End highlight mode, and other modes. */
       *clearScr,
       *clearEol,
       *scrollRegion,
       *moveCursor,
       *deleteRow,
       *insertRow,
       *saveCursor,         /* Save the current cursor position */
       *restoreCursor;      /* Restore the saved cursor position */

  int dumbTerm,             /* 1 if the terminal is a dumb terminal */
      flush;                /* 1 if the emulation should flush stdout */
};

struct CtrlSeq ctrlSeq;

#define DEFAULT_COLS    80
#define DEFAULT_ROWS    24

void ce_flush( int toSet );
void ce_puts( char *str );
void ce_gotoRowCol( int row, int col );

void ce_writeStrRowCol( char *theText, int row, int col );
void ce_writeStr( char *theText );
void ce_writeCharRowCol( char theChar, int row, int col );
void ce_writeChar( char theChar );

void ce_clearScreen( void );
void ce_clearEol( void );

void ce_highlight( int on );
void ce_scrollRegion( int row1, int row2 );
void ce_deleteRow( int row );
void ce_insertRow( int row );
void ce_saveCursor( void );
void ce_restoreCursor( void );

int ce_getRows( void );
int ce_getCols( void );

#endif

cursemu.c

#include "cursemu.h"

int putchar_x( int c )
{                     
  return( putchar( c ) );
}                        

/*  Returns 0 on success, -1 on error
 */                                  
int ce_startCurses( void )           
{                                    
  char *ptr,                         
       tempBuff[ 1024 ];             
  int  result = 0;                   

  if( (ptr = (char *)getenv( "TERM" )) != NULL )
    result = tgetent( tempBuff, ptr );          
  else                                          
    result = tgetent( tempBuff, "vt100" );      

  if( result < 1 )
  {               
    perror( "FATAL Error: No termcap entry found (even tried vt100)!\n" );
    return( -1 );                                                         
  }                                                                       

  ptr = ctrlSeq.termcap;

  if( (ctrlSeq.numCols = tgetnum( "co" )) == -1 )
    ctrlSeq.numCols = DEFAULT_COLS;              
  if( (ctrlSeq.numRows = tgetnum( "li" )) == -1 )
    ctrlSeq.numRows = DEFAULT_ROWS;              

  if( (ctrlSeq.moveCursor = (char *)tgetstr( "cm", &ptr )) == NULL )
    ctrlSeq.moveCursor = (char *)tgetstr( "cl", &ptr );             
  if( (ctrlSeq.highlight = (char *)tgetstr( "mr", &ptr )) == NULL ) 
    ctrlSeq.highlight = (char *)tgetstr( "md", &ptr );              

  ctrlSeq.endMode       = (char *)tgetstr( "me", &ptr );
  ctrlSeq.clearEol      = (char *)tgetstr( "ce", &ptr );
  ctrlSeq.clearScr      = (char *)tgetstr( "cl", &ptr );
  ctrlSeq.scrollRegion  = (char *)tgetstr( "cs", &ptr );
  ctrlSeq.deleteRow     = (char *)tgetstr( "dl", &ptr );
  ctrlSeq.insertRow     = (char *)tgetstr( "al", &ptr );
  ctrlSeq.saveCursor    = (char *)tgetstr( "sc", &ptr );
  ctrlSeq.restoreCursor = (char *)tgetstr( "rc", &ptr );

  ctrlSeq.dumbTerm = (ctrlSeq.moveCursor == NULL) ||
                     (ctrlSeq.scrollRegion == NULL) ||
                     (ctrlSeq.saveCursor == NULL) ||  
                     (ctrlSeq.restoreCursor == NULL) ||
                     (ctrlSeq.clearEol == NULL);       

  ctrlSeq.flush = 1;

  if( !ctrlSeq.dumbTerm )
  {                      
    if( (_tty_ch = open( "/dev/tty", O_RDWR, 0 ) ) == -1 )
      _tty_ch = 0;                                        

    savetty();
    cbreak(); 
    noecho(); 
    return( 0 );
  }             

  return( -1 );
}              

int ce_endCurses( void )
{                       
  ce_scrollRegion( -1, -1 );
  ce_gotoRowCol( ce_getRows() - 1, 0 );
  resetty();                           
}                                      

void ce_flush( int toSet )
{                         
  ctrlSeq.flush = toSet;  

  if( toSet == 1 )
    fflush( stdout );
}                    

void ce_puts( char *str )
{                        
  tputs( str, 0, putchar_x );

  if( ctrlSeq.flush )
    fflush( stdout );
}                    

void ce_gotoRowCol( int row, int col )
{                                     
  if( row > ctrlSeq.numRows )         
    row = ctrlSeq.numRows;            
  if( col > ctrlSeq.numCols )         
    col = ctrlSeq.numCols;            

  ce_puts( (char *)tgoto( ctrlSeq.moveCursor, col, row ) );
}                                                          

void ce_writeStrRowCol( char *theText, int row, int col )
{                                                        
  ce_flush( 0 );                                         
  ce_gotoRowCol( row, col );                             
  ce_writeStr( theText );                                
  ce_flush( 1 );                                         
}                                                        

void ce_writeStr( char *theText )
{                                
  ce_flush( 0 );                 
  printf( "%s", theText );       
  ce_flush( 1 );                 
}                                

void ce_writeCharRowCol( char theChar, int row, int col )
{                                                        
  ce_flush( 0 );                                         
  ce_gotoRowCol( row, col );                             
  ce_writeChar( theChar );                               
  ce_flush( 1 );                                         
}                                                        

void ce_writeChar( char theChar )
{                                
  ce_flush( 0 );                 
  printf( "%c", theChar );       
  ce_flush( 1 );                 
}                                

void ce_clearScreen( void )
{                          
  ce_puts( ctrlSeq.clearScr );
}

void ce_clearEol( void )
{
  ce_puts( ctrlSeq.clearEol );
}

void ce_highlight( int on )
{
  if( on == 0 )
    ce_puts( ctrlSeq.endMode );
  else
    ce_puts( ctrlSeq.highlight );
}

void ce_scrollRegion( int row1, int row2 )
{
  ce_puts( (char *)tgoto( ctrlSeq.scrollRegion, row1, row2 ) );
}

void ce_deleteRow( int row )
{
  ce_gotoRowCol( row, 0 );
  ce_puts( ctrlSeq.deleteRow );
}

void ce_insertRow( int row )
{
  ce_gotoRowCol( row, 0 );
  ce_puts( ctrlSeq.insertRow );
}

void ce_saveCursor( void )
{
  ce_puts( ctrlSeq.saveCursor );
}

void ce_restoreCursor( void )
{
  ce_puts( ctrlSeq.restoreCursor );
}

int ce_getRows( void )
{
  return( ctrlSeq.numRows );
}

int ce_getCols( void )
{
  return( ctrlSeq.numCols );
}

Compiling

Nécessite:

gcc -o cursemu.o -lcurses -ltermcap
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top