lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



Hmm.. there might not be a valid answer for this, in plain Lua.

The reason, again, is that such a feature is not ANSI C, so... you'll need an OS specific C binding.

Here's some code, off svn://slugak.dyndns.org/public/luax/trunk/ Modules/Sys/sys_module.c that may help you (or not?)

-asko


/*----- Keyboard functions -----*/

#ifdef PLATFORM_WIN32
  #define Loc_KbHit()  kbhit()
  #define Loc_Getch()  getch()
  //
#elif (defined PLATFORM_WINCE)
  #define Loc_KbHit()  kbhit()    // PocketConsole
  #define Loc_Getch()  FALSE  //getch()
  //
#else   // Linux & OS X
  //
  static struct termios initial_settings, new_settings;
  static int peek_character = -1;
static /*volatile*/ bool kb_state= 0; // -> 1 (in use) -> 2 (cleaned up)
  //
  static void Loc_InitKb( void )
  {
    // Different calling reasons (based on 'kb_state' value):
    //
    // 0: Keyboard services need to be initialised
    // 1: Clean-up (called by 'atexit' during program termination)
    // 2: Error (services already cleaned up!)
    //
    switch( kb_state )
        {
        case 0:
            // Do terminal initialisation:
            //
            tcgetattr(0,&initial_settings);
            new_settings = initial_settings;
            new_settings.c_lflag &= ~ICANON;
            new_settings.c_lflag &= ~ECHO;
            new_settings.c_lflag &= ~ISIG;
            new_settings.c_cc[VMIN] = 1;
            new_settings.c_cc[VTIME] = 0;
            tcsetattr(0, TCSANOW, &new_settings);

            // Ask us to be called again when program terminates.
            //
            atexit( Loc_InitKb );

            kb_state++;
            break;

        case 1:
            // Called by 'atexit' to do cleanup:
            //
            tcsetattr(0, TCSANOW, &initial_settings);

            kb_state++;
            break;

        default:
            assert(FALSE);
            break;
        }
  }
  //
  int Loc_KbHit( void )     // Returns the 'peek character'
  {
  unsigned char ch;
  int nread;

    if (kb_state != 1)  // Do we have access to the keyboard services?
        Loc_InitKb();

    if (peek_character != -1)
        return 1;

    new_settings.c_cc[VMIN]=0;
    tcsetattr(0, TCSANOW, &new_settings);

    nread = read(0,&ch,1);

    new_settings.c_cc[VMIN]=1;
    tcsetattr(0, TCSANOW, &new_settings);

    if(nread != 1)
        return 0;   // no keyboard press

    peek_character = ch;
    return ch;
  }
  //
  uint Loc_Getch( void )
  {
  unsigned char ch;

    if(peek_character != -1)
        {
        ch = peek_character;
        peek_character = -1;
        return ch;
        }
    read(0,&ch,1);
    return ch;
  }
  //
#endif  // Posix


//---
// [bool]= kbhit()
//
// Returns: 'true' if a keypress is pending (must be read by 'getch ()'!).
//
GLUA_FUNC( kbhit )
{
    glua_pushBoolean( Loc_KbHit() );
}
GLUA_END


//---
// code_int= getch()
//
GLUA_FUNC( getch )
{
    glua_pushUnsigned( Loc_Getch() );
}
GLUA_END



UkrNet kirjoitti 17.6.2006 kello 16.50:

I'm just a bigginer in Lua programming. I've got a question:
How can I read just one character from keybord?