From 4835ae35afafa88aac69b8db70743defc4c4ac4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Wed, 11 Sep 2013 22:49:49 +0200 Subject: [PATCH] Keybord support Added * Implemented 'cellKb*' functions from 'sys_io' module, which are part of the libkb library. * Added corresponding entries in the 'Config > Settings' menu to change the handler of the keyboard. Supported handlers: Windows, Null. INFO: This keyboard library is *very* experimental and I am aware of some bugs. There will be improvements soon. --- rpcs3/Emu/Io/Keyboard.cpp | 38 +++ rpcs3/Emu/Io/Keyboard.h | 27 ++ rpcs3/Emu/Io/KeyboardHandler.h | 301 ++++++++++++++++++ rpcs3/Emu/Io/Null/NullKeyboardHandler.h | 24 ++ rpcs3/Emu/Io/Windows/WindowsKeyboardHandler.h | 162 ++++++++++ rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 28 -- rpcs3/Emu/SysCalls/Modules/sys_io.cpp | 11 + rpcs3/Emu/SysCalls/SysCalls.h | 12 + rpcs3/Emu/SysCalls/lv2/SC_Keyboard.cpp | 166 ++++++++++ rpcs3/Emu/System.cpp | 1 + rpcs3/Emu/System.h | 3 + rpcs3/Gui/MainFrame.cpp | 14 +- rpcs3/Ini.h | 8 +- rpcs3/rpcs3.vcxproj | 2 + rpcs3/rpcs3.vcxproj.filters | 6 + 15 files changed, 771 insertions(+), 32 deletions(-) create mode 100644 rpcs3/Emu/Io/Keyboard.cpp create mode 100644 rpcs3/Emu/Io/Keyboard.h create mode 100644 rpcs3/Emu/Io/KeyboardHandler.h create mode 100644 rpcs3/Emu/Io/Null/NullKeyboardHandler.h create mode 100644 rpcs3/Emu/Io/Windows/WindowsKeyboardHandler.h create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_Keyboard.cpp diff --git a/rpcs3/Emu/Io/Keyboard.cpp b/rpcs3/Emu/Io/Keyboard.cpp new file mode 100644 index 0000000000..e20e90e313 --- /dev/null +++ b/rpcs3/Emu/Io/Keyboard.cpp @@ -0,0 +1,38 @@ +#include "stdafx.h" +#include "Keyboard.h" +#include "Null/NullKeyboardHandler.h" +#include "Windows/WindowsKeyboardHandler.h" + +KeyboardManager::KeyboardManager() + : m_keyboard_handler(nullptr) + , m_inited(false) +{ +} + +KeyboardManager::~KeyboardManager() +{ +} + +void KeyboardManager::Init(const u32 max_connect) +{ + if(m_inited) return; + + switch(Ini.KeyboardHandlerMode.GetValue()) + { + case 1: m_keyboard_handler = new WindowsKeyboardHandler(); break; + + default: + case 0: m_keyboard_handler = new NullKeyboardHandler(); break; + } + + m_keyboard_handler->Init(max_connect); + m_inited = true; +} + +void KeyboardManager::Close() +{ + if(m_keyboard_handler) m_keyboard_handler->Close(); + m_keyboard_handler = nullptr; + + m_inited = false; +} \ No newline at end of file diff --git a/rpcs3/Emu/Io/Keyboard.h b/rpcs3/Emu/Io/Keyboard.h new file mode 100644 index 0000000000..5a44408fde --- /dev/null +++ b/rpcs3/Emu/Io/Keyboard.h @@ -0,0 +1,27 @@ +#pragma once + +#include "KeyboardHandler.h" + +class KeyboardManager //: public wxWindow +{ + bool m_inited; + KeyboardHandlerBase* m_keyboard_handler; + +public: + KeyboardManager(); + ~KeyboardManager(); + + void Init(const u32 max_connect); + void Close(); + + Array& GetKeyboards() { return m_keyboard_handler->GetKeyboards(); } + KbInfo& GetInfo() { return m_keyboard_handler->GetInfo(); } + Array& GetButtons(const u32 keyboard) { return m_keyboard_handler->GetButtons(keyboard); } + CellKbData& GetData(const u32 keyboard) { return m_keyboard_handler->GetData(keyboard); } + CellKbConfig& GetConfig(const u32 keyboard) { return m_keyboard_handler->GetConfig(keyboard); } + + bool IsInited() { return m_inited; } + +//private: + //DECLARE_EVENT_TABLE(); +}; \ No newline at end of file diff --git a/rpcs3/Emu/Io/KeyboardHandler.h b/rpcs3/Emu/Io/KeyboardHandler.h new file mode 100644 index 0000000000..44bd2bdfcf --- /dev/null +++ b/rpcs3/Emu/Io/KeyboardHandler.h @@ -0,0 +1,301 @@ +#pragma once + +extern u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode); // (TODO: Can it be problematic to place SysCalls in middle of nowhere?) + +enum KbPortStatus +{ + CELL_KB_STATUS_DISCONNECTED = 0x00000000, + CELL_KB_STATUS_CONNECTED = 0x00000001, +}; + +enum CellKbReadMode +{ + CELL_KB_RMODE_INPUTCHAR = 0, + CELL_KB_RMODE_PACKET = 1, +}; + +enum CellKbCodeType +{ + CELL_KB_CODETYPE_RAW = 0, + CELL_KB_CODETYPE_ASCII = 1, +}; + +enum KbMetaKeys +{ + CELL_KB_MKEY_L_CTRL = 0x00000001, + CELL_KB_MKEY_L_SHIFT = 0x00000002, + CELL_KB_MKEY_L_ALT = 0x00000004, + CELL_KB_MKEY_L_WIN = 0x00000008, + CELL_KB_MKEY_R_CTRL = 0x00000010, + CELL_KB_MKEY_R_SHIFT = 0x00000020, + CELL_KB_MKEY_R_ALT = 0x00000040, + CELL_KB_MKEY_R_WIN = 0x00000080, +}; + +enum Keys +{ + // Non-ASCII Raw data + CELL_KEYC_NO_EVENT = 0x00, + CELL_KEYC_E_ROLLOVER = 0x01, + CELL_KEYC_E_POSTFAIL = 0x02, + CELL_KEYC_E_UNDEF = 0x03, + CELL_KEYC_ESCAPE = 0x29, + CELL_KEYC_106_KANJI = 0x35, + CELL_KEYC_CAPS_LOCK = 0x39, + CELL_KEYC_F1 = 0x3a, + CELL_KEYC_F2 = 0x3b, + CELL_KEYC_F3 = 0x3c, + CELL_KEYC_F4 = 0x3d, + CELL_KEYC_F5 = 0x3e, + CELL_KEYC_F6 = 0x3f, + CELL_KEYC_F7 = 0x40, + CELL_KEYC_F8 = 0x41, + CELL_KEYC_F9 = 0x42, + CELL_KEYC_F10 = 0x43, + CELL_KEYC_F11 = 0x44, + CELL_KEYC_F12 = 0x45, + CELL_KEYC_PRINTSCREEN = 0x46, + CELL_KEYC_SCROLL_LOCK = 0x47, + CELL_KEYC_PAUSE = 0x48, + CELL_KEYC_INSERT = 0x49, + CELL_KEYC_HOME = 0x4a, + CELL_KEYC_PAGE_UP = 0x4b, + CELL_KEYC_DELETE = 0x4c, + CELL_KEYC_END = 0x4d, + CELL_KEYC_PAGE_DOWN = 0x4e, + CELL_KEYC_RIGHT_ARROW = 0x4f, + CELL_KEYC_LEFT_ARROW = 0x50, + CELL_KEYC_DOWN_ARROW = 0x51, + CELL_KEYC_UP_ARROW = 0x52, + CELL_KEYC_NUM_LOCK = 0x53, + CELL_KEYC_APPLICATION = 0x65, + CELL_KEYC_KANA = 0x88, + CELL_KEYC_HENKAN = 0x8a, + CELL_KEYC_MUHENKAN = 0x8b, + + // Raw keycodes for ASCII keys + CELL_KEYC_A = 0x04, + CELL_KEYC_B = 0x05, + CELL_KEYC_C = 0x06, + CELL_KEYC_D = 0x07, + CELL_KEYC_E = 0x08, + CELL_KEYC_F = 0x09, + CELL_KEYC_G = 0x0A, + CELL_KEYC_H = 0x0B, + CELL_KEYC_I = 0x0C, + CELL_KEYC_J = 0x0D, + CELL_KEYC_K = 0x0E, + CELL_KEYC_L = 0x0F, + CELL_KEYC_M = 0x10, + CELL_KEYC_N = 0x11, + CELL_KEYC_O = 0x12, + CELL_KEYC_P = 0x13, + CELL_KEYC_Q = 0x14, + CELL_KEYC_R = 0x15, + CELL_KEYC_S = 0x16, + CELL_KEYC_T = 0x17, + CELL_KEYC_U = 0x18, + CELL_KEYC_V = 0x19, + CELL_KEYC_W = 0x1A, + CELL_KEYC_X = 0x1B, + CELL_KEYC_Y = 0x1C, + CELL_KEYC_Z = 0x1D, + CELL_KEYC_1 = 0x1E, + CELL_KEYC_2 = 0x1F, + CELL_KEYC_3 = 0x20, + CELL_KEYC_4 = 0x21, + CELL_KEYC_5 = 0x22, + CELL_KEYC_6 = 0x23, + CELL_KEYC_7 = 0x24, + CELL_KEYC_8 = 0x25, + CELL_KEYC_9 = 0x26, + CELL_KEYC_0 = 0x27, + CELL_KEYC_ENTER = 0x28, + CELL_KEYC_ESC = 0x29, + CELL_KEYC_BS = 0x2A, + CELL_KEYC_TAB = 0x2B, + CELL_KEYC_SPACE = 0x2C, + CELL_KEYC_MINUS = 0x2D, + CELL_KEYC_EQUAL_101 = 0x2E, + CELL_KEYC_ACCENT_CIRCONFLEX_106 = 0x2E, + CELL_KEYC_LEFT_BRACKET_101 = 0x2F, + CELL_KEYC_ATMARK_106 = 0x2F, + CELL_KEYC_RIGHT_BRACKET_101 = 0x30, + CELL_KEYC_LEFT_BRACKET_106 = 0x30, + CELL_KEYC_BACKSLASH_101 = 0x31, + CELL_KEYC_RIGHT_BRACKET_106 = 0x32, + CELL_KEYC_SEMICOLON = 0x33, + CELL_KEYC_QUOTATION_101 = 0x34, + CELL_KEYC_COLON_106 = 0x34, + CELL_KEYC_COMMA = 0x36, + CELL_KEYC_PERIOD = 0x37, + CELL_KEYC_SLASH = 0x38, + //CELL_KEYC_CAPS_LOCK = 0x39, + CELL_KEYC_KPAD_NUMLOCK = 0x53, + CELL_KEYC_KPAD_SLASH = 0x54, + CELL_KEYC_KPAD_ASTERISK = 0x55, + CELL_KEYC_KPAD_MINUS = 0x56, + CELL_KEYC_KPAD_PLUS = 0x57, + CELL_KEYC_KPAD_ENTER = 0x58, + CELL_KEYC_KPAD_1 = 0x59, + CELL_KEYC_KPAD_2 = 0x5A, + CELL_KEYC_KPAD_3 = 0x5B, + CELL_KEYC_KPAD_4 = 0x5C, + CELL_KEYC_KPAD_5 = 0x5D, + CELL_KEYC_KPAD_6 = 0x5E, + CELL_KEYC_KPAD_7 = 0x5F, + CELL_KEYC_KPAD_8 = 0x60, + CELL_KEYC_KPAD_9 = 0x61, + CELL_KEYC_KPAD_0 = 0x62, + CELL_KEYC_KPAD_PERIOD = 0x63, + CELL_KEYC_BACKSLASH_106 = 0x87, + CELL_KEYC_YEN_106 = 0x89, +}; + +enum CellKbMappingType +{ + CELL_KB_MAPPING_101, + CELL_KB_MAPPING_106, + CELL_KB_MAPPING_106_KANA, + CELL_KB_MAPPING_GERMAN_GERMANY, + CELL_KB_MAPPING_SPANISH_SPAIN, + CELL_KB_MAPPING_FRENCH_FRANCE, + CELL_KB_MAPPING_ITALIAN_ITALY, + CELL_KB_MAPPING_DUTCH_NETHERLANDS, + CELL_KB_MAPPING_PORTUGUESE_PORTUGAL, + CELL_KB_MAPPING_RUSSIAN_RUSSIA, + CELL_KB_MAPPING_ENGLISH_UK, + CELL_KB_MAPPING_KOREAN_KOREA, + CELL_KB_MAPPING_NORWEGIAN_NORWAY, + CELL_KB_MAPPING_FINNISH_FINLAND, + CELL_KB_MAPPING_DANISH_DENMARK, + CELL_KB_MAPPING_SWEDISH_SWEDEN, + CELL_KB_MAPPING_CHINESE_TRADITIONAL, + CELL_KB_MAPPING_CHINESE_SIMPLIFIED, + CELL_KB_MAPPING_SWISS_FRENCH_SWITZERLAND, + CELL_KB_MAPPING_SWISS_GERMAN_SWITZERLAND, + CELL_KB_MAPPING_CANADIAN_FRENCH_CANADA, + CELL_KB_MAPPING_BELGIAN_BELGIUM, + CELL_KB_MAPPING_POLISH_POLAND, + CELL_KB_MAPPING_PORTUGUESE_BRAZIL, +}; + +static const u32 CELL_KB_MAX_KEYBOARDS = 127; +static const u32 CELL_KB_MAX_PORT_NUM = 7; +static const u32 CELL_KB_MAX_KEYCODES = 62; + +struct KbInfo +{ + u32 max_connect; + u32 now_connect; + u32 info; + u8 status[CELL_KB_MAX_KEYBOARDS]; +}; + +struct CellKbData +{ + u32 led; + u32 mkey; + s32 len; + u16 keycode[CELL_KB_MAX_KEYCODES]; + + CellKbData() + : led(0) + , mkey(0) + , len(0) + { + } +}; + +struct CellKbConfig +{ + u32 arrange; + u32 read_mode; + u32 code_type; + + CellKbConfig() + : arrange(CELL_KB_MAPPING_106) + , read_mode(CELL_KB_RMODE_INPUTCHAR) + , code_type(CELL_KB_CODETYPE_ASCII) + { + } +}; + +struct KbButton +{ + u32 m_keyCode; + u32 m_outKeyCode; + bool m_pressed; + //bool m_flush; + + KbButton(u32 keyCode, u32 outKeyCode) + : m_pressed(false) + //, m_flush(false) + , m_keyCode(keyCode) + , m_outKeyCode(outKeyCode) + { + } +}; + +struct Keyboard +{ + CellKbData m_data; + CellKbConfig m_config; + Array m_buttons; + + Keyboard() + : m_data() + , m_config() + { + } + + ~Keyboard() { m_buttons.Clear(); } +}; + +class KeyboardHandlerBase +{ +protected: + KbInfo m_info; + Array m_keyboards; + +public: + virtual void Init(const u32 max_connect)=0; + virtual void Close()=0; + + void Key(const u32 code, bool pressed) + { + for(u64 p=0; p& GetKeyboards() { return m_keyboards; } + Array& GetButtons(const u32 keyboard) { return GetKeyboards()[keyboard].m_buttons; } + CellKbData& GetData(const u32 keyboard) { return GetKeyboards()[keyboard].m_data; } + CellKbConfig& GetConfig(const u32 keyboard) { return GetKeyboards()[keyboard].m_config; } +}; \ No newline at end of file diff --git a/rpcs3/Emu/Io/Null/NullKeyboardHandler.h b/rpcs3/Emu/Io/Null/NullKeyboardHandler.h new file mode 100644 index 0000000000..d5693a78cc --- /dev/null +++ b/rpcs3/Emu/Io/Null/NullKeyboardHandler.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Emu/Io/KeyboardHandler.h" + +class NullKeyboardHandler : public KeyboardHandlerBase +{ +public: + NullKeyboardHandler() + { + } + + virtual void Init(const u32 max_connect) + { + memset(&m_info, 0, sizeof(KbInfo)); + m_info.max_connect = max_connect; + m_keyboards.Clear(); + } + + virtual void Close() + { + memset(&m_info, 0, sizeof(KbInfo)); + m_keyboards.Clear(); + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/Io/Windows/WindowsKeyboardHandler.h b/rpcs3/Emu/Io/Windows/WindowsKeyboardHandler.h new file mode 100644 index 0000000000..020dcd96fc --- /dev/null +++ b/rpcs3/Emu/Io/Windows/WindowsKeyboardHandler.h @@ -0,0 +1,162 @@ +#pragma once + +#include "Emu/Io/KeyboardHandler.h" + +class WindowsKeyboardHandler + : public wxWindow + , public KeyboardHandlerBase +{ + AppConnector m_app_connector; + +public: + WindowsKeyboardHandler() : wxWindow() + { + m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WindowsKeyboardHandler::KeyDown), (wxObject*)0, this); + m_app_connector.Connect(wxEVT_KEY_UP, wxKeyEventHandler(WindowsKeyboardHandler::KeyUp), (wxObject*)0, this); + } + + virtual void KeyDown(wxKeyEvent& event) { Key(event.GetKeyCode(), 1); event.Skip(); } + virtual void KeyUp(wxKeyEvent& event) { Key(event.GetKeyCode(), 0); event.Skip(); } + + virtual void Init(const u32 max_connect) + { + for(u32 i=0; i(GetKeyboards().GetCount(), max_connect); + m_info.info = 0; // Ownership of keyboard data: 0=Application, 1=System + m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards) + } + + virtual void Close() + { + memset(&m_info, 0, sizeof(KbInfo)); + m_keyboards.Clear(); + } + + void LoadSettings() + { + // CELL_KB_RAWDAT + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_NO_EVENT)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_E_ROLLOVER)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_E_POSTFAIL)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_E_UNDEF)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_ESCAPE, CELL_KEYC_ESCAPE)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_106_KANJI)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_CAPS_LOCK)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F1, CELL_KEYC_F1)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F2, CELL_KEYC_F2)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F3, CELL_KEYC_F3)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F4, CELL_KEYC_F4)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F5, CELL_KEYC_F5)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F6, CELL_KEYC_F6)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F7, CELL_KEYC_F7)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F8, CELL_KEYC_F8)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F9, CELL_KEYC_F9)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F10, CELL_KEYC_F10)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F11, CELL_KEYC_F11)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_F12, CELL_KEYC_F12)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_PRINT, CELL_KEYC_PRINTSCREEN)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_SCROLL, CELL_KEYC_SCROLL_LOCK)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_PAUSE, CELL_KEYC_PAUSE)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_INSERT, CELL_KEYC_INSERT)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_HOME)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_PAGEUP, CELL_KEYC_PAGE_UP)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_DELETE, CELL_KEYC_DELETE)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_END, CELL_KEYC_END)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_PAGEDOWN, CELL_KEYC_PAGE_DOWN)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_RIGHT, CELL_KEYC_RIGHT_ARROW)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_LEFT, CELL_KEYC_LEFT_ARROW)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_DOWN, CELL_KEYC_DOWN_ARROW)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_UP, CELL_KEYC_UP_ARROW)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_APPLICATION)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_KANA)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_HENKAN)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_MUHENKAN)); + + // CELL_KB_KEYPAD + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMLOCK, CELL_KEYC_KPAD_NUMLOCK)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_DIVIDE, CELL_KEYC_KPAD_SLASH)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_MULTIPLY, CELL_KEYC_KPAD_ASTERISK)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_SUBTRACT, CELL_KEYC_KPAD_MINUS)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_ADD, CELL_KEYC_KPAD_PLUS)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_ENTER, CELL_KEYC_KPAD_ENTER)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD1, CELL_KEYC_KPAD_1)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD2, CELL_KEYC_KPAD_2)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD3, CELL_KEYC_KPAD_3)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD4, CELL_KEYC_KPAD_4)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD5, CELL_KEYC_KPAD_5)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD6, CELL_KEYC_KPAD_6)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD7, CELL_KEYC_KPAD_7)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD8, CELL_KEYC_KPAD_8)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD9, CELL_KEYC_KPAD_9)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD0, CELL_KEYC_KPAD_0)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_NUMPAD_DELETE, CELL_KEYC_KPAD_PERIOD)); + + // ASCII Printable characters + m_keyboards[0].m_buttons.Move(new KbButton('A', CELL_KEYC_A)); + m_keyboards[0].m_buttons.Move(new KbButton('B', CELL_KEYC_B)); + m_keyboards[0].m_buttons.Move(new KbButton('C', CELL_KEYC_C)); + m_keyboards[0].m_buttons.Move(new KbButton('D', CELL_KEYC_D)); + m_keyboards[0].m_buttons.Move(new KbButton('E', CELL_KEYC_E)); + m_keyboards[0].m_buttons.Move(new KbButton('F', CELL_KEYC_F)); + m_keyboards[0].m_buttons.Move(new KbButton('G', CELL_KEYC_G)); + m_keyboards[0].m_buttons.Move(new KbButton('H', CELL_KEYC_H)); + m_keyboards[0].m_buttons.Move(new KbButton('I', CELL_KEYC_I)); + m_keyboards[0].m_buttons.Move(new KbButton('J', CELL_KEYC_J)); + m_keyboards[0].m_buttons.Move(new KbButton('K', CELL_KEYC_K)); + m_keyboards[0].m_buttons.Move(new KbButton('L', CELL_KEYC_L)); + m_keyboards[0].m_buttons.Move(new KbButton('M', CELL_KEYC_M)); + m_keyboards[0].m_buttons.Move(new KbButton('N', CELL_KEYC_N)); + m_keyboards[0].m_buttons.Move(new KbButton('O', CELL_KEYC_O)); + m_keyboards[0].m_buttons.Move(new KbButton('P', CELL_KEYC_P)); + m_keyboards[0].m_buttons.Move(new KbButton('Q', CELL_KEYC_Q)); + m_keyboards[0].m_buttons.Move(new KbButton('R', CELL_KEYC_R)); + m_keyboards[0].m_buttons.Move(new KbButton('S', CELL_KEYC_S)); + m_keyboards[0].m_buttons.Move(new KbButton('T', CELL_KEYC_T)); + m_keyboards[0].m_buttons.Move(new KbButton('U', CELL_KEYC_U)); + m_keyboards[0].m_buttons.Move(new KbButton('V', CELL_KEYC_V)); + m_keyboards[0].m_buttons.Move(new KbButton('W', CELL_KEYC_W)); + m_keyboards[0].m_buttons.Move(new KbButton('X', CELL_KEYC_X)); + m_keyboards[0].m_buttons.Move(new KbButton('Y', CELL_KEYC_Y)); + m_keyboards[0].m_buttons.Move(new KbButton('Z', CELL_KEYC_Z)); + + m_keyboards[0].m_buttons.Move(new KbButton('1', CELL_KEYC_1)); + m_keyboards[0].m_buttons.Move(new KbButton('2', CELL_KEYC_2)); + m_keyboards[0].m_buttons.Move(new KbButton('3', CELL_KEYC_3)); + m_keyboards[0].m_buttons.Move(new KbButton('4', CELL_KEYC_4)); + m_keyboards[0].m_buttons.Move(new KbButton('5', CELL_KEYC_5)); + m_keyboards[0].m_buttons.Move(new KbButton('6', CELL_KEYC_6)); + m_keyboards[0].m_buttons.Move(new KbButton('7', CELL_KEYC_7)); + m_keyboards[0].m_buttons.Move(new KbButton('8', CELL_KEYC_8)); + m_keyboards[0].m_buttons.Move(new KbButton('9', CELL_KEYC_9)); + m_keyboards[0].m_buttons.Move(new KbButton('0', CELL_KEYC_0)); + + m_keyboards[0].m_buttons.Move(new KbButton(WXK_RETURN, CELL_KEYC_ENTER)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_ESC)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_TAB, CELL_KEYC_TAB)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_SPACE, CELL_KEYC_SPACE)); + m_keyboards[0].m_buttons.Move(new KbButton(WXK_SUBTRACT, CELL_KEYC_MINUS)); + m_keyboards[0].m_buttons.Move(new KbButton('=', CELL_KEYC_EQUAL_101)); + m_keyboards[0].m_buttons.Move(new KbButton('^', CELL_KEYC_ACCENT_CIRCONFLEX_106)); + //m_keyboards[0].m_buttons.Move(new KbButton('(', CELL_KEYC_LEFT_BRACKET_101)); + m_keyboards[0].m_buttons.Move(new KbButton('@', CELL_KEYC_ATMARK_106)); + //m_keyboards[0].m_buttons.Move(new KbButton(')', CELL_KEYC_RIGHT_BRACKET_101)); + m_keyboards[0].m_buttons.Move(new KbButton('(', CELL_KEYC_LEFT_BRACKET_106)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_BACKSLASH_101)); + m_keyboards[0].m_buttons.Move(new KbButton('(', CELL_KEYC_RIGHT_BRACKET_106)); + m_keyboards[0].m_buttons.Move(new KbButton(';', CELL_KEYC_SEMICOLON)); + m_keyboards[0].m_buttons.Move(new KbButton('"', CELL_KEYC_QUOTATION_101)); + m_keyboards[0].m_buttons.Move(new KbButton(':', CELL_KEYC_COLON_106)); + m_keyboards[0].m_buttons.Move(new KbButton(',', CELL_KEYC_COMMA)); + m_keyboards[0].m_buttons.Move(new KbButton('.', CELL_KEYC_PERIOD)); + m_keyboards[0].m_buttons.Move(new KbButton('/', CELL_KEYC_SLASH)); + m_keyboards[0].m_buttons.Move(new KbButton('\\', CELL_KEYC_BACKSLASH_106)); + //m_keyboards[0].m_buttons.Move(new KbButton(, CELL_KEYC_YEN_106)); + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 1602f4fc52..643879ccdd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -99,34 +99,6 @@ enum CELL_SYSUTIL_PAD_RUMBLE_ON = 1, }; -enum -{ - CELL_KB_MAPPING_101, - CELL_KB_MAPPING_106, - CELL_KB_MAPPING_106_KANA, - CELL_KB_MAPPING_GERMAN_GERMANY, - CELL_KB_MAPPING_SPANISH_SPAIN, - CELL_KB_MAPPING_FRENCH_FRANCE, - CELL_KB_MAPPING_ITALIAN_ITALY, - CELL_KB_MAPPING_DUTCH_NETHERLANDS, - CELL_KB_MAPPING_PORTUGUESE_PORTUGAL, - CELL_KB_MAPPING_RUSSIAN_RUSSIA, - CELL_KB_MAPPING_ENGLISH_UK, - CELL_KB_MAPPING_KOREAN_KOREA, - CELL_KB_MAPPING_NORWEGIAN_NORWAY, - CELL_KB_MAPPING_FINNISH_FINLAND, - CELL_KB_MAPPING_DANISH_DENMARK, - CELL_KB_MAPPING_SWEDISH_SWEDEN, - CELL_KB_MAPPING_CHINESE_TRADITIONAL, - CELL_KB_MAPPING_CHINESE_SIMPLIFIED, - CELL_KB_MAPPING_SWISS_FRENCH_SWITZERLAND, - CELL_KB_MAPPING_SWISS_GERMAN_SWITZERLAND, - CELL_KB_MAPPING_CANADIAN_FRENCH_CANADA, - CELL_KB_MAPPING_BELGIAN_BELGIUM, - CELL_KB_MAPPING_POLISH_POLAND, - CELL_KB_MAPPING_PORTUGUESE_BRAZIL, -}; - void cellSysutil_init(); Module cellSysutil(0x0015, cellSysutil_init); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index 385f5c99d1..4339052ecf 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -15,4 +15,15 @@ void sys_io_init() sys_io.AddFunc(0xf65544ee, cellPadSetActDirect); sys_io.AddFunc(0xa703a51d, cellPadGetInfo2); sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting); + + sys_io.AddFunc(0x433f6ec0, cellKbInit); + sys_io.AddFunc(0xbfce3285, cellKbEnd); + sys_io.AddFunc(0x2073b7f6, cellKbClearBuf); + sys_io.AddFunc(0x4ab1fa77, cellKbCnvRawCode); + sys_io.AddFunc(0x2f1774d5, cellKbGetInfo); + sys_io.AddFunc(0xff0a21b7, cellKbRead); + sys_io.AddFunc(0xa5f85e4d, cellKbSetCodeType); + sys_io.AddFunc(0x3f72c56e, cellKbSetLEDStatus); + sys_io.AddFunc(0xdeefdfa7, cellKbSetReadMode); + sys_io.AddFunc(0x1f71ecbe, cellKbGetConfiguration); } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index edbb9a6dae..68e12d882a 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -216,6 +216,18 @@ extern int cellPadSetActDirect(u32 port_no, u32 param_addr); extern int cellPadGetInfo2(u32 info_addr); extern int cellPadSetPortSetting(u32 port_no, u32 port_setting); +//cellKb +extern int cellKbInit(u32 max_connect); +extern int cellKbEnd(); +extern int cellKbClearBuf(u32 port_no); +extern u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode); +extern int cellKbGetInfo(u32 info_addr); +extern int cellKbRead(u32 port_no, u32 data_addr); +extern int cellKbSetCodeType(u32 port_no, u32 type); +extern int cellKbSetLEDStatus(u32 port_no, u8 led); +extern int cellKbSetReadMode(u32 port_no, u32 rmode); +extern int cellKbGetConfiguration(u32 port_no, u32 config_addr); + //cellGcm extern int cellGcmCallback(u32 context_addr, u32 count); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Keyboard.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Keyboard.cpp new file mode 100644 index 0000000000..90073fe946 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_Keyboard.cpp @@ -0,0 +1,166 @@ +#include "stdafx.h" +#include "Emu/Io/Keyboard.h" +#include "Emu/SysCalls/SysCalls.h" + +extern Module sys_io; + +enum CELL_KB_ERROR_CODE +{ + CELL_KB_ERROR_FATAL = 0x80121001, + CELL_KB_ERROR_INVALID_PARAMETER = 0x80121002, + CELL_KB_ERROR_ALREADY_INITIALIZED = 0x80121003, + CELL_KB_ERROR_UNINITIALIZED = 0x80121004, + CELL_KB_ERROR_RESOURCE_ALLOCATION_FAILED = 0x80121005, + CELL_KB_ERROR_READ_FAILED = 0x80121006, + CELL_KB_ERROR_NO_DEVICE = 0x80121007, + CELL_KB_ERROR_SYS_SETTING_FAILED = 0x80121008, +}; + +int cellKbInit(u32 max_connect) +{ + sys_io.Log("cellKbInit(max_connect=%d)", max_connect); + if(Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_ALREADY_INITIALIZED; + if(max_connect > 7) return CELL_KB_ERROR_INVALID_PARAMETER; + + Emu.GetKeyboardManager().Init(max_connect); + return CELL_OK; +} + +int cellKbEnd() +{ + sys_io.Log("cellKbEnd()"); + if(!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; + Emu.GetKeyboardManager().Close(); + return CELL_OK; +} + +int cellKbClearBuf(u32 port_no) +{ + sys_io.Log("cellKbClearBuf(port_no=%d)", port_no); + if(!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; + if(port_no >= Emu.GetKeyboardManager().GetKeyboards().GetCount()) return CELL_KB_ERROR_INVALID_PARAMETER; + + //? + + return CELL_OK; +} + +u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode) +{ + sys_io.Log("cellKbCnvRawCode(arrange=%d,mkey=%d,led=%d,rawcode=%d)", arrange, mkey, led, rawcode); + + // CELL_KB_RAWDAT + if ((rawcode >= 0x00 && rawcode <= 0x03) || rawcode == 0x29 || rawcode == 0x35 || + (rawcode >= 0x39 && rawcode <= 0x53) || rawcode == 0x65 || rawcode == 0x88 || + rawcode == 0x8A || rawcode == 0x8B) + { + return rawcode | 0x8000; + } + + // CELL_KB_NUMPAD + if (rawcode >= 0x59 && rawcode <= 0x61) return (rawcode - 0x28) | 0x4000; // '1' - '9' + if (rawcode == 0x62) return 0x30 | 0x4000; // '0' + if (rawcode == 0x53) return 0x00 | 0x4000; // 'Num Lock' + if (rawcode == 0x54) return 0x2F | 0x4000; // '/' + if (rawcode == 0x55) return 0x2A | 0x4000; // '*' + if (rawcode == 0x56) return 0x2D | 0x4000; // '-' + if (rawcode == 0x57) return 0x2B | 0x4000; // '+' + if (rawcode == 0x58) return 0x0A | 0x4000; // '\n' + + // ASCII + if (rawcode >= 0x04 && rawcode <= 0x1D) return rawcode + 0x3D; // 'A' - 'Z' + if (rawcode >= 0x1E && rawcode <= 0x26) return rawcode + 0x13; // '1' - '9' + if (rawcode == 0x27) return 0x30; // '0' + if (rawcode == 0x28) return 0x0A; // '\n' + if (rawcode == 0x2B) return 0x09; // '\t' + if (rawcode == 0x2C) return 0x20; // ' ' + if (rawcode == 0x2D) return 0x2D; // '-' + if (rawcode == 0x2E) return 0x3D; // '=' + + // (TODO: Add more cases) + + return 0x0000; +} + +int cellKbGetInfo(u32 info_addr) +{ + sys_io.Log("cellKbGetInfo(info_addr=0x%x)", info_addr); + if(!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; + + const KbInfo& current_info = Emu.GetKeyboardManager().GetInfo(); + mem_class_t info(info_addr); + info += current_info.max_connect; + info += current_info.now_connect; + info += current_info.info; + for(u32 i=0; i& keyboards = Emu.GetKeyboardManager().GetKeyboards(); + if(!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; + if(port_no >= keyboards.GetCount()) return CELL_KB_ERROR_INVALID_PARAMETER; + + CellKbData& current_data = Emu.GetKeyboardManager().GetData(port_no); + + mem_class_t data(data_addr); + data += current_data.led; + data += current_data.mkey; + data += min((u32)current_data.len, CELL_KB_MAX_KEYCODES); + for(s32 i=0; iAppend("Windows"); //cbox_pad_handler->Append("DirectInput"); + cbox_keyboard_handler->Append("Null"); + cbox_keyboard_handler->Append("Windows"); + //cbox_pad_handler->Append("DirectInput"); + chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0); @@ -322,6 +328,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) cbox_gs_resolution->SetSelection(ResolutionIdToNum(Ini.GSResolution.GetValue()) - 1); cbox_gs_aspect->SetSelection(Ini.GSAspectRatio.GetValue() - 1); cbox_pad_handler->SetSelection(Ini.PadHandlerMode.GetValue()); + cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue()); s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); @@ -335,7 +342,9 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) s_round_gs->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5)); s_round_pad_handler->Add(cbox_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_keyboard_handler->Add(cbox_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_pad->Add(s_round_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_pad->Add(s_round_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); @@ -359,6 +368,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1); Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue()); Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection()); + Ini.KeyboardHandlerMode.SetValue(cbox_keyboard_handler->GetSelection()); Ini.Save(); } diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 829db83c46..e9b2c92652 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -98,6 +98,7 @@ public: IniEntry GSAspectRatio; IniEntry GSVSyncEnable; IniEntry PadHandlerMode; + IniEntry KeyboardHandlerMode; public: Inis() : DefPath("EmuSettings") @@ -113,8 +114,9 @@ public: GSAspectRatio.Init("AspectRatio", path); GSVSyncEnable.Init("VSyncEnable", path); - path = DefPath + "\\" + "Pad"; - PadHandlerMode.Init("HandlerMode", path); + path = DefPath + "\\" + "IO"; + PadHandlerMode.Init("PadHandlerMode", path); + KeyboardHandlerMode.Init("KeyboardHandlerMode", path); } void Load() @@ -125,6 +127,7 @@ public: GSAspectRatio.Load(1); GSVSyncEnable.Load(false); PadHandlerMode.Load(0); + KeyboardHandlerMode.Load(0); } void Save() @@ -135,6 +138,7 @@ public: GSAspectRatio.Save(); GSVSyncEnable.Save(); PadHandlerMode.Save(); + KeyboardHandlerMode.Save(); } }; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index fe1af9b6ff..637e88a80a 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -221,6 +221,7 @@ + @@ -230,6 +231,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 09c648cf32..7a15323230 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -295,6 +295,12 @@ Emu\SysCalls\Modules + + Emu\Io + + + Emu\SysCalls\lv2 +