/*---------------------------------------------------------*\ | AlienwareController.h | | | | Driver for Dell Alienware RGB USB controller | | | | Gabriel Marcano (gemarcano) 19 Apr 2021 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ #pragma once #include #include #include "RGBController.h" /*----------------------------------------------------------------------------------------------*\ | Definitions for Alienware Controller | \*----------------------------------------------------------------------------------------------*/ #define ALIENWARE_REPORT_SIZE 33 #define HIDAPI_ALIENWARE_REPORT_SIZE (ALIENWARE_REPORT_SIZE + 1) #define ALIENWARE_CONTROLLER_NAME "AlienWare Controller" enum { ALIENWARE_COMMAND_REPORT = 0x20, /* Set report type to get */ ALIENWARE_COMMAND_USER_ANIM = 0x21, /* Set user animation settings */ ALIENWARE_COMMAND_POWER_ANIM = 0x22, /* Set power animation settings */ ALIENWARE_COMMAND_SELECT_ZONES = 0x23, /* Select zones to apply actions to */ ALIENWARE_COMMAND_ADD_ACTION = 0x24, /* Set actions to apply */ ALIENWARE_COMMAND_UNKNOWN1 = 0x25, /* Supposedly set event? */ ALIENWARE_COMMAND_DIM = 0x26, /* Set dim percentage */ ALIENWARE_COMMAND_SET_COLOR = 0x27, /* Unclear (causes color flash) */ ALIENWARE_COMMAND_RESET = 0x28, /* Reset */ ALIENWARE_COMMAND_ERASE_FLASH = 0xFF, /* Erases flash memory on controller */ }; enum { ALIENWARE_COMMAND_REPORT_FIRMWARE = 0x00, /* Get firmware verion */ ALIENWARE_COMMAND_REPORT_STATUS = 0x01, /* Get status */ ALIENWARE_COMMAND_REPORT_CONFIG = 0x02, /* Get firmware config */ ALIENWARE_COMMAND_REPORT_ANIMATION = 0x03, /* Get animation count and last id */ ALIENWARE_COMMAND_REPORT_UNKNOWN1 = 0x04, /* Get ELC animation by ID */ ALIENWARE_COMMAND_REPORT_UNKNOWN2 = 0x05, /* Read series??? */ ALIENWARE_COMMAND_REPORT_UNKNOWN3 = 0x06, /* Get action??? */ ALIENWARE_COMMAND_REPORT_UNKNOWN4 = 0x07, /* Get Caldera status??? */ }; enum { ALIENWARE_COMMAND_USER_ANIM_NEW = 0x0001, /* Start new animation */ ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE = 0x0002, /* Finish and save animation */ ALIENWARE_COMMAND_USER_ANIM_FINISH_PLAY = 0x0003, /* Finish and play animation */ ALIENWARE_COMMAND_USER_ANIM_REMOVE = 0x0004, /* Remove/erase animation */ ALIENWARE_COMMAND_USER_ANIM_PLAY = 0x0005, /* Play animation */ ALIENWARE_COMMAND_USER_ANIM_DEFAULT = 0x0006, /* Set default animation */ ALIENWARE_COMMAND_USER_ANIM_STARTUP = 0x0007, /* Set startup animation */ }; enum { ALIENWARE_ANIM_DEFAULT_STARTUP = 0x0008, /* Default slot for startup */ ALIENWARE_ANIM_DEFAULT = 0x0061, /* Default slot */ ALIENWARE_COMMAND_USER_ANIM_KEYBOARD = 0xFFFF, /* Non-saved animation slot */ }; enum { ALIENWARE_MODE_COLOR = 0x00, /* Action to set color mode */ ALIENWARE_MODE_PULSE = 0x01, /* Action to set pulse mode */ ALIENWARE_MODE_MORPH = 0x02, /* Action to set morph mode */ ALIENWARE_MODE_SPECTRUM, /* Abitrary code for spectrum mode */ ALIENWARE_MODE_RAINBOW, /* Arbitrary code for rainbow wave mode */ ALIENWARE_MODE_BREATHING, /* Arbitrary code for rainbow wave mode */ }; enum { ALIENWARE_TEMPO_MIN = 0x0064, /* Min tempo (as used by AWCC) */ ALIENWARE_TEMPO_MAX = 0x00FA, /* Max tempo (as used by AWCC) */ ALIENWARE_TEMPO_SPECTRUM = 0x000F, /* Used by Spectrum mode */ }; enum { ALIENWARE_DURATION_LONG = 0x09C4, /* Min tempo (as used by AWCC) */ ALIENWARE_DURATION_MED = 0x05DC, /* Max tempo (as used by AWCC) */ ALIENWARE_DURATION_SHORT = 0x01F3, /* Max tempo (as used by AWCC) */ ALIENWARE_DURATION_SPECTRUM = 0x01AC, /* Used by Spectrum mode */ }; typedef struct { unsigned char data[ALIENWARE_REPORT_SIZE]; } AlienwareReport; class AlienwareController { public: AlienwareController(hid_device* dev_handle, const hid_device_info& info, std::string name); ~AlienwareController(); std::string GetSerialString(); std::string GetDeviceLocation(); std::string GetDeviceName(); std::string GetFirmwareVersion(); unsigned GetZoneCount(); std::vector GetZoneNames(); void SetColor(uint8_t zone, RGBColor color); void SetColor(uint8_t zone, RGBColor color1, RGBColor color2); void SetMode(uint8_t zone, uint8_t mode); void SetPeriod(uint8_t zone, uint16_t period); void SetTempo(uint8_t zone, uint16_t tempo); void SetDim(uint8_t zone, uint8_t dim); AlienwareReport GetStatus(uint8_t subcommand); void UpdateDim(); void UpdateMode(); void UpdateController(); protected: hid_device* dev; private: typedef struct { RGBColor color[2]; uint8_t mode; uint16_t period; uint16_t tempo; uint8_t dim; } alienware_zone; typedef struct { unsigned char data[HIDAPI_ALIENWARE_REPORT_SIZE]; } HidapiAlienwareReport; std::string device_name; std::string location; std::vector zones; std::string serial_number; std::string version; std::vector zone_names; bool dirty; bool dirty_dim; HidapiAlienwareReport GetResponse(); HidapiAlienwareReport Report(uint8_t subcommand); bool Dim(std::vector zones, double percent); bool UserAnimation(uint16_t subcommand, uint16_t animation, uint16_t duration); bool SelectZones(const std::vector& zones); bool ModeAction(uint8_t mode, uint16_t duration, uint16_t tempo, RGBColor color); bool ModeAction(const uint8_t *mode, const uint16_t *duration, const uint16_t *tempo, const RGBColor *color, unsigned amount); bool MultiModeAction(const uint8_t *mode, const uint16_t *duration, const uint16_t *tempo, const RGBColor *color, unsigned amount); bool SetColorDirect(RGBColor color, std::vector zones); bool UpdateDirect(); bool Reset(); };