text: /******************************************************************************/
  /* Mednafen - Multi-system Emulator                                           */
  /******************************************************************************/
  /* keyboard.h:
  **  Copyright (C) 2017-2018 Mednafen Team
  **
  ** This program is free software; you can redistribute it and/or
  ** modify it under the terms of the GNU General Public License
  ** as published by the Free Software Foundation; either version 2
  ** of the License, or (at your option) any later version.
  **
  ** This program is distributed in the hope that it will be useful,
  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ** GNU General Public License for more details.
  **
  ** You should have received a copy of the GNU General Public License
  ** along with this program; if not, write to the Free Software Foundation, Inc.,
  ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
  
  #ifndef __MDFN_DRIVERS_KEYBOARD_H
  #define __MDFN_DRIVERS_KEYBOARD_H
  
  #include "keyboard_scancodes.h"
  
  #define MKK(k) MDFN_SCANCODE_##k
  #define MKK_COUNT (MDFN_NUM_SCANCODES)
  
  #define KBD_SCANCODE_STRING__(sc) #sc
  #define KBD_SCANCODE_STRING_(sc) KBD_SCANCODE_STRING__(sc)
  #define KBD_SCANCODE_STRING(sc) KBD_SCANCODE_STRING_(MKK(sc))
  
  enum
  {
   KEYBOARD_BN_INDEX_MASK = 0x0FFF,
   KEYBOARD_BN_MODS_SHIFT = 12,
   //KEYBOARD_BN_MODS_MASK = 0xF << KB_BN_MODS_SHIFT
  };
  
  namespace KBMan
  {
   enum
   {
    KEYS_FLAG_PRESSED		= 0x1,
    KEYS_FLAG_PRESSED_MASKBYPASS	= (KEYS_FLAG_PRESSED << 1),
    //
    KEYS_FLAG_KEYUP 		= 0x4,
    KEYS_FLAG_KEYDOWN 		= 0x8,
    KEYS_FLAG_KEYDOWN_SEEN	= (KEYS_FLAG_KEYDOWN << 1),
   };
  
   MDFN_HIDE extern uint8 keys[MKK_COUNT];
   MDFN_HIDE extern uint32 mods[2][2];
  
   void Init(void) MDFN_COLD;
   void Kill(void) MDFN_COLD;
  
   void Reset_BC_ChangeCheck(bool isck);
   bool Do_BC_ChangeCheck(ButtConfig* bc);
  
   void Event(const SDL_Event* event);
   void UpdateKeyboards(void);
  
   void MaskSysKBKeys(void);
   void UnmaskSysKBKeys(const unsigned* sc, const size_t count);
  
   std::string BNToString(const uint32 bn);
   bool StringToBN(const char* s, uint16* bn);
  
   INLINE bool TestSC(const size_t sc, const bool bypass_key_masking)
   {
    return (keys[sc] >> bypass_key_masking) & KEYS_FLAG_PRESSED;
   }
  
   INLINE bool TestButton(const ButtConfig& bc, const bool bypass_key_masking)
   {
    return TestSC(bc.ButtonNum & KEYBOARD_BN_INDEX_MASK, bypass_key_masking);
   }
  
   INLINE bool TestButtonWithMods(const ButtConfig&bc, const bool bypass_key_masking, const bool ignore_ralt)
   {
    return TestButton(bc, bypass_key_masking) & ((unsigned)(bc.ButtonNum >> KEYBOARD_BN_MODS_SHIFT) == mods[bypass_key_masking][ignore_ralt]);
   }
  
   INLINE int32 TestAnalogButton(const ButtConfig& bc, const bool bypass_key_masking)
   {
    return std::min<int32>(32767, ((TestButton(bc, bypass_key_masking) ? 32767 : 0) * bc.Scale) >> 12);
   }
  
   INLINE int64 TestAxisRel(const ButtConfig& bc, const bool bypass_key_masking)
   {
    return (int64)(TestButton(bc, bypass_key_masking) * bc.Scale) << 4;
   }
  }
  
  #endif
  