+ if (mouse_hook_enabled && (mouse_extra != 0x00)) {
+ // mouse wheel events have occurred; unlike l/m/r buttons, these are queued as keypresses, so add to end of buffer
+ switch (mouse_extra) {
+ case 0xff:
+ // wheel up
+ queue_keypress(0xfe, KEYPRESS_PRESS, PLATFORM_AMIGA);
+ break;
+ case 0x01:
+ // wheel down
+ queue_keypress(0xff, KEYPRESS_PRESS, PLATFORM_AMIGA);
+ break;
+ }
+
+ // dampen the scroll wheel until next while loop iteration
+ mouse_extra = 0x00;
+ }
+ goto cpu_loop;
+
+stop_cpu_emulation:
+ printf("[CPU] End of CPU thread\n");
+}
+
+void *keyboard_task() {
+ struct pollfd kbdfd[1];
+ int kpoll;
+
+ printf("[KBD] Keyboard thread started\n");
+
+ kbdfd[0].fd = keyboard_fd;
+ kbdfd[0].events = POLLIN;
+
+key_loop:
+ kpoll = poll(kbdfd, 1, KEY_POLL_INTERVAL_MSEC);
+ if ((kpoll > 0) && (kbdfd[0].revents & POLLHUP)) {
+ // in the event that a keyboard is unplugged, keyboard_task will whiz up to 100% utilisation
+ // this is undesired, so if the keyboard HUPs, end the thread without ending the emulation
+ printf("[KBD] Keyboard node returned HUP (unplugged?)\n");
+ goto key_end;
+ }
+
+ // if kpoll > 0 then it contains number of events to pull, also check if POLLIN is set in revents
+ if ((kpoll <= 0) || !(kbdfd[0].revents & POLLIN)) {
+ goto key_loop;
+ }
+
+ printf("[KBD-DEBUG] Going to process %d events\n", kpoll);
+