diff --git a/core/hostevents.cpp b/core/hostevents.cpp index 355f6c9..ffb26f7 100644 --- a/core/hostevents.cpp +++ b/core/hostevents.cpp @@ -46,12 +46,21 @@ void EventManager::poll_events() } break; - case SDL_KEYDOWN: - key_downs++; + case SDL_KEYDOWN: { + KeyboardEvent ke; + ke.key_code = event.key.keysym.sym; + ke.flags = KEYBOARD_EVENT_DOWN; + this->_keyboard_signal.emit(ke); + key_downs++; + } break; - case SDL_KEYUP: - key_ups++; + case SDL_KEYUP: { + KeyboardEvent ke; + ke.flags = KEYBOARD_EVENT_UP; + this->_keyboard_signal.emit(ke); + key_ups++; + } break; case SDL_MOUSEMOTION: { diff --git a/core/hostevents.h b/core/hostevents.h index 2092f33..6b1bcc8 100644 --- a/core/hostevents.h +++ b/core/hostevents.h @@ -39,7 +39,7 @@ enum : uint32_t { MOUSE_EVENT_MOTION = 1 << 0, MOUSE_EVENT_BUTTON = 1 << 1, KEYBOARD_EVENT_DOWN = 1 << 0, - KEYBOARD_EVENT_UP = 1 << 1, + KEYBOARD_EVENT_UP = 1 << 7, }; class MouseEvent { @@ -59,8 +59,12 @@ public: ~KeyboardEvent() = default; uint32_t flags; - uint32_t key; - uint16_t keys_state; + uint32_t key_code; + uint16_t led_lights; + uint8_t key_buffer[16]; + uint8_t key_state[128]; + uint8_t adb_code; + bool key_pressed; }; class EventManager { diff --git a/devices/common/adb/adbdevice.cpp b/devices/common/adb/adbdevice.cpp index 41cfa3e..cf7e884 100644 --- a/devices/common/adb/adbdevice.cpp +++ b/devices/common/adb/adbdevice.cpp @@ -88,6 +88,10 @@ bool AdbDevice::get_register_3() { return true; } +bool AdbDevice::assert_srq() { + return this->srq_flag; +} + uint8_t AdbDevice::gen_random_address() { return (TimerManager::get_instance()->current_time_ns() + 8) & 0xF; } diff --git a/devices/common/adb/adbdevice.h b/devices/common/adb/adbdevice.h index 49f68c1..8824820 100644 --- a/devices/common/adb/adbdevice.h +++ b/devices/common/adb/adbdevice.h @@ -65,6 +65,8 @@ protected: virtual void set_register_2() {}; virtual void set_register_3() {}; + virtual bool assert_srq(); + uint8_t exc_event_flag = 0; uint8_t srq_flag = 0; uint8_t my_addr = 0; diff --git a/devices/common/adb/adbkeyboard.cpp b/devices/common/adb/adbkeyboard.cpp index ce81522..d772b1d 100644 --- a/devices/common/adb/adbkeyboard.cpp +++ b/devices/common/adb/adbkeyboard.cpp @@ -32,23 +32,83 @@ AdbKeyboard::AdbKeyboard(std::string name) : AdbDevice(name) { void AdbKeyboard::event_handler(const KeyboardEvent& event) { if (event.flags & KEYBOARD_EVENT_DOWN) { - } + adb_code = adb_translate(event.key_code); + this->key_pressed = true; + for (int input_spot = 0; input_spot < 16; input_spot++) { + if (this->key_state[input_spot] == 0xFF) { + this->key_state[input_spot] = 0x0 | adb_code; + } + } + } else if (event.flags & KEYBOARD_EVENT_UP) { + this->key_pressed = false; + for (int input_spot = 0; input_spot < 16; input_spot++) { + this->key_state[input_spot] = 0x80 | adb_code; + } } } void AdbKeyboard::reset() { - this->my_addr = ADB_ADDR_KBD; - this->dev_handler_id = 2; // Extended ADB keyboard - this->exc_event_flag = 2; - this->srq_flag = 1; // enable service requests + this->my_addr = ADB_ADDR_KBD; + this->dev_handler_id = 2; // Standard ADB keyboard + this->exc_event_flag = 1; + this->srq_flag = 1; // enable service requests + this->flags = 0; + this->led_lights = 0; + for (int key_array_len = 0; key_array_len < 16; key_array_len++) { + this->key_state[key_array_len] = 0xFF; + } + this->key_pressed = false; } bool AdbKeyboard::get_register_0() { + if (this->key_pressed) { + uint8_t* out_buf = this->host_obj->get_output_buf(); + + for (int input_spot = 0; input_spot < 16; input_spot += 2) { + out_buf[0] = key_state[input_spot]; + out_buf[1] = key_state[input_spot + 1]; + + this->host_obj->set_output_count(2); + } + return true; + } + return false; +} + +bool AdbKeyboard::get_register_2() { + if (this->key_pressed) { + uint8_t* out_buf = this->host_obj->get_output_buf(); + + out_buf[0] = led_lights >> 8; + out_buf[1] = led_lights & 0xFF; + + this->host_obj->set_output_count(2); + this->key_pressed = false; + return true; + } return false; } void AdbKeyboard::set_register_2() { + for (int input_spot = 0; input_spot < 16; input_spot++) { + switch (key_state[input_spot]) { + case ADB_keycode_del: + led_lights |= 1 << 14; + case ADB_keycode_caps: + led_lights |= 1 << 13; + case ADB_keycode_ctrl: + led_lights |= 1 << 11; + case ADB_keycode_shift: + led_lights |= 1 << 10; + case ADB_keycode_opt: + led_lights |= 1 << 9; + case ADB_keycode_appl: + led_lights |= 1 << 8; + default: + led_lights = 0; + } + } } void AdbKeyboard::set_register_3() { @@ -78,8 +138,167 @@ void AdbKeyboard::set_register_3() { } } -static const DeviceDescription AdbKeyboard_Descriptor = { - AdbKeyboard::create, {}, {} -}; +uint8_t AdbKeyboard::adb_translate(SDL_Keycode input) { + // Hoping there's a better way to do this, + // but this will have to do for now. + switch (input) { + case SDLK_0: + return ADB_keycode_0; + case SDLK_1: + return ADB_keycode_1; + case SDLK_2: + return ADB_keycode_2; + case SDLK_3: + return ADB_keycode_3; + case SDLK_4: + return ADB_keycode_4; + case SDLK_5: + return ADB_keycode_5; + case SDLK_6: + return ADB_keycode_6; + case SDLK_7: + return ADB_keycode_7; + case SDLK_8: + return ADB_keycode_8; + case SDLK_9: + return ADB_keycode_9; + case SDLK_q: + return ADB_keycode_q; + case SDLK_w: + return ADB_keycode_w; + case SDLK_e: + return ADB_keycode_e; + case SDLK_r: + return ADB_keycode_r; + case SDLK_t: + return ADB_keycode_t; + case SDLK_y: + return ADB_keycode_y; + case SDLK_i: + return ADB_keycode_i; + case SDLK_o: + return ADB_keycode_o; + case SDLK_u: + return ADB_keycode_u; + case SDLK_p: + return ADB_keycode_p; + case SDLK_a: + return ADB_keycode_a; + case SDLK_s: + return ADB_keycode_s; + case SDLK_d: + return ADB_keycode_d; + case SDLK_f: + return ADB_keycode_f; + case SDLK_g: + return ADB_keycode_g; + case SDLK_h: + return ADB_keycode_h; + case SDLK_j: + return ADB_keycode_j; + case SDLK_k: + return ADB_keycode_k; + case SDLK_l: + return ADB_keycode_l; + case SDLK_z: + return ADB_keycode_z; + case SDLK_x: + return ADB_keycode_x; + case SDLK_c: + return ADB_keycode_c; + case SDLK_v: + return ADB_keycode_v; + case SDLK_b: + return ADB_keycode_b; + case SDLK_n: + return ADB_keycode_n; + case SDLK_m: + return ADB_keycode_m; + case SDLK_SPACE: + return ADB_keycode_space; + case SDLK_EQUALS: + return ADB_keycode_eq; + case SDLK_ESCAPE: + return ADB_keycode_esc; + case SDLK_RETURN: + return ADB_keycode_ret; + case SDLK_QUOTE: + return ADB_keycode_quote; + case SDLK_COMMA: + return ADB_keycode_comma; + case SDLK_PERIOD: + return ADB_keycode_per; + case SDLK_SLASH: + return ADB_keycode_slsh; + case SDLK_BACKSLASH: + return ADB_keycode_bksl; + case SDLK_LEFTBRACKET: + return ADB_keycode_lb; + case SDLK_RIGHTBRACKET: + return ADB_keycode_rb; + case SDLK_LEFT: + return ADB_keycode_left; + case SDLK_RIGHT: + return ADB_keycode_right; + case SDLK_UP: + return ADB_keycode_up; + case SDLK_DOWN: + return ADB_keycode_down; + //case SDLK_BACKQUOTE: -for ref; Apple Extended KB not yet implemented + // return ADB_keycode_bkqt; + case SDLK_TAB: + return ADB_keycode_tab; + case SDLK_BACKSPACE: + return ADB_keycode_del; + case SDLK_LSHIFT: + return ADB_keycode_shift; + case SDLK_LCTRL: + return ADB_keycode_ctrl; + case SDLK_LALT: + return ADB_keycode_opt; + case SDLK_BACKQUOTE: + case SDLK_APPLICATION: //temp map + case SDLK_MENU: + return ADB_keycode_opt; + case SDLK_CAPSLOCK: + return ADB_keycode_caps; + case SDLK_NUMLOCKCLEAR: + return ADB_keycode_kp_clr; + case SDLK_KP_DIVIDE: + return ADB_keycode_kp_div; + case SDLK_KP_MULTIPLY: + return ADB_keycode_kp_mul; + case SDLK_KP_MINUS: + return ADB_keycode_kp_minus; + case SDLK_KP_PLUS: + return ADB_keycode_kp_plus; + case SDLK_KP_ENTER: + return ADB_keycode_kp_enter; + case SDLK_KP_PERIOD: + return ADB_keycode_kp_per; + case SDLK_KP_0: + return ADB_keycode_kp_0; + case SDLK_KP_1: + return ADB_keycode_kp_1; + case SDLK_KP_2: + return ADB_keycode_kp_2; + case SDLK_KP_3: + return ADB_keycode_kp_3; + case SDLK_KP_4: + return ADB_keycode_kp_4; + case SDLK_KP_5: + return ADB_keycode_kp_5; + case SDLK_KP_6: + return ADB_keycode_kp_6; + case SDLK_KP_7: + return ADB_keycode_kp_7; + case SDLK_KP_8: + return ADB_keycode_kp_8; + case SDLK_KP_9: + return ADB_keycode_kp_9; + } +} + +static const DeviceDescription AdbKeyboard_Descriptor = {AdbKeyboard::create, {}, {}}; REGISTER_DEVICE(AdbKeyboard, AdbKeyboard_Descriptor); diff --git a/devices/common/adb/adbkeyboard.h b/devices/common/adb/adbkeyboard.h index fbebd2b..abfad89 100644 --- a/devices/common/adb/adbkeyboard.h +++ b/devices/common/adb/adbkeyboard.h @@ -28,9 +28,108 @@ along with this program. If not, see . #include #include +#include + +#include #include #include +enum : uint8_t { + ADB_keycode_a, + ADB_keycode_s, + ADB_keycode_d, + ADB_keycode_f, + ADB_keycode_h, + ADB_keycode_g, + ADB_keycode_z, + ADB_keycode_x, + ADB_keycode_c, + ADB_keycode_v, + ADB_keycode_int1, + ADB_keycode_b, + ADB_keycode_q, + ADB_keycode_w, + ADB_keycode_e, + ADB_keycode_r, + ADB_keycode_y, + ADB_keycode_t, + ADB_keycode_1, + ADB_keycode_2, + ADB_keycode_3, + ADB_keycode_4, + ADB_keycode_6, + ADB_keycode_5, + ADB_keycode_eq, + ADB_keycode_9, + ADB_keycode_7, + ADB_keycode_min, + ADB_keycode_8, + ADB_keycode_0, + ADB_keycode_rb, + ADB_keycode_o, + ADB_keycode_u, + ADB_keycode_lb, + ADB_keycode_i, + ADB_keycode_p, + ADB_keycode_ret, + ADB_keycode_l, + ADB_keycode_j, + ADB_keycode_quote, + ADB_keycode_k, + ADB_keycode_semi, + ADB_keycode_bksl, + ADB_keycode_comma, + ADB_keycode_slsh, + ADB_keycode_n, + ADB_keycode_m, + ADB_keycode_per, + ADB_keycode_tab, + ADB_keycode_space, + ADB_keycode_bkqt, + ADB_keycode_del, + ADB_keycode_bunk_34, + ADB_keycode_esc, + ADB_keycode_ctrl, + ADB_keycode_appl, + ADB_keycode_shift, + ADB_keycode_caps, + ADB_keycode_opt, + ADB_keycode_left, + ADB_keycode_right, + ADB_keycode_down, + ADB_keycode_up, + ADB_keycode_bunk_3f, + ADB_keycode_bunk_40, + ADB_keycode_kp_per, + ADB_keycode_bunk_42, + ADB_keycode_kp_mul, + ADB_keycode_bunk_44, + ADB_keycode_kp_plus, + ADB_keycode_bunk_46, + ADB_keycode_kp_clr, + ADB_keycode_bunk_48, + ADB_keycode_bunk_49, + ADB_keycode_bunk_4a, + ADB_keycode_kp_div, + ADB_keycode_kp_enter, + ADB_keycode_bunk_4d, + ADB_keycode_kp_minus, + ADB_keycode_bunk_4f, + ADB_keycode_bunk_50, + ADB_keycode_bunk_51, + ADB_keycode_kp_0, + ADB_keycode_kp_1, + ADB_keycode_kp_2, + ADB_keycode_kp_3, + ADB_keycode_kp_4, + ADB_keycode_kp_5, + ADB_keycode_kp_6, + ADB_keycode_kp_7, + ADB_keycode_bunk_5a, + ADB_keycode_kp_8, + ADB_keycode_kp_9, +}; + class AdbKeyboard : public AdbDevice { public: AdbKeyboard(std::string name); @@ -40,19 +139,25 @@ public: return std::unique_ptr(new AdbKeyboard("ADB-KEYBOARD")); } + uint8_t adb_translate(SDL_Keycode input); + void reset() override; void event_handler(const KeyboardEvent& event); bool get_register_0() override; + bool get_register_2() override; void set_register_2() override; void set_register_3() override; private: - int32_t x_rel = 0; - int32_t y_rel = 0; - uint8_t buttons_state = 0; - bool changed = false; + uint32_t flags = 0; + uint32_t key_code = 0; + uint16_t led_lights = 0; + uint8_t key_buffer[16] = {0xFF}; + uint8_t key_state[128] = {0xFF}; + uint8_t adb_code = 0; + bool key_pressed = false; }; -#endif // ADB_KEYBOARD_H \ No newline at end of file +#endif // ADB_KEYBOARD_H diff --git a/devices/common/viacuda.cpp b/devices/common/viacuda.cpp index dd804e5..a39c26c 100644 --- a/devices/common/viacuda.cpp +++ b/devices/common/viacuda.cpp @@ -479,7 +479,7 @@ void ViaCuda::autopoll_handler() { return; // send TALK R0 command to address 3 (mouse) - uint8_t in_data[2] = { 0x3C, 0}; + uint8_t in_data[2] = {poll_cmd, 0}; adb_status = this->adb_bus_obj->process_command(in_data, 1); @@ -490,7 +490,7 @@ void ViaCuda::autopoll_handler() { // prepare autopoll packet response_header(CUDA_PKT_ADB, adb_status | ADB_STAT_AUTOPOLL); - this->out_buf[2] = 0x3C; // put the proper ADB command + this->out_buf[2] = poll_cmd; // put the proper ADB command output_size = this->adb_bus_obj->get_output_count(); if (output_size) { std::memcpy(&this->out_buf[3], this->adb_bus_obj->get_output_buf(), output_size); @@ -504,6 +504,14 @@ void ViaCuda::autopoll_handler() { // draw guest system's attention schedule_sr_int(USECS_TO_NSECS(30)); } + + //alternate between mouse and keyboard between cycles + if (poll_cmd == 0x3C) { + poll_cmd = 0x2C; + } + else if (poll_cmd == 0x2C) { + poll_cmd = 0x3C; + } } void ViaCuda::pseudo_command(int cmd, int data_count) { diff --git a/devices/common/viacuda.h b/devices/common/viacuda.h index 1422690..30ae984 100644 --- a/devices/common/viacuda.h +++ b/devices/common/viacuda.h @@ -206,6 +206,7 @@ private: uint8_t old_byteack; uint8_t treq; uint8_t in_buf[CUDA_IN_BUF_SIZE]; + uint8_t poll_cmd = 0x3C; int32_t in_count; uint8_t out_buf[16]; int32_t out_count;