public byte WaitForKey() { bool success; success = WinApi.FlushConsoleInputBuffer(ConsoleInputHandle); if (!success) { throw new Exception($"Cannot wait on key - FlushConsoleInputBuffer failed: {new Win32Exception(Marshal.GetLastWin32Error()).Message}"); } var inputRecords = new WinApi.INPUT_RECORD[1]; while (true) { uint numEventsRead; success = WinApi.ReadConsoleInput(ConsoleInputHandle, inputRecords, 1, out numEventsRead); if (!success || numEventsRead != 1) { throw new Exception($"Cannot wait on key - ReadConsoleInput failed: {new Win32Exception(Marshal.GetLastWin32Error()).Message}"); } if (inputRecords[0].EventType == WinApi.KEY_EVENT) { var keyEvent = inputRecords[0].KeyEvent; // Only care about events for the 16 Chip-8 (COSMAC-VIP) Keys, ignore everything else // Also filter out keys that are repeated (already being held down), we want first hits only // TODO: The filtering out repeated of already-pressed keys isn't working, Windows just sends key down events // with a repeat count of 1 while holding down a key :( if (keyEvent.bKeyDown && keyEvent.wRepeatCount == 1 && WindowsVirtualScanCodeIsChip8Key(keyEvent.wVirtualScanCode)) { return(WindowsVirtualScanCodeToChip8Key(keyEvent.wVirtualScanCode)); } } } }
/// <summary> /// Process console input events to record which CHIP-8 keys are held down or not. /// </summary> public void ProcessInputEvents() { bool success; var inputRecords = new WinApi.INPUT_RECORD[1]; while (true) { uint numEvents; success = WinApi.GetNumberOfConsoleInputEvents(ConsoleInputHandle, out numEvents); if (!success) { throw new Exception($"Cannot process key input events - GetNumberOfConsoleInputEvents failed: {new Win32Exception(Marshal.GetLastWin32Error()).Message}"); } if (numEvents == 0) { break; } uint numEventsRead; success = WinApi.ReadConsoleInput(ConsoleInputHandle, inputRecords, 1, out numEventsRead); if (!success || numEventsRead != 1) { throw new Exception($"Cannot process key input events - ReadConsoleInput failed: {new Win32Exception(Marshal.GetLastWin32Error()).Message}"); } if (inputRecords[0].EventType == WinApi.KEY_EVENT) { var keyEvent = inputRecords[0].KeyEvent; // Only care about events for the 16 Chip-8 (COSMAC-VIP) Keys, ignore everything else if (WindowsVirtualScanCodeIsChip8Key(keyEvent.wVirtualScanCode)) { var chip8Key = WindowsVirtualScanCodeToChip8Key(keyEvent.wVirtualScanCode); KeyPressStates[chip8Key] = keyEvent.bKeyDown; } } } }