diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/OpenRGB.iml b/.idea/OpenRGB.iml new file mode 100644 index 000000000..bc2cd8740 --- /dev/null +++ b/.idea/OpenRGB.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..16eb6d542 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..35eb1ddfb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Controllers/A4TechController/A4Tech_Detector.cpp b/Controllers/A4TechController/A4TechDetector.cpp similarity index 55% rename from Controllers/A4TechController/A4Tech_Detector.cpp rename to Controllers/A4TechController/A4TechDetector.cpp index 5e576ff72..a537b2f55 100644 --- a/Controllers/A4TechController/A4Tech_Detector.cpp +++ b/Controllers/A4TechController/A4TechDetector.cpp @@ -1,3 +1,13 @@ +/*-------------------------------------------------------------------*\ +| A4TechDetector.cpp | +| | +| Driver for A4Tech Devices Detector | +| | +| Chris M (Dr_No) 30 Jun 2022 | +| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 | +| | +\*-------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ | OpenRGB includes | \*-----------------------------------------------------*/ @@ -5,10 +15,13 @@ #include "Detector.h" #include "RGBController.h" + /*-----------------------------------------------------*\ | A4 Tech specific includes | \*-----------------------------------------------------*/ #include "RGBController_BloodyMouse.h" +#include "BloodyB820RController.h" +#include "RGBController_BloodyB820R.h" /*-----------------------------------------------------*\ | A4 Tech USB vendor ID | @@ -29,6 +42,23 @@ void DetectA4TechMouseControllers(hid_device_info* info, const std::string& name } } +void DetectBloodyB820R(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + BloodyB820RController* controller = new BloodyB820RController(dev, info->path); + RGBController_BloodyB820R* rgb_controller = new RGBController_BloodyB820R(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + + REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529); REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D); REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009); + +REGISTER_HID_DETECTOR_IPU("A4Tech Bloody B820R", DetectBloodyB820R, A4_TECH_VID, BLOODY_B820R_PID, 2, 0xFF52, 0x0210); diff --git a/Controllers/A4TechController/BloodyB820RController.cpp b/Controllers/A4TechController/BloodyB820RController.cpp new file mode 100644 index 000000000..f8d3b070b --- /dev/null +++ b/Controllers/A4TechController/BloodyB820RController.cpp @@ -0,0 +1,274 @@ +/*-------------------------------------------------------------------*\ +| BloodyB820RController.cpp | +| | +| Driver for A4Tech Bloody B820R Keyboard Controller | +| | +| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 | +| | +\*-------------------------------------------------------------------*/ + +#include "LogManager.h" +#include "BloodyB820RController.h" + +static uint8_t map_layout1[58][2] = { + {6}, + {7}, + {8}, + {9}, + {10}, + {11}, + {12}, + {13}, + {14}, + {15}, + {16}, + {17}, + {18}, + {19}, + {20}, + {21}, + {22}, + {23}, + {24}, + {25}, + {26}, + {27}, + {28}, + {29}, + {30}, + {31}, + {32}, + {33}, + {34}, + {35}, + {36}, + {37}, + {38}, + {39}, + {40}, + {41}, + {42}, + {43}, + {44}, + {45}, + {46}, + {47}, + {48}, + {49}, + {50}, + {51}, + {52}, + {53}, + {54}, + {55}, + {56}, + {57}, + {58}, + {59}, + {60}, + {61}, + {62}, + {63} +}; + +static uint8_t map_layout2[58][2] = { + {6}, + {7}, + {8}, + {9}, + {10}, + {11}, + {12}, + {13}, + {14}, + {15}, + {16}, + {17}, + {18}, + {19}, + {20}, + {21}, + {22, 55}, + {23}, + {24}, + {25}, + {26}, + {27}, + {28}, + {29}, + {30}, + {31}, + {32}, + {33}, + {34}, + {35}, + {36}, + {37}, + {38}, + {39}, + {40}, + {41}, + {42}, + {43}, + {44}, + {45}, + {46}, + {47}, + {48}, + {49}, + {50}, + {51}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} +}; + + +BloodyB820RController::BloodyB820RController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + InitDevice(); +} + +BloodyB820RController::~BloodyB820RController() +{ + hid_close(dev); +} + +std::string BloodyB820RController::GetDeviceName() +{ + const int szTemp = HID_MAX_STR; + wchar_t tmpName[szTemp]; + + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + std::string name = std::string(wName.begin(), wName.end()); + + return name; +} + +std::string BloodyB820RController::GetSerial() +{ + const int szTemp = HID_MAX_STR; + wchar_t tmpName[szTemp]; + + hid_get_serial_number_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + std::string serial = std::string(wName.begin(), wName.end()); + + return serial; +} + +std::string BloodyB820RController::GetLocation() +{ + return("HID: " + location); +} + +void BloodyB820RController::InitDevice() +{ + uint8_t buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }; + + hid_send_feature_report(dev, buffer, BLOODY_B820R_PACKET_SIZE); + + buffer[BLOODY_B820R_MODE_BYTE] = 0; + buffer[BLOODY_B820R_DATA_BYTE] = 1; + + hid_send_feature_report(dev, buffer, BLOODY_B820R_PACKET_SIZE); +} + +void BloodyB820RController::ReleaseDevice() +{ + uint8_t buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }; + + hid_send_feature_report(dev, buffer, BLOODY_B820R_PACKET_SIZE); + + buffer[BLOODY_B820R_MODE_BYTE] = 0; + + hid_send_feature_report(dev, buffer, BLOODY_B820R_PACKET_SIZE); +} + +void BloodyB820RController::SetMode( + int mode, + int speed, + unsigned char brightness, + unsigned char dir, + unsigned char red, + unsigned char green, + unsigned char blue) { + + + switch (mode) { + case BLOODY_B820R_MODE_DIRECT: + case BLOODY_B820R_MODE_INIT: + InitDevice(); + break; + case BLOODY_B820R_MODE_RELEASE: + ReleaseDevice(); + break; + default: + break; + } + +} + +void BloodyB820RController::SetLEDDirect(std::vector colors) +{ + + uint8_t R1Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x07, 0x00, 0x00 }; + uint8_t R2Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x08, 0x00, 0x00 }; + uint8_t G1Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x09, 0x00, 0x00 }; + uint8_t G2Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x0a, 0x00, 0x00 }; + uint8_t B1Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x0b, 0x00, 0x00 }; + uint8_t B2Buffer[BLOODY_B820R_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x0c, 0x00, 0x00 }; + + /*-----------------------------------------------------------------*\ + | Set up Direct packet | + | packet_map is the index of the Key from full_matrix_map and | + | the value is the position in the direct packet buffer | + \*-----------------------------------------------------------------*/ + + + for(size_t i = 0; i < colors.size(); i++) + { + RGBColor key = colors[i]; + + + size_t layout1_length = sizeof(map_layout1) / sizeof(map_layout1[0]); + + if (i < layout1_length) { + for(auto j : map_layout1[i]) { + if (j != 0) { + R1Buffer[j] = RGBGetRValue(key); + G1Buffer[j] = RGBGetGValue(key); + B1Buffer[j] = RGBGetBValue(key); + } + } + } else { + for(auto j : map_layout2[i - layout1_length]) { + if (j != 0) { + R2Buffer[j] = RGBGetRValue(key); + G2Buffer[j] = RGBGetGValue(key); + B2Buffer[j] = RGBGetBValue(key); + } + } + } + } + + hid_send_feature_report(dev, R1Buffer, BLOODY_B820R_PACKET_SIZE); + hid_send_feature_report(dev, R2Buffer, BLOODY_B820R_PACKET_SIZE); + hid_send_feature_report(dev, G1Buffer, BLOODY_B820R_PACKET_SIZE); + hid_send_feature_report(dev, G2Buffer, BLOODY_B820R_PACKET_SIZE); + hid_send_feature_report(dev, B1Buffer, BLOODY_B820R_PACKET_SIZE); + hid_send_feature_report(dev, B2Buffer, BLOODY_B820R_PACKET_SIZE); +} \ No newline at end of file diff --git a/Controllers/A4TechController/BloodyB820RController.h b/Controllers/A4TechController/BloodyB820RController.h new file mode 100644 index 000000000..b3730c459 --- /dev/null +++ b/Controllers/A4TechController/BloodyB820RController.h @@ -0,0 +1,55 @@ +/*-------------------------------------------------------------------*\ +| BloodyB820RController.h | +| | +| Driver for A4Tech Bloody B820R Keyboard Controller | +| | +| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 | +| | +\*-------------------------------------------------------------------*/ + +#include +#include +#include "RGBController.h" + +#pragma once + +#define NA 0xFFFFFFFF +#define HID_MAX_STR 255 + +#define BLOODY_B820R_PACKET_SIZE 64 +#define BLOODY_B820R_KEYCOUNT 104 +#define BLOODY_B820R_MODE_BYTE 3 +#define BLOODY_B820R_DATA_BYTE 8 + +/*---------------------------------------------------------*\ +| Bloody B820R product ID | +\*---------------------------------------------------------*/ +#define BLOODY_B820R_PID 0xFA10 + +enum +{ + BLOODY_B820R_MODE_DIRECT = 0x01, // Direct LED control - Independently set LEDs in zone + BLOODY_B820R_MODE_RELEASE = 0x02, // Release the OpenRGB control from the keyboard + BLOODY_B820R_MODE_INIT = 0x03, // Regain the OpenRGB control of the keyboard + BLOODY_B820R_MODE_BREATHING = 0x04, // Set breathing RGB effect +}; + +class BloodyB820RController +{ +public: + BloodyB820RController(hid_device* dev_handle, const char* path); + ~BloodyB820RController(); + + std::string GetDeviceName(); + std::string GetSerial(); + std::string GetLocation(); + + void SetLEDDirect(std::vector colors); + void SetMode(int mode, int speed, unsigned char brightness, unsigned char dir, unsigned char red, unsigned char green, unsigned char blue); +private: + std::string location; + hid_device* dev; + + void InitDevice(); + void ReleaseDevice(); +}; diff --git a/Controllers/A4TechController/RGBController_BloodyB820R.cpp b/Controllers/A4TechController/RGBController_BloodyB820R.cpp new file mode 100644 index 000000000..8b3c3646e --- /dev/null +++ b/Controllers/A4TechController/RGBController_BloodyB820R.cpp @@ -0,0 +1,281 @@ +/*-------------------------------------------------------------------*\ +| RGBController_BloodyB820R.cpp | +| | +| Driver for A4Tech Bloody B820R Keyboard Controller | +| | +| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 | +| | +\*-------------------------------------------------------------------*/ + +#include "RGBControllerKeyNames.h" +#include "RGBController_BloodyB820R.h" + +static unsigned int matrix_map[6][21] = + { + {0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, NA, NA, NA, NA, 13, 14, 15}, + {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}, + {37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57}, + {58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, NA, NA, NA, NA, 71, 72, 73, NA}, + {74, NA, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, NA, NA, 86, NA, 87, 88, 89, 90}, + {91, 92, 93, 94, NA, NA, NA, NA, NA, NA, 95, 96, 97, 98, 99, 100, 101, 102, NA, 103, NA}, + }; + +static const char *led_names[] = + { + KEY_EN_ESCAPE, //00 + KEY_EN_F1, + KEY_EN_F2, + KEY_EN_F3, + KEY_EN_F4, + KEY_EN_F5, + KEY_EN_F6, + KEY_EN_F7, + KEY_EN_F8, + KEY_EN_F9, + KEY_EN_F10, //10 + KEY_EN_F11, + KEY_EN_F12, + KEY_EN_PRINT_SCREEN, + KEY_EN_SCROLL_LOCK, + KEY_EN_PAUSE_BREAK, + + KEY_EN_BACK_TICK, + KEY_EN_1, + KEY_EN_2, + KEY_EN_3, + KEY_EN_4, //20 + KEY_EN_5, + KEY_EN_6, + KEY_EN_7, + KEY_EN_8, + KEY_EN_9, + KEY_EN_0, + KEY_EN_MINUS, + KEY_EN_EQUALS, + KEY_EN_BACKSPACE, + KEY_EN_INSERT, //30 + KEY_EN_HOME, + KEY_EN_PAGE_UP, + KEY_EN_NUMPAD_LOCK, + KEY_EN_NUMPAD_DIVIDE, + KEY_EN_NUMPAD_TIMES, + KEY_EN_NUMPAD_MINUS, + + KEY_EN_TAB, + KEY_EN_Q, + KEY_EN_W, + KEY_EN_E, + KEY_EN_R, + KEY_EN_T, + KEY_EN_Y, + KEY_EN_U, //40 + KEY_EN_I, + KEY_EN_O, + KEY_EN_P, + KEY_EN_LEFT_BRACKET, + KEY_EN_RIGHT_BRACKET, + KEY_EN_ANSI_BACK_SLASH, + KEY_EN_DELETE, + KEY_EN_END, + KEY_EN_PAGE_DOWN, + KEY_EN_NUMPAD_7, + KEY_EN_NUMPAD_8, + KEY_EN_NUMPAD_9, + KEY_EN_NUMPAD_PLUS, + + KEY_EN_CAPS_LOCK, //50 + KEY_EN_A, + KEY_EN_S, + KEY_EN_D, + KEY_EN_F, + KEY_EN_G, + KEY_EN_H, + KEY_EN_J, + KEY_EN_K, + KEY_EN_L, + KEY_EN_SEMICOLON, //60 + KEY_EN_QUOTE, + KEY_EN_ANSI_ENTER, + KEY_EN_NUMPAD_4, + KEY_EN_NUMPAD_5, + KEY_EN_NUMPAD_6, + + KEY_EN_LEFT_SHIFT, + KEY_EN_Z, + KEY_EN_X, + KEY_EN_C, + KEY_EN_V, + KEY_EN_B, + KEY_EN_N, + KEY_EN_M, //70 + KEY_EN_COMMA, + KEY_EN_PERIOD, + KEY_EN_FORWARD_SLASH, + KEY_EN_RIGHT_SHIFT, + KEY_EN_UP_ARROW, + KEY_EN_NUMPAD_1, + KEY_EN_NUMPAD_2, + KEY_EN_NUMPAD_3, + KEY_EN_NUMPAD_ENTER, + + KEY_EN_LEFT_CONTROL, + KEY_EN_LEFT_WINDOWS, + KEY_EN_LEFT_ALT, + KEY_EN_SPACE, + KEY_EN_RIGHT_ALT, //80 + KEY_EN_RIGHT_FUNCTION, + KEY_EN_MENU, + KEY_EN_RIGHT_CONTROL, + KEY_EN_LEFT_ARROW, + KEY_EN_DOWN_ARROW, + KEY_EN_RIGHT_ARROW, + KEY_EN_NUMPAD_0, + KEY_EN_NUMPAD_PERIOD + }; + +/**------------------------------------------------------------------*\ + @name A4Tech Bloody B820R + @category Keyboard + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors A4TechDetector + @comment The A4Tech Bloody B820R keyboard controller currently + supports the full size (ANSI layout). +\*-------------------------------------------------------------------*/ + +RGBController_BloodyB820R::RGBController_BloodyB820R(BloodyB820RController *controller_ptr) +{ + controller = controller_ptr; + + name = "Bloody B820R"; + vendor = "A4Tech"; + type = DEVICE_TYPE_KEYBOARD; + description = "Contributed by Mohammed Julfikar Ali Mahbub (github.com/o-julfikar)"; + serial = controller->GetSerial(); + location = controller->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = BLOODY_B820R_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Init; + Init.name = "Init"; + Init.value = BLOODY_B820R_MODE_INIT; + Init.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Init.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Init); + + mode Release; + Release.name = "Release Control"; + Release.value = BLOODY_B820R_MODE_RELEASE; + Release.flags = 0; + Release.color_mode = MODE_COLORS_NONE; + modes.push_back(Release); + + SetupZones(); +} + +RGBController_BloodyB820R::~RGBController_BloodyB820R() +{ + delete controller; +} + +void RGBController_BloodyB820R::SetupZones() +{ + /*-------------------------------------------------*\ + | Create the Keyboard zone and add the matrix map | + \*-------------------------------------------------*/ + zone KB_zone; + KB_zone.name = ZONE_EN_KEYBOARD; + KB_zone.type = ZONE_TYPE_MATRIX; + KB_zone.leds_min = BLOODY_B820R_KEYCOUNT; + KB_zone.leds_max = BLOODY_B820R_KEYCOUNT; + KB_zone.leds_count = BLOODY_B820R_KEYCOUNT; + + KB_zone.matrix_map = new matrix_map_type; + KB_zone.matrix_map->height = 6; + KB_zone.matrix_map->width = 21; + KB_zone.matrix_map->map = (unsigned int *)&matrix_map; + zones.push_back(KB_zone); + + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + for(std::size_t zone_index = 0; zone_index < zones.size(); zone_index++) + { + for(unsigned int led_index = 0; led_index < zones[zone_index].leds_count; led_index++) + { + led new_led; + new_led.name = led_names[led_index]; + new_led.value = led_index; + leds.push_back(new_led); + } + } + + SetupColors(); +} + +void RGBController_BloodyB820R::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + + +void RGBController_BloodyB820R::DeviceUpdateLEDs() +{ + controller->SetLEDDirect(colors); +} + +void RGBController_BloodyB820R::UpdateZoneLEDs(int zone) +{ + std::vector colour; + for(size_t i = 0; i < zones[zone].leds_count; i++) + { + colour.push_back(zones[zone].colors[i]); + } + + controller->SetLEDDirect(colour); +} + +void RGBController_BloodyB820R::UpdateSingleLED(int led) +{ + std::vector colour; + colour.push_back(colors[led]); + + controller->SetLEDDirect(colour); +} + +void RGBController_BloodyB820R::DeviceUpdateMode() +{ + unsigned char red = 0; + unsigned char grn = 0; + unsigned char blu = 0; + unsigned char dir = 0; + + if(modes[active_mode].color_mode & MODE_COLORS_MODE_SPECIFIC) + { + red = RGBGetRValue(modes[active_mode].colors[0]); + grn = RGBGetGValue(modes[active_mode].colors[0]); + blu = RGBGetBValue(modes[active_mode].colors[0]); + } + + if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) + { + dir = (unsigned char)modes[active_mode].direction; + } + + controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, dir, red, grn, blu); +} diff --git a/Controllers/A4TechController/RGBController_BloodyB820R.h b/Controllers/A4TechController/RGBController_BloodyB820R.h new file mode 100644 index 000000000..2e50110f4 --- /dev/null +++ b/Controllers/A4TechController/RGBController_BloodyB820R.h @@ -0,0 +1,33 @@ +/*-------------------------------------------------------------------*\ +| RGBController_BloodyB820R.h | +| | +| Driver for A4Tech Bloody B820R Keyboard Controller | +| | +| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 | +| | +\*-------------------------------------------------------------------*/ + +#pragma once +#include "LogManager.h" +#include "RGBController.h" +#include "BloodyB820RController.h" +#include + +class RGBController_BloodyB820R : public RGBController +{ +public: + RGBController_BloodyB820R(BloodyB820RController* controller_ptr); + ~RGBController_BloodyB820R(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + BloodyB820RController* controller; +};