Thursday, April 9, 2009

Capturing key input (Update!)

Well, I finally managed to fix a few issues with my Chip8 emulator... One of them was the lousy input I used. With the help of a WinAPI call, I was able to make everything run smooth :)

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;