diff --git a/Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.cpp b/Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.cpp index 72920c8c..3623ab48 100644 --- a/Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.cpp +++ b/Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.cpp @@ -112,6 +112,9 @@ void RGBController_RoccatVulcanKeyboard::SetupZones() case ROCCAT_VULCAN_TKL_PID: keyboard_ptr = &RoccatVulcanTKLLayouts; break; + case ROCCAT_PYRO_PID: + keyboard_ptr = &RoccatPyroLayouts; + break; case ROCCAT_MAGMA_PID: case ROCCAT_MAGMA_MINI_PID: keyboard_ptr = &RoccatMagmaLayouts; diff --git a/Controllers/RoccatController/RoccatControllerDetect.cpp b/Controllers/RoccatController/RoccatControllerDetect.cpp index deb9b926..2fc70bff 100644 --- a/Controllers/RoccatController/RoccatControllerDetect.cpp +++ b/Controllers/RoccatController/RoccatControllerDetect.cpp @@ -94,8 +94,22 @@ void DetectRoccatVulcanKeyboardControllers(hid_device_info* info, const std::str std::string dev_ctrl_path; std::string dev_led_path; - int dev_led_page = (info->product_id == ROCCAT_MAGMA_PID || info->product_id == ROCCAT_MAGMA_MINI_PID) ? 0xFF00 : 0x0001; - int dev_ctrl_page = (info->product_id == ROCCAT_MAGMA_PID || info->product_id == ROCCAT_MAGMA_MINI_PID) ? 0xFF01 : 0x000B; + int dev_led_page; + int dev_ctrl_page; + + switch (info->product_id) + { + case ROCCAT_PYRO_PID: + case ROCCAT_MAGMA_PID: + case ROCCAT_MAGMA_MINI_PID: + dev_led_page = 0xFF00; + dev_ctrl_page = 0xFF01; + break; + default: + dev_led_page = 0x0001; + dev_ctrl_page = 0x000B; + break; + } while(info_temp) { @@ -257,6 +271,7 @@ REGISTER_HID_DETECTOR_IPU("Roccat Horde Aimo", DetectRoccatHordeAim REGISTER_HID_DETECTOR_IP ("Roccat Magma", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_MAGMA_PID, 1, 0xFF01); REGISTER_HID_DETECTOR_IP ("Roccat Magma Mini", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_MAGMA_MINI_PID, 1, 0xFF01); +REGISTER_HID_DETECTOR_IP ("Roccat Pyro", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_PYRO_PID, 1, 0xFF01); REGISTER_HID_DETECTOR_IP ("Roccat Vulcan 100 Aimo", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_VULCAN_100_AIMO_PID, 1, 11); REGISTER_HID_DETECTOR_IP ("Roccat Vulcan 120-Series Aimo", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_VULCAN_120_AIMO_PID, 1, 11); REGISTER_HID_DETECTOR_IP ("Roccat Vulcan TKL", DetectRoccatVulcanKeyboardControllers, ROCCAT_VID, ROCCAT_VULCAN_TKL_PID, 1, 11); diff --git a/Controllers/RoccatController/RoccatVulcanKeyboardController.cpp b/Controllers/RoccatController/RoccatVulcanKeyboardController.cpp index 4b5d956b..1d2277bf 100644 --- a/Controllers/RoccatController/RoccatVulcanKeyboardController.cpp +++ b/Controllers/RoccatController/RoccatVulcanKeyboardController.cpp @@ -61,6 +61,7 @@ device_info RoccatVulcanKeyboardController::InitDeviceInfo() switch(device_pid) { + case ROCCAT_PYRO_PID: case ROCCAT_MAGMA_PID: case ROCCAT_MAGMA_MINI_PID: packet_length = 9; @@ -112,6 +113,7 @@ void RoccatVulcanKeyboardController::EnableDirect(bool on_off_switch) uint8_t* buf; switch(device_pid) { + case ROCCAT_PYRO_PID: case ROCCAT_MAGMA_PID: case ROCCAT_MAGMA_MINI_PID: buf = new uint8_t[5] { 0x0E, 0x05, on_off_switch, 0x00, 0x00 }; @@ -128,7 +130,7 @@ void RoccatVulcanKeyboardController::SendColors(std::vector colors) { unsigned short packet_length; unsigned char column_length; - unsigned char header_length = 0; + unsigned char protocol_version; switch(device_pid) { @@ -136,10 +138,17 @@ void RoccatVulcanKeyboardController::SendColors(std::vector colors) case ROCCAT_MAGMA_MINI_PID: packet_length = 64; column_length = 5; + protocol_version = 2; + break; + case ROCCAT_PYRO_PID: + packet_length = 378; + column_length = 1; + protocol_version = 2; break; default: packet_length = 436; column_length = 12; + protocol_version = 1; } unsigned char packet_num = ceil((float) packet_length / 64); @@ -152,8 +161,19 @@ void RoccatVulcanKeyboardController::SendColors(std::vector colors) memset(&bufs[p][0], 0x00, sizeof(bufs[p][0]) * bufs[p].size()); } - bufs[0][1] = 0xA1; - bufs[0][2] = 0x01; + if(protocol_version > 1) + { + for(unsigned int i = 0; i < packet_num; i++) + { + bufs[i][1] = 0xA1; + bufs[i][2] = i + 1; + } + } + else + { + bufs[0][1] = 0xA1; + bufs[0][2] = 0x01; + } unsigned char header_length_first = (packet_length > 255) ? 4 : 3; @@ -163,26 +183,58 @@ void RoccatVulcanKeyboardController::SendColors(std::vector colors) } else { - bufs[0][3] = packet_length / 256; - bufs[0][4] = packet_length % 256; + if(protocol_version > 1) + { + bufs[0][3] = packet_length % 256; + bufs[0][4] = packet_length / 256; + } + else + { + bufs[0][3] = packet_length / 256; + bufs[0][4] = packet_length % 256; + } } - unsigned int data_length_packet = 64 - header_length; - for(unsigned int i = 0; i < colors.size(); i++) { int coloumn = floor(colors[i].value / column_length); int row = colors[i].value % column_length; - int offset = coloumn * 3 * column_length + row + header_length_first; + /*-----------------------------------------------------------------------*\ + | This has to be split up for readability. | + | This assumes that the header for each packet besides the first | + | is either 0 bytes long (protocol v1) or as long as the first one (v2). | + | This currently covers all keyboards. | + | A solution unified solution that can handle general header length | + | independent of the first header would be desirable, but seems | + | too complicated for now. | + \*-----------------------------------------------------------------------*/ + if(protocol_version == 1) + { + int offset = coloumn * 3 * column_length + row + header_length_first; - bufs[offset / data_length_packet][offset % data_length_packet + header_length + 1] = RGBGetRValue(colors[i].color); + bufs[offset / 64][offset % 64 + 1] = RGBGetRValue(colors[i].color); - offset += column_length; - bufs[offset / data_length_packet][offset % data_length_packet + header_length + 1] = RGBGetGValue(colors[i].color); + offset += column_length; + bufs[offset / 64][offset % 64 + 1] = RGBGetGValue(colors[i].color); - offset += column_length; - bufs[offset / data_length_packet][offset % data_length_packet + header_length + 1] = RGBGetBValue(colors[i].color); + offset += column_length; + bufs[offset / 64][offset % 64 + 1] = RGBGetBValue(colors[i].color); + } + else + { + unsigned int data_length_packet = 64 - header_length_first; + + int offset = coloumn * 3 * column_length + row; + + bufs[offset / data_length_packet][offset % data_length_packet + header_length_first + 1] = RGBGetRValue(colors[i].color); + + offset += column_length; + bufs[offset / data_length_packet][offset % data_length_packet + header_length_first + 1] = RGBGetGValue(colors[i].color); + + offset += column_length; + bufs[offset / data_length_packet][offset % data_length_packet + header_length_first + 1] = RGBGetBValue(colors[i].color); + } } for(int p = 0; p < packet_num; p++) @@ -206,6 +258,11 @@ void RoccatVulcanKeyboardController::SendMode(unsigned int mode, unsigned int sp switch(device_pid) { + case ROCCAT_PYRO_PID: + protocol_version = 2; + packet_length = 365; + column_length = 1; + break; case ROCCAT_MAGMA_PID: case ROCCAT_MAGMA_MINI_PID: protocol_version = 2; @@ -291,6 +348,7 @@ void RoccatVulcanKeyboardController::WaitUntilReady() switch(device_pid) { + case ROCCAT_PYRO_PID: case ROCCAT_MAGMA_PID: case ROCCAT_MAGMA_MINI_PID: packet_length = 4; diff --git a/Controllers/RoccatController/RoccatVulcanKeyboardController.h b/Controllers/RoccatController/RoccatVulcanKeyboardController.h index 54ca0a60..4cbc23a5 100644 --- a/Controllers/RoccatController/RoccatVulcanKeyboardController.h +++ b/Controllers/RoccatController/RoccatVulcanKeyboardController.h @@ -20,6 +20,7 @@ enum ROCCAT_VULCAN_100_AIMO_PID = 0x307A, ROCCAT_VULCAN_120_AIMO_PID = 0x3098, ROCCAT_VULCAN_TKL_PID = 0x2FEE, + ROCCAT_PYRO_PID = 0x314C, ROCCAT_MAGMA_PID = 0x3124, ROCCAT_MAGMA_MINI_PID = 0x69A0, }; @@ -29,7 +30,13 @@ enum ROCCAT_VULCAN_MODE_DIRECT = 0x0B, ROCCAT_VULCAN_MODE_STATIC = 0x01, ROCCAT_VULCAN_MODE_WAVE = 0x0A, - ROCCAT_VULCAN_MODE_DEFAULT = 0x00, + /*-------------------------------------------------------------------*\ + | This mode is not a real mode, it's just the default mode when | + | a mode is software generated, but Swarm is inactive, hence it has | + | no id. Unfortunately 0 is refused by some keyboards, so 2 seems | + | like a good choice as it is not used anywhere else | + \*-------------------------------------------------------------------*/ + ROCCAT_VULCAN_MODE_DEFAULT = 0x02, }; enum diff --git a/Controllers/RoccatController/RoccatVulcanKeyboardLayouts.h b/Controllers/RoccatController/RoccatVulcanKeyboardLayouts.h index f914ff51..c72eb56d 100644 --- a/Controllers/RoccatController/RoccatVulcanKeyboardLayouts.h +++ b/Controllers/RoccatController/RoccatVulcanKeyboardLayouts.h @@ -363,6 +363,283 @@ static std::map RoccatVulcan120AimoLayouts = }, }; +static std::map RoccatPyroLayouts = +{ + { + ROCCAT_VULCAN_LAYOUT_UK, + { + *ROCCAT_VULCAN_120_AIMO_LAYOUT_KEYS_105, + 105, + 6, + 24, + { + { KEY_EN_ESCAPE, 0x02 }, + { KEY_EN_BACK_TICK, 0x03 }, + { KEY_EN_TAB, 0x04 }, + { KEY_EN_CAPS_LOCK, 0x05 }, + { KEY_EN_LEFT_SHIFT, 0x00 }, + { KEY_EN_LEFT_CONTROL, 0x01 }, + + { KEY_EN_1, 0x08 }, + { KEY_EN_ISO_BACK_SLASH, 0x06 }, + { KEY_EN_LEFT_WINDOWS, 0x07 }, + + { KEY_EN_F1, 0x0D }, + { KEY_EN_2, 0x0E }, + { KEY_EN_Q, 0x09 }, + { KEY_EN_A, 0x0A }, + { KEY_EN_Z, 0x0B }, + { KEY_EN_LEFT_ALT, 0x0C }, + + { KEY_EN_F2, 0x14 }, + { KEY_EN_3, 0x15 }, + { KEY_EN_W, 0x0F }, + { KEY_EN_S, 0x10 }, + { KEY_EN_X, 0x11 }, + + { KEY_EN_F3, 0x19 }, + { KEY_EN_4, 0x1A }, + { KEY_EN_E, 0x16 }, + { KEY_EN_D, 0x17 }, + { KEY_EN_C, 0x18 }, + + { KEY_EN_F4, 0x1E }, + { KEY_EN_5, 0x1F }, + { KEY_EN_R, 0x1B }, + { KEY_EN_F, 0x1C }, + { KEY_EN_V, 0x1D }, + + { KEY_EN_6, 0x24 }, + { KEY_EN_T, 0x20 }, + { KEY_EN_G, 0x21 }, + { KEY_EN_B, 0x22 }, + { KEY_EN_SPACE, 0x23 }, + + { KEY_EN_F5, 0x28 }, + { KEY_EN_7, 0x29 }, + { KEY_EN_Y, 0x25 }, + { KEY_EN_H, 0x26 }, + { KEY_EN_N, 0x27 }, + + { KEY_EN_F6, 0x2F }, + { KEY_EN_8, 0x30 }, + { KEY_EN_U, 0x2A }, + { KEY_EN_J, 0x2B }, + { KEY_EN_M, 0x2C }, + + { KEY_EN_F7, 0x35 }, + { KEY_EN_9, 0x36 }, + { KEY_EN_I, 0x31 }, + { KEY_EN_K, 0x32 }, + { KEY_EN_COMMA, 0x33 }, + + { KEY_EN_F8, 0x3B }, + { KEY_EN_0, 0x3C }, + { KEY_EN_O, 0x37 }, + { KEY_EN_L, 0x38 }, + { KEY_EN_PERIOD, 0x39 }, + { KEY_EN_RIGHT_ALT, 0x3A }, + + { KEY_EN_F9, 0x41 }, + { KEY_EN_MINUS, 0x42 }, + { KEY_EN_P, 0x3D }, + { KEY_EN_SEMICOLON, 0x3E }, + { KEY_EN_FORWARD_SLASH, 0x3F }, + { KEY_EN_RIGHT_FUNCTION, 0x40 }, + + { KEY_EN_F10, 0x47 }, + { KEY_EN_EQUALS, 0x48 }, + { KEY_EN_LEFT_BRACKET, 0x43 }, + { KEY_EN_QUOTE, 0x44 }, + { KEY_EN_MENU, 0x46 }, + + { KEY_EN_F11, 0x4D }, + { KEY_EN_BACKSPACE, 0x50 }, + { KEY_EN_RIGHT_BRACKET, 0x49 }, + { KEY_EN_POUND, 0x4A }, + { KEY_EN_RIGHT_SHIFT, 0x4B }, + + { KEY_EN_F12, 0x4F }, + { KEY_EN_ISO_ENTER, 0x52 }, + { KEY_EN_RIGHT_CONTROL, 0x4C }, + + { KEY_EN_PRINT_SCREEN, 0x53 }, + { KEY_EN_INSERT, 0x54 }, + { KEY_EN_DELETE, 0x55 }, + { KEY_EN_LEFT_ARROW, 0x56 }, + + { KEY_EN_SCROLL_LOCK, 0x57 }, + { KEY_EN_HOME, 0x58 }, + { KEY_EN_END, 0x59 }, + { KEY_EN_UP_ARROW, 0x5A }, + { KEY_EN_DOWN_ARROW, 0x5B }, + + { KEY_EN_PAUSE_BREAK, 0x5C }, + { KEY_EN_PAGE_UP, 0x5D }, + { KEY_EN_PAGE_DOWN, 0x5E }, + { KEY_EN_RIGHT_ARROW, 0x5F }, + + { KEY_EN_NUMPAD_LOCK, 0x61 }, + { KEY_EN_NUMPAD_7, 0x62 }, + { KEY_EN_NUMPAD_4, 0x63 }, + { KEY_EN_NUMPAD_1, 0x64 }, + { KEY_EN_NUMPAD_0, 0x65 }, + + { KEY_EN_NUMPAD_DIVIDE, 0x67 }, + { KEY_EN_NUMPAD_8, 0x68 }, + { KEY_EN_NUMPAD_5, 0x69 }, + { KEY_EN_NUMPAD_2, 0x6A }, + + { KEY_EN_NUMPAD_TIMES, 0x6C }, + { KEY_EN_NUMPAD_9, 0x6D }, + { KEY_EN_NUMPAD_6, 0x6E }, + { KEY_EN_NUMPAD_3, 0x6F }, + { KEY_EN_NUMPAD_PERIOD, 0x70 }, + + { KEY_EN_NUMPAD_MINUS, 0x72 }, + { KEY_EN_NUMPAD_PLUS, 0x73 }, + { KEY_EN_NUMPAD_ENTER, 0x75 } + } + } + }, + { + ROCCAT_VULCAN_LAYOUT_US, + { + *ROCCAT_VULCAN_120_AIMO_LAYOUT_KEYS_104, + 104, + 6, + 24, + { + { KEY_EN_ESCAPE, 0x02 }, + { KEY_EN_BACK_TICK, 0x03 }, + { KEY_EN_TAB, 0x04 }, + { KEY_EN_CAPS_LOCK, 0x05 }, + { KEY_EN_LEFT_SHIFT, 0x00 }, + { KEY_EN_LEFT_CONTROL, 0x01 }, + + { KEY_EN_1, 0x08 }, + { KEY_EN_LEFT_WINDOWS, 0x07 }, + + { KEY_EN_F1, 0x0D }, + { KEY_EN_2, 0x0E }, + { KEY_EN_Q, 0x09 }, + { KEY_EN_A, 0x0A }, + { KEY_EN_Z, 0x0B }, + { KEY_EN_LEFT_ALT, 0x0C }, + + { KEY_EN_F2, 0x14 }, + { KEY_EN_3, 0x15 }, + { KEY_EN_W, 0x0F }, + { KEY_EN_S, 0x10 }, + { KEY_EN_X, 0x11 }, + + { KEY_EN_F3, 0x19 }, + { KEY_EN_4, 0x1A }, + { KEY_EN_E, 0x16 }, + { KEY_EN_D, 0x17 }, + { KEY_EN_C, 0x18 }, + + { KEY_EN_F4, 0x1E }, + { KEY_EN_5, 0x1F }, + { KEY_EN_R, 0x1B }, + { KEY_EN_F, 0x1C }, + { KEY_EN_V, 0x1D }, + + { KEY_EN_6, 0x24 }, + { KEY_EN_T, 0x20 }, + { KEY_EN_G, 0x21 }, + { KEY_EN_B, 0x22 }, + { KEY_EN_SPACE, 0x23 }, + + { KEY_EN_F5, 0x28 }, + { KEY_EN_7, 0x29 }, + { KEY_EN_Y, 0x25 }, + { KEY_EN_H, 0x26 }, + { KEY_EN_N, 0x27 }, + + { KEY_EN_F6, 0x2F }, + { KEY_EN_8, 0x30 }, + { KEY_EN_U, 0x2A }, + { KEY_EN_J, 0x2B }, + { KEY_EN_M, 0x2C }, + + { KEY_EN_F7, 0x35 }, + { KEY_EN_9, 0x36 }, + { KEY_EN_I, 0x31 }, + { KEY_EN_K, 0x32 }, + { KEY_EN_COMMA, 0x33 }, + + { KEY_EN_F8, 0x3B }, + { KEY_EN_0, 0x3C }, + { KEY_EN_O, 0x37 }, + { KEY_EN_L, 0x38 }, + { KEY_EN_PERIOD, 0x39 }, + { KEY_EN_RIGHT_ALT, 0x3A }, + + { KEY_EN_F9, 0x41 }, + { KEY_EN_MINUS, 0x42 }, + { KEY_EN_P, 0x3D }, + { KEY_EN_SEMICOLON, 0x3E }, + { KEY_EN_FORWARD_SLASH, 0x3F }, + { KEY_EN_RIGHT_FUNCTION, 0x40 }, + + { KEY_EN_F10, 0x47 }, + { KEY_EN_EQUALS, 0x48 }, + { KEY_EN_LEFT_BRACKET, 0x43 }, + { KEY_EN_QUOTE, 0x44 }, + { KEY_EN_MENU, 0x46 }, + + { KEY_EN_F11, 0x4D }, + { KEY_EN_BACKSPACE, 0x50 }, + { KEY_EN_RIGHT_BRACKET, 0x49 }, + { KEY_EN_RIGHT_SHIFT, 0x4B }, + + { KEY_EN_F12, 0x4F }, + { KEY_EN_ANSI_BACK_SLASH, 0x51 }, + { KEY_EN_ANSI_ENTER, 0x52 }, + { KEY_EN_RIGHT_CONTROL, 0x4C }, + + { KEY_EN_PRINT_SCREEN, 0x53 }, + { KEY_EN_INSERT, 0x54 }, + { KEY_EN_DELETE, 0x55 }, + { KEY_EN_LEFT_ARROW, 0x56 }, + + { KEY_EN_SCROLL_LOCK, 0x57 }, + { KEY_EN_HOME, 0x58 }, + { KEY_EN_END, 0x59 }, + { KEY_EN_UP_ARROW, 0x5A }, + { KEY_EN_DOWN_ARROW, 0x5B }, + + { KEY_EN_PAUSE_BREAK, 0x5C }, + { KEY_EN_PAGE_UP, 0x5D }, + { KEY_EN_PAGE_DOWN, 0x5E }, + { KEY_EN_RIGHT_ARROW, 0x5F }, + + { KEY_EN_NUMPAD_LOCK, 0x61 }, + { KEY_EN_NUMPAD_7, 0x62 }, + { KEY_EN_NUMPAD_4, 0x63 }, + { KEY_EN_NUMPAD_1, 0x64 }, + { KEY_EN_NUMPAD_0, 0x65 }, + + { KEY_EN_NUMPAD_DIVIDE, 0x67 }, + { KEY_EN_NUMPAD_8, 0x68 }, + { KEY_EN_NUMPAD_5, 0x69 }, + { KEY_EN_NUMPAD_2, 0x6A }, + + { KEY_EN_NUMPAD_TIMES, 0x6C }, + { KEY_EN_NUMPAD_9, 0x6D }, + { KEY_EN_NUMPAD_6, 0x6E }, + { KEY_EN_NUMPAD_3, 0x6F }, + { KEY_EN_NUMPAD_PERIOD, 0x70 }, + + { KEY_EN_NUMPAD_MINUS, 0x72 }, + { KEY_EN_NUMPAD_PLUS, 0x73 }, + { KEY_EN_NUMPAD_ENTER, 0x75 } + } + } + }, +}; + static std::map RoccatVulcanTKLLayouts = { {