First I implemented the getAsyncKeyState function from User32.dll.
client static int getAsyncKeyState(int _vKey)
{
DLL _winApiDLL = new DLL(#UserDLL);
DLLFunction _getAsyncKeyState = new DLLFunction(_winApiDLL, 'GetAsyncKeyState');
;
_getAsyncKeyState.returns(ExtTypes::DWord);
_getAsyncKeyState.arg(ExtTypes::DWord);
return _getAsyncKeyState.call(_vKey);
}
Next, Chip8 has two opcodes that polls if a key is pressed. All I had to do was use my newly implemented method and now pong has never ran so smooth. Here's how it looks (chip2vkey converts a value from 0 .. 16 to the vKey value of the key I want to map):
case 0xE :
switch (opcode & 0xFF)
{
case 0x9E :
//EX9E - Skip next instruction if key V[X] is pressed
if (WinAPI::getAsyncKeyState(this.chip2vKey(reg[#X])) & 0x8000)
PC +=2;
break;
case 0xA1 :
//EXA1 - Skip next instruction if key V[X] is not pressed
if (!(WinAPI::getAsyncKeyState(this.chip2vKey(reg[#X])) & 0x8000))
PC +=2;
break;
default :
throw error("Invalid opcode " + int2hex(opcode, 4));
}
break;