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);
}
0xE0
is an escape code for extended keys - i.e. for left, you send0xE0
, then send0x4B
immediately afterwards.