diff --git a/Controllers/AlienwareController/AlienwareController.cpp b/Controllers/AlienwareController/AlienwareController.cpp index 5210d9bb6..3f2a3e94e 100644 --- a/Controllers/AlienwareController/AlienwareController.cpp +++ b/Controllers/AlienwareController/AlienwareController.cpp @@ -32,6 +32,7 @@ static const std::map zone_quirks_table = { 0x0C01, 4 }, // Dell G5 SE 5505 { 0x0A01, 16 }, // Dell G7 15 7500 { 0x0E03, 4 }, // Dell G15 5511 + { 0x0E07, 4 }, // Dell G15 5520 { 0x0E0A, 4 } // Dell G15 5530 }; @@ -49,9 +50,21 @@ static const std::map> zone_name "Light Bar 7", "Light Bar 8", "Light Bar 9", "Light Bar 10", "Light Bar 11", "Light Bar 12" } }, { 0x0E03, { "Left", "Middle", "Right", "Numpad" } }, + { 0x0E07, { "Left", "Middle", "Right", "Numpad" } }, { 0x0E0A, { "Left", "Middle", "Right", "Numpad" } } }; +/*---------------------------------------------------------*\ +| Mapping the platform ID to the actual hardware zone IDs | +\*---------------------------------------------------------*/ +static const std::map> zone_ids_table = +{ + { 0x0C01, { 0x00, 0x01, 0x02, 0x03 } }, // Dell G5 SE 5505 + { 0x0E03, { 0x00, 0x01, 0x02, 0x03 } }, // Dell G15 5511 + { 0x0E07, { 0x10, 0x11, 0x12, 0x13 } }, // Dell G15 5520 + { 0x0E0A, { 0x10, 0x11, 0x12, 0x13 } } // Dell G15 5530 +}; + static void SendHIDReport(hid_device *dev, const unsigned char* usb_buf, size_t usb_buf_size) { using namespace std::chrono_literals; @@ -138,6 +151,21 @@ AlienwareController::AlienwareController(hid_device* dev_handle, const hid_devic } } + /*-----------------------------------------------------*\ + | Initialize hardware zone IDs | + \*-----------------------------------------------------*/ + if(zone_ids_table.count(platform_id)) + { + zone_ids = zone_ids_table.at(platform_id); + } + else + { + for(size_t i = 0; i < number_of_zones; i++) + { + zone_ids.push_back(static_cast(i)); + } + } + /*-----------------------------------------------------*\ | Set defaults for all zones | | It doesn't seem possible to read the controller's | @@ -155,6 +183,7 @@ AlienwareController::AlienwareController(hid_device* dev_handle, const hid_devic zones[zone_idx].period = 2000; zones[zone_idx].tempo = ALIENWARE_TEMPO_MAX; zones[zone_idx].dim = 0; + zones[zone_idx].direction = 0; } /*-----------------------------------------------------*\ @@ -673,6 +702,15 @@ void AlienwareController::SetDim(uint8_t zone, uint8_t dim) } } +void AlienwareController::SetDirection(uint8_t zone, uint8_t direction) +{ + if(zone < zones.size()) + { + zones[zone].direction = direction; + dirty = true; + } +} + void AlienwareController::UpdateDim() { if(!dirty_dim) @@ -688,7 +726,8 @@ void AlienwareController::UpdateDim() for(size_t i = 0; i < zones.size(); i++) { - dim_zone_map[zones[i].dim].emplace_back((uint8_t)i); + uint8_t hw_zone = (i < zone_ids.size()) ? zone_ids[i] : static_cast(i); + dim_zone_map[zones[i].dim].emplace_back(hw_zone); } for(std::pair> &pair : dim_zone_map) @@ -715,7 +754,8 @@ bool AlienwareController::UpdateDirect() for(size_t i = 0; i < zones.size(); i++) { - color_zone_map[zones[i].color[0]].emplace_back((uint8_t)i); + uint8_t hw_zone = (i < zone_ids.size()) ? zone_ids[i] : static_cast(i); + color_zone_map[zones[i].color[0]].emplace_back(hw_zone); } for(std::pair> &pair : color_zone_map) @@ -759,8 +799,9 @@ void AlienwareController::UpdateMode() for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { alienware_zone zone = zones[zone_idx]; + uint8_t hw_zone = (zone_idx < zone_ids.size()) ? zone_ids[zone_idx] : static_cast(zone_idx); - result = SelectZones({static_cast(zone_idx)}); + result = SelectZones({hw_zone}); if(!result) { @@ -783,18 +824,18 @@ void AlienwareController::UpdateMode() case ALIENWARE_MODE_MORPH: { - uint8_t zones[2] = { zone.mode, zone.mode }; + uint8_t modes[2] = { zone.mode, zone.mode }; uint16_t periods[2] = { zone.period, zone.period }; uint16_t tempos[2] = { zone.tempo, zone.tempo }; RGBColor colors[2] = { zone.color[0], zone.color[1] }; - result = MultiModeAction(zones, periods, tempos, colors, 2); + result = MultiModeAction(modes, periods, tempos, colors, 2); } break; case ALIENWARE_MODE_SPECTRUM: { - uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH }; @@ -807,13 +848,13 @@ void AlienwareController::UpdateMode() zone.tempo, zone.tempo, zone.tempo }; - result = MultiModeAction(zones, periods, tempos, rainbow_colors[0], 7); + result = MultiModeAction(modes, periods, tempos, rainbow_colors[0], 7); } break; case ALIENWARE_MODE_RAINBOW: { - uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH }; @@ -826,18 +867,19 @@ void AlienwareController::UpdateMode() zone.tempo, zone.tempo, zone.tempo }; - result = MultiModeAction(zones, periods, tempos, rainbow_colors[zone_idx], 7); + unsigned int color_idx = (zone.direction == MODE_DIRECTION_LEFT) ? (4 - 1 - (zone_idx % 4)) : (zone_idx % 4); + result = MultiModeAction(modes, periods, tempos, rainbow_colors[color_idx], 7); } break; case ALIENWARE_MODE_BREATHING: { - uint8_t zones[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH }; + uint8_t modes[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH }; uint16_t periods[2] = { zone.period, zone.period }; uint16_t tempos[2] = { zone.tempo, zone.tempo }; RGBColor colors[2] = { zone.color[0], 0x0 }; - result = MultiModeAction(zones, periods, tempos, colors, 2); + result = MultiModeAction(modes, periods, tempos, colors, 2); } break; @@ -864,6 +906,117 @@ void AlienwareController::UpdateMode() dirty = false; } +void AlienwareController::SaveController() +{ + /*-----------------------------------------------------*\ + | Save current mode configuration to EEPROM slot 0x0061 | + \*-----------------------------------------------------*/ + UserAnimation(ALIENWARE_COMMAND_USER_ANIM_REMOVE, ALIENWARE_ANIM_DEFAULT, 0); + bool result = UserAnimation(ALIENWARE_COMMAND_USER_ANIM_NEW, ALIENWARE_ANIM_DEFAULT, 0); + + if(!result) + { + return; + } + + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + alienware_zone zone = zones[zone_idx]; + uint8_t hw_zone = (zone_idx < zone_ids.size()) ? zone_ids[zone_idx] : static_cast(zone_idx); + + result = SelectZones({hw_zone}); + + if(!result) + { + return; + } + + switch (zone.mode) + { + case ALIENWARE_MODE_COLOR: + result = ModeAction(zone.mode, 2000, ALIENWARE_TEMPO_MAX, zone.color[0]); + break; + + case ALIENWARE_MODE_PULSE: + result = ModeAction(zone.mode, zone.period, zone.tempo, zone.color[0]); + break; + + case ALIENWARE_MODE_MORPH: + { + uint8_t modes[2] = { zone.mode, zone.mode }; + uint16_t periods[2] = { zone.period, zone.period }; + uint16_t tempos[2] = { zone.tempo, zone.tempo }; + RGBColor colors[2] = { zone.color[0], zone.color[1] }; + + result = MultiModeAction(modes, periods, tempos, colors, 2); + } + break; + + case ALIENWARE_MODE_SPECTRUM: + { + uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH }; + uint16_t periods[7] = { zone.period, zone.period, + zone.period, zone.period, + zone.period, zone.period, + zone.period }; + uint16_t tempos[7] = { zone.tempo, zone.tempo, + zone.tempo, zone.tempo, + zone.tempo, zone.tempo, + zone.tempo }; + + result = MultiModeAction(modes, periods, tempos, rainbow_colors[0], 7); + } + break; + + case ALIENWARE_MODE_RAINBOW: + { + uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH, + ALIENWARE_MODE_MORPH }; + uint16_t periods[7] = { zone.period, zone.period, + zone.period, zone.period, + zone.period, zone.period, + zone.period }; + uint16_t tempos[7] = { zone.tempo, zone.tempo, + zone.tempo, zone.tempo, + zone.tempo, zone.tempo, + zone.tempo }; + + unsigned int color_idx = (zone.direction == MODE_DIRECTION_LEFT) ? (4 - 1 - (zone_idx % 4)) : (zone_idx % 4); + result = MultiModeAction(modes, periods, tempos, rainbow_colors[color_idx], 7); + } + break; + + case ALIENWARE_MODE_BREATHING: + { + uint8_t modes[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH }; + uint16_t periods[2] = { zone.period, zone.period }; + uint16_t tempos[2] = { zone.tempo, zone.tempo }; + RGBColor colors[2] = { zone.color[0], 0x0 }; + + result = MultiModeAction(modes, periods, tempos, colors, 2); + } + break; + + default: + result = false; + } + + if(!result) + { + return; + } + } + + UserAnimation(ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE, ALIENWARE_ANIM_DEFAULT, 0); + UserAnimation(ALIENWARE_COMMAND_USER_ANIM_DEFAULT, ALIENWARE_ANIM_DEFAULT, 0); + UserAnimation(ALIENWARE_COMMAND_USER_ANIM_STARTUP, ALIENWARE_ANIM_DEFAULT, 0); +} + void AlienwareController::UpdateController() { UpdateMode(); diff --git a/Controllers/AlienwareController/AlienwareController.h b/Controllers/AlienwareController/AlienwareController.h index 57c6fc102..951ee2575 100644 --- a/Controllers/AlienwareController/AlienwareController.h +++ b/Controllers/AlienwareController/AlienwareController.h @@ -123,11 +123,13 @@ public: void SetPeriod(uint8_t zone, uint16_t period); void SetTempo(uint8_t zone, uint16_t tempo); void SetDim(uint8_t zone, uint8_t dim); + void SetDirection(uint8_t zone, uint8_t direction); AlienwareReport GetStatus(uint8_t subcommand); void UpdateDim(); void UpdateMode(); void UpdateController(); + void SaveController(); protected: hid_device* dev; @@ -140,6 +142,7 @@ private: uint16_t period; uint16_t tempo; uint8_t dim; + uint8_t direction; } alienware_zone; typedef struct @@ -153,6 +156,7 @@ private: std::string serial_number; std::string version; std::vector zone_names; + std::vector zone_ids; bool dirty; bool dirty_dim; diff --git a/Controllers/AlienwareController/RGBController_Alienware.cpp b/Controllers/AlienwareController/RGBController_Alienware.cpp index 4ae388d7b..4ffa5b851 100644 --- a/Controllers/AlienwareController/RGBController_Alienware.cpp +++ b/Controllers/AlienwareController/RGBController_Alienware.cpp @@ -39,7 +39,7 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Color; Color.name = "Static"; Color.value = ALIENWARE_MODE_COLOR; - Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; Color.color_mode = MODE_COLORS_PER_LED; Color.colors_min = 1; Color.colors_max = 1; @@ -51,13 +51,13 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Pulse; Pulse.name = "Flashing"; Pulse.value = ALIENWARE_MODE_PULSE; - Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; Pulse.color_mode = MODE_COLORS_PER_LED; Pulse.colors_min = 1; Pulse.colors_max = 1; - Pulse.speed_min = ALIENWARE_TEMPO_MIN; - Pulse.speed_max = ALIENWARE_TEMPO_MAX; - Pulse.speed = ALIENWARE_TEMPO_MIN; + Pulse.speed_min = ALIENWARE_TEMPO_MAX; + Pulse.speed_max = 50; + Pulse.speed = 150; Pulse.brightness_min = 100; Pulse.brightness_max = 0; Pulse.brightness = 0; @@ -66,14 +66,16 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Morph; Morph.name = "Morph"; Morph.value = ALIENWARE_MODE_MORPH; - Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; Morph.color_mode = MODE_COLORS_MODE_SPECIFIC; - Morph.colors_min = 2 * controller->GetZoneCount(); - Morph.colors_max = Morph.colors_min; - Morph.colors.resize(Morph.colors_max); - Morph.speed_min = ALIENWARE_TEMPO_MIN; - Morph.speed_max = ALIENWARE_TEMPO_MAX; - Morph.speed = ALIENWARE_TEMPO_MIN; + Morph.colors_min = 2; + Morph.colors_max = 2 * controller->GetZoneCount(); + Morph.colors.resize(2); + Morph.colors[0] = 0x0000FF; + Morph.colors[1] = 0xFF0000; + Morph.speed_min = ALIENWARE_TEMPO_MAX; + Morph.speed_max = 20; + Morph.speed = 100; Morph.brightness_min = 100; Morph.brightness_max = 0; Morph.brightness = 0; @@ -82,11 +84,11 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Spectrum; Spectrum.name = "Spectrum Cycle"; Spectrum.value = ALIENWARE_MODE_SPECTRUM; - Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; Spectrum.color_mode = MODE_COLORS_NONE; - Spectrum.speed_min = ALIENWARE_TEMPO_SPECTRUM; - Spectrum.speed_max = ALIENWARE_TEMPO_MAX; - Spectrum.speed = ALIENWARE_TEMPO_SPECTRUM; + Spectrum.speed_min = ALIENWARE_TEMPO_MAX; + Spectrum.speed_max = ALIENWARE_TEMPO_SPECTRUM; + Spectrum.speed = 40; Spectrum.brightness_min = 100; Spectrum.brightness_max = 0; Spectrum.brightness = 0; @@ -95,11 +97,12 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Rainbow; Rainbow.name = "Rainbow Wave"; Rainbow.value = ALIENWARE_MODE_RAINBOW; - Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_MANUAL_SAVE; Rainbow.color_mode = MODE_COLORS_NONE; - Rainbow.speed_min = ALIENWARE_TEMPO_SPECTRUM; - Rainbow.speed_max = ALIENWARE_TEMPO_MAX; - Rainbow.speed = ALIENWARE_TEMPO_SPECTRUM; + Rainbow.speed_min = ALIENWARE_TEMPO_MAX; + Rainbow.speed_max = ALIENWARE_TEMPO_SPECTRUM; + Rainbow.speed = 40; + Rainbow.direction = MODE_DIRECTION_RIGHT; Rainbow.brightness_min = 100; Rainbow.brightness_max = 0; Rainbow.brightness = 0; @@ -108,13 +111,13 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller mode Breathing; Breathing.name = "Breathing"; Breathing.value = ALIENWARE_MODE_BREATHING; - Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; Breathing.color_mode = MODE_COLORS_PER_LED; Breathing.colors_min = 1; Breathing.colors_max = 1; - Breathing.speed_min = ALIENWARE_TEMPO_MIN; - Breathing.speed_max = ALIENWARE_TEMPO_MAX; - Breathing.speed = ALIENWARE_TEMPO_MIN; + Breathing.speed_min = ALIENWARE_TEMPO_MAX; + Breathing.speed_max = 50; + Breathing.speed = 150; Breathing.brightness_min = 100; Breathing.brightness_max = 0; Breathing.brightness = 0; @@ -224,6 +227,7 @@ void RGBController_Alienware::DeviceUpdateMode() uint16_t period = 0x07d0; controller->SetMode(zone_idx, current_mode.value); + controller->SetDirection(zone_idx, current_mode.direction); switch(current_mode_idx) { @@ -235,6 +239,7 @@ void RGBController_Alienware::DeviceUpdateMode() break; case ALIENWARE_MODE_PULSE: + period = std::max(500, (uint16_t)(current_mode.speed * 10)); controller->SetPeriod(zone_idx, period); controller->SetColor( zone_idx, colors[current_zone.start_idx]); controller->SetTempo( zone_idx, current_mode.speed); @@ -242,10 +247,22 @@ void RGBController_Alienware::DeviceUpdateMode() break; case ALIENWARE_MODE_MORPH: - controller->SetPeriod(zone_idx, period); - controller->SetColor( zone_idx, current_mode.colors[zone_idx * 2], current_mode.colors[(zone_idx * 2) + 1]); - controller->SetTempo( zone_idx, current_mode.speed); - controller->SetDim( zone_idx, modes[current_mode_idx].brightness); + { + RGBColor c1 = (current_mode.colors.size() >= 1) ? current_mode.colors[0] : 0x0000FF; + RGBColor c2 = (current_mode.colors.size() >= 2) ? current_mode.colors[1] : 0xFF0000; + + if(current_mode.colors.size() >= (zone_idx + 1) * 2) + { + c1 = current_mode.colors[zone_idx * 2]; + c2 = current_mode.colors[(zone_idx * 2) + 1]; + } + + period = std::max(400, (uint16_t)(current_mode.speed * 10)); + controller->SetPeriod(zone_idx, period); + controller->SetColor( zone_idx, c1, c2); + controller->SetTempo( zone_idx, current_mode.speed); + controller->SetDim( zone_idx, modes[current_mode_idx].brightness); + } break; case ALIENWARE_MODE_SPECTRUM: @@ -256,6 +273,7 @@ void RGBController_Alienware::DeviceUpdateMode() break; case ALIENWARE_MODE_BREATHING: + period = std::max(500, (uint16_t)(current_mode.speed * 10)); controller->SetPeriod(zone_idx, period); controller->SetColor( zone_idx, colors[current_zone.start_idx], 0x0); controller->SetTempo( zone_idx, current_mode.speed); @@ -282,3 +300,9 @@ void RGBController_Alienware::DeviceUpdateMode() current_mode = new_current_mode; } } + +void RGBController_Alienware::DeviceSaveMode() +{ + controller->SaveController(); +} + diff --git a/Controllers/AlienwareController/RGBController_Alienware.h b/Controllers/AlienwareController/RGBController_Alienware.h index b3ebb7206..0938beb5f 100644 --- a/Controllers/AlienwareController/RGBController_Alienware.h +++ b/Controllers/AlienwareController/RGBController_Alienware.h @@ -28,6 +28,7 @@ public: void DeviceUpdateSingleLED(int led); void DeviceUpdateMode(); + void DeviceSaveMode(); private: AlienwareController* controller;