c++iokeyboardhardware-interfaceioports

Writing to I/O Port Controller driver (inpout) (PS/2 Keyboard port) Left and Right keyboard keypresses?


I'm using inpout32/64 Hardware I/O Port Controller using this system driver InpOut32 and InpOutx64

I'm trying to use this to bypass problems I have with DirectInput games.
(Can't use SendInput, because it will reject inputs without a very long sleep delays, and I can't wait that long it has to be very fast keyboard inputs).

I currently got inpout32 working for mostly all my keyboard keys, I can't figure out how to access LEFT/RIGHT arrow keys.

By looking at this webpage about PS/2 Keyboard PS/2 Keyboard commands

Figured out this is what I need

0xE0, 0x4B   cursor left pressed
0xE0, 0x4D   cursor right pressed

How do I send both of those, I don't understand what is that 0xE0 i'm guessing it's the scan code and the 0x4B and 0x4D are the positions in that scan code, but it's not working in my example it keeps sending the \ for the LEFT key.

Here is the code I'm using

BOOL isDriverOn = false;
#define LEFT 0x4B 
#define RIGHT 0x4D 

void setup() {
        isDriverOn = IsInpOutDriverOpen();
}

//void  _stdcall Out32(short PortAddress, short data);
//short _stdcall Inp32(short PortAddress);
void DD_PS2command(short comm, short value) {
        if(!isDriverOn) {
            printf("PS/2 Keyboard port driver is not opened\n");
            return;
        }
        //keyboard wait.
        int kb_wait_cycle_counter = 1000;
        while((Inp32(0x64) & 0x02) && kb_wait_cycle_counter--) //wait to get communication.
            Sleep(1);
        if(kb_wait_cycle_counter) { //if it didn't timeout.
            Out32(0x64, comm); //send command
            kb_wait_cycle_counter = 1000;
            while((Inp32(0x64) & 0x02) && kb_wait_cycle_counter--) //wait to get communication.
                Sleep(1);
            if(!kb_wait_cycle_counter) {
                printf("failed to get communication in cycle counter timeout), who knows what will happen now\n");
                //return false;
            }
            Out32(0x60, value); //send data as short
            Sleep(1);
            //return true;
        } else {
            printf("failed to get communication in counter timeout, busy)\n");
            //return false;
        }
}

void DD_Button(short btn, bool release = false, int delay = 0)
{
  //0xE0, 0x4B   {Left}
  //0xE0, 0x4D   {Rght}
  //return scode | (release?0x80:0x00);
  short scan_code = 0;
  if(btn == LEFT)
      scan_code = LEFT + 0xE0;
  else if(btn == RIGHT)
      scan_code = RIGHT + 0xE0;
  else
      scan_code = 0x0;

  scan_code |= (release ? 0x80 : 0x00);

  if(delay)  
    Sleep(delay);
  DD_PS2command(0xD2, scan_code);
}




EDIT: Problem is solved, this below function works, just need to make DD_PS2command return true/false (to indicate if it went through or not).
New problem it releases the key instantly it doesn't hold the key down.

Here are all the keys http://www.computer-engineering.org/ps2keyboard/scancodes1.html

void DD_Button(short btn, bool release = false, int delay = 0)
{
  //;0xE0, 0x4B      {Left}
  //;0xE0, 0x4D      {Rght}
  //  return scode | (release? 0x80: 0x00)
  short scan_code = 0;
  bool good = false;
  switch(btn) {
    case LEFT:
    case RIGHT:
        scan_code = btn;
        //send extended byte first (grey code)
        good = DD_PS2command(0xD2, 0xE0);
        break;
  }
  printf("good = %d\n", good);
  scan_code |= (release ? 0x80 : 0x00);

  if(delay)  
    Sleep(delay);
  //0xD2 - Write keyboard output buffer
  good = DD_PS2command(0xD2, scan_code);
  printf("2 good = %d\n", good);
}

Solution

  • 0xE0 is an escape code for extended keys - i.e. for left, you send 0xE0, then send 0x4B immediately afterwards.