RoBoard魔人的機器人日誌

2012/3/19

[RoBoRC第六回] 介紹程式碼userio

這一次要介紹的是userio

userio主要是使用於接收key的值及一些常用的函式

什麼?

覺得接收key很簡單?

當然...在一平台下會認為接收key很簡單

但這userio可是適用於各個平台!

不管是LINUX,WINCE...等等

幾乎都可以執行

接下來就來研究看看吧!



userio.h
#ifndef __USERIO_H
#define __USERIO_H

#include "defines.h"


#ifdef __cplusplus
extern "C" {
#endif

//MESSAGE
bool msg_SetLogFile(char* logfile);
void msg_CloseLogFile(void);

void showmsg(const char* fmt, ...);


//KEYBOARD:
void keyboard_init(int type);
#define KEYBOARD_STD    (1)
#define KEYBOARD_ADV    (2)

void keyboard_close(void);

unsigned keyboard_getkey(void);
unsigned keyboard_waitkey(void);
#define KBENTER         (0x000d)
#define KBTAB           (0x0009)
#define KBESC           (0x001b)
#define KBBACKSPACE     (0x0008)
#define KBSPACE         (0x0020)

#define KBLEFT          (0x0025)
#define KBRIGHT         (0x0027)
#define KBUP            (0x0026)
#define KBDOWN          (0x0028)

#define KBHOME          (0x0024)
#define KBEND           (0x0023)
#define KBPGUP          (0x0021)
#define KBPGDN          (0x0022)

#define KBINS           (0x002d)
#define KBDEL           (0x002e)

#define KBF1            (0x0070)
#define KBF2            (0x0071)
#define KBF3            (0x0072)
#define KBF4            (0x0073)
#define KBF5            (0x0074)
#define KBF6            (0x0075)
#define KBF7            (0x0076)
#define KBF8            (0x0077)
#define KBF9            (0x0078)
#define KBF10           (0x0079)
#define KBF11           (0x007a)
#define KBF12           (0x007b)

#define KBSHIFT         (0x0010)
#define KBLSHIFT        (0x00a0)
#define KBRSHIFT        (0x00a1)
#define KBCTRL          (0x0011)
#define KBLCTRL         (0x00a2)
#define KBRCTRL         (0x00a3)
#define KBALT           (0x0012)
#define KBLALT          (0x00a4)
#define KBRALT          (0x00a5)

#ifdef __cplusplus
}
#endif
#endif





userio.cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#ifdef USE_RBDLL
 #define  USE_COMMON
 #include <roboard_dll.h>
#else
 #define  USE_COMMON
 #include <roboard.h>
#endif
#include "userio.h"


#if defined(RB_LINUX)
    #include <unistd.h>
    //#include <termios.h>
    #include <ncurses.h>
#elif defined(RB_MSVC_WIN32)
    #include <windows.h>
    #include <conio.h>
#elif defined(RB_MSVC_WINCE)
    #include <windows.h>
#elif defined(RB_BC_DOS) || defined(RB_DJGPP)
    #include <conio.h>
    #define _getch getch
    #define _kbhit kbhit
#endif

#define KEYBOARD_NOUSE  (0)
static int keyboard_inUse = KEYBOARD_NOUSE;



/*****************  Common Message Functions  ******************/
static FILE* MSG_outputDevice = stdout;

bool msg_SetLogFile(char* logfile) {
    msg_CloseLogFile();

 if (logfile == NULL)                  //logfile為NULL  就把MSG_outputDevice也改為NULL  回傳true
 {
  MSG_outputDevice = NULL;
  return true;
 }

 if ((MSG_outputDevice = fopen(logfile, "w")) != NULL) return true;       //如果開啟logfile成功  回傳true

 MSG_outputDevice = stdout;
    return false;
}

void msg_CloseLogFile(void) {                 //確定MSG_outputDevice為stdout
    if ((MSG_outputDevice != stdout) && (MSG_outputDevice != NULL))
        fclose(MSG_outputDevice);

 MSG_outputDevice = stdout;
}


#ifdef _MANAGED
 #pragma managed(push, off)
#endif
void showmsg(const char* fmt, ...) {               //show message在螢幕上
    char buf[256];
    va_list args;

 va_start(args, fmt);
 vsprintf(buf, fmt, args);
 va_end(args);

    #ifdef RB_LINUX
        if ((keyboard_inUse == KEYBOARD_STD) && (MSG_outputDevice == stdout))
        {
            printw("%s", buf);
            refresh();
            return;
        }
    #endif

 fprintf(MSG_outputDevice, "%s", buf);
    fflush(MSG_outputDevice);
}
#ifdef _MANAGED
 #pragma managed(pop)
#endif
/*-------------- end of Common Message Functions --------------*/



/*****************  Common Keyboard Functions  *****************/
static unsigned keymap[512] = 
    {
        0, 0, 0, 0, 0, 0, 0, 0, KBBACKSPACE, KBTAB, 0, 0, 0, KBENTER, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBESC, 0, 0, 0, 0,
        KBSPACE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',   0,   0,   0,   0,   0,   0,
          0, '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',   0,  0 ,   0,   0,   0,
          0, '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',   0,  0 ,   0,   0,   0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBF1, KBF2, KBF3, KBF4, KBF5,
        KBF6, KBF7, KBF8, KBF9, KBF10, 0, 0, KBHOME, KBUP, KBPGUP, 0, KBLEFT, 0, KBRIGHT, 0, KBEND,
        KBDOWN, KBPGDN, KBINS, KBDEL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, KBF11, KBF12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };


void keyboard_init(int type) {                 //init keyboard
    if (keyboard_inUse != KEYBOARD_NOUSE) return; else keyboard_inUse = type;
    switch (type)
    {
        case KEYBOARD_STD:
            #if defined(RB_LINUX)
                initscr();
                cbreak();
                nonl();
                noecho();
                scrollok(stdscr, TRUE);
                nodelay(stdscr, TRUE);
                intrflush(stdscr,FALSE);
                keypad(stdscr,TRUE);
                refresh();
            #elif defined(RB_MSVC_WINCE)
    keyboard_getkey();
            #endif
   return;
        case KEYBOARD_ADV:
   return;
    }

 keyboard_inUse = KEYBOARD_NOUSE;
}

void keyboard_close(void) {                  //close keyboard
    if (keyboard_inUse == KEYBOARD_NOUSE) return;

    switch (keyboard_inUse)
    {
        case KEYBOARD_STD:
            #if defined(RB_LINUX)
                endwin();
            #elif defined(RB_MSVC_WINCE)
                fflush(stdin);
            #endif
            break;
        case KEYBOARD_ADV:
            break;
    }

    keyboard_inUse = KEYBOARD_NOUSE;
}


static unsigned keyboard_getkey_std(void) {              //讀取keyboard的值   適用各種平台
    #if defined(RB_LINUX)
        int c = getch();
        
        if ((c == 27) || ((c >= 0x20) && (c <= 0x7f))) return keymap[c];
    
        switch (c)
        {
            case KEY_BACKSPACE:
            case 127: //some linux maps BACKSPACE to delete (127)
                return KBBACKSPACE;
            case KEY_ENTER:
            case '\r':
                return KBENTER;
            case '\t':
                return KBTAB;
    
            case KEY_UP:    return KBUP;
            case KEY_DOWN:  return KBDOWN;
            case KEY_LEFT:  return KBLEFT;
            case KEY_RIGHT: return KBRIGHT;
    
            case KEY_HOME:  return KBHOME;
            case KEY_END:   return KBEND;
            case KEY_NPAGE: return KBPGDN;
            case KEY_PPAGE: return KBPGUP;
    
            case KEY_IC:    return KBINS;
            case KEY_DC:    return KBDEL;

            case KEY_F(1):  return KBF1;
            case KEY_F(2):  return KBF2;
            case KEY_F(3):  return KBF3;
            case KEY_F(4):  return KBF4;
            case KEY_F(5):  return KBF5;
            case KEY_F(6):  return KBF6;
            case KEY_F(7):  return KBF7;
            case KEY_F(8):  return KBF8;
            case KEY_F(9):  return KBF9;
            case KEY_F(10): return KBF10;
            case KEY_F(11): return KBF11;
            case KEY_F(12): return KBF12;

            case ERR:       return 0;
        }
        
        return 0;
    #elif defined(RB_MSVC_WINCE)
        static bool          vkeystat[256] = {false};
        static unsigned long vkeytime[256] = {0L};

        int c;
        unsigned firstkey = 0;
        
        for (c=0; c<512; c++)
        {
            if ((keymap[c] == 0) || ((c >= 'a') && (c <= 'z'))) continue;

            if ((GetAsyncKeyState(keymap[c]) & 0x8000) == 0)
                vkeystat[keymap[c]] = false;
            else
            if (vkeystat[keymap[c]] == false)
            {
    vkeystat[keymap[c]] = true;
                vkeytime[keymap[c]] = timer_nowtime() + 800L;
                if (firstkey == 0) firstkey = keymap[c];
            }
   else
   if (timer_nowtime() > vkeytime[keymap[c]])
   {
                vkeytime[keymap[c]] = timer_nowtime() + 90L;
                if (firstkey == 0) firstkey = keymap[c];
   }
        }

        return firstkey;
    #else
        int c;
        
        if (!_kbhit()) return 0; else c = _getch();

        if ((c != 0) && (c != 0xe0))
            return keymap[c];
        else
            return keymap[_getch() + 256];
    #endif
}


unsigned keyboard_getkey(void) {                //根據keyboard的狀態來回傳
    switch (keyboard_inUse)
    {
  case KEYBOARD_STD:
            return keyboard_getkey_std();
        case KEYBOARD_ADV:
         return 0;
    }//end switch (keyboard_inUse)

 return 0;
}

unsigned keyboard_waitkey(void) {                //等待按完一個按鍵才繼續動作
    unsigned c;

    if (keyboard_inUse == KEYBOARD_NOUSE) return 0;

 while ((c = keyboard_getkey()) == 0);
 return c;
}
/*----------------- end of Keyboard Functions -----------------*/

Share:

0 留言:

張貼留言

技術提供:Blogger.

追蹤者