diff --git a/MSIRGB.DLL/MSIRGB.Lighting.h b/MSIRGB.DLL/MSIRGB.Lighting.h index 62f5187..0c665e4 100644 --- a/MSIRGB.DLL/MSIRGB.Lighting.h +++ b/MSIRGB.DLL/MSIRGB.Lighting.h @@ -85,6 +85,41 @@ namespace MSIRGB { return Nullable(Color::FromRgb(colour->r, colour->g, colour->b)); } + Boolean GetDefaultColourChannelsInvertedSetting() + { + return lighting->get_default_colour_channels_inverted_setting(); + } + + void SetRChannelInverted(Boolean inverted) + { + lighting->set_r_channel_inverted(inverted); + } + + void SetGChannelInverted(Boolean inverted) + { + lighting->set_g_channel_inverted(inverted); + } + + void SetBChannelInverted(Boolean inverted) + { + lighting->set_b_channel_inverted(inverted); + } + + Boolean IsRChannelInverted() + { + return lighting->is_r_channel_inverted(); + } + + Boolean IsGChannelInverted() + { + return lighting->is_g_channel_inverted(); + } + + Boolean IsBChannelInverted() + { + return lighting->is_b_channel_inverted(); + } + bool SetBreathingModeEnabled(Boolean enabled) { return lighting->set_breathing_mode_enabled(enabled); diff --git a/MSIRGB.DLL/logic/Lighting.cpp b/MSIRGB.DLL/logic/Lighting.cpp index 52f0497..0377b57 100644 --- a/MSIRGB.DLL/logic/Lighting.cpp +++ b/MSIRGB.DLL/logic/Lighting.cpp @@ -111,6 +111,12 @@ namespace logic { throw Exception(ErrorCode::DriverLoadFailed); } leave_critical_section(); + + // Set default inverted colour channels setting + bool default_colour_channels_inv = get_default_colour_channels_inverted_setting(); + set_r_channel_inverted(default_colour_channels_inv); + set_g_channel_inverted(default_colour_channels_inv); + set_b_channel_inverted(default_colour_channels_inv); } Lighting::~Lighting() @@ -227,6 +233,74 @@ namespace logic { return std::make_optional(Colour{ r, g, b }); } + bool Lighting::get_default_colour_channels_inverted_setting() const + { + return mb_flags & MbFlags::INVERTED_COLOUR_CHANNELS; + } + + void Lighting::set_r_channel_inverted(bool inverted) + { + curr_batch.r_channel_inverted = inverted; + + if (!batch_calls) { + batch_commit(); + } + } + + void Lighting::set_g_channel_inverted(bool inverted) + { + curr_batch.g_channel_inverted = inverted; + + if (!batch_calls) { + batch_commit(); + } + } + + void Lighting::set_b_channel_inverted(bool inverted) + { + curr_batch.b_channel_inverted = inverted; + + if (!batch_calls) { + batch_commit(); + } + } + + bool Lighting::is_r_channel_inverted() const + { + // See batch_commit for details + enter_critical_section(); + + std::uint8_t val_at_ff = sio->read_uint8_from_bank(RGB_BANK, 0xFF); + + leave_critical_section(); + + return val_at_ff & 0b00010000; + } + + bool Lighting::is_g_channel_inverted() const + { + // See batch_commit for details + enter_critical_section(); + + std::uint8_t val_at_ff = sio->read_uint8_from_bank(RGB_BANK, 0xFF); + + leave_critical_section(); + + return val_at_ff & 0b00001000; + } + + bool Lighting::is_b_channel_inverted() const + { + // See batch_commit for details + enter_critical_section(); + + std::uint8_t val_at_ff = sio->read_uint8_from_bank(RGB_BANK, 0xFF); + + leave_critical_section(); + + return val_at_ff & 0b00000100; + } + bool Lighting::set_breathing_mode_enabled(bool enable) { if (get_flash_speed() != FlashingSpeed::Disabled && @@ -505,17 +579,41 @@ namespace logic { // I think it's only supported on other MBs that have RGB headers but are // different somehow - those function differently from the MBs supported // here. - if (mb_flags & MbFlags::INVERTED_COLOUR_CHANNELS) { - val_at_ff |= 0b00011100; - + if (mb_flags & MbFlags::INVERTED_COLOUR_CHANNELS) { // rainbow crap + // NOTE: This is within this IF because it seems to only be applied + // by Mystic Light when colour channels are inverted. std::uint8_t val_at_fd = sio->read_uint8_from_bank(RGB_BANK, 0xFD); - + val_at_fd &= 0b11111000; sio->write_uint8_to_bank(RGB_BANK, 0xFD, val_at_fd); } - else { - val_at_ff &= 0b11100011; + + if (curr_batch.r_channel_inverted.has_value()) { + if (*(curr_batch.r_channel_inverted) == true) { + val_at_ff |= 0b00010000; + } + else { + val_at_ff &= 0b11101111; + } + } + + if (curr_batch.g_channel_inverted.has_value()) { + if (*(curr_batch.g_channel_inverted) == true) { + val_at_ff |= 0b00001000; + } + else { + val_at_ff &= 0b11110111; + } + } + + if (curr_batch.b_channel_inverted.has_value()) { + if (*(curr_batch.b_channel_inverted) == true) { + val_at_ff |= 0b00000100; + } + else { + val_at_ff &= 0b11111011; + } } // Fade in value is first 3 bits: BGR, in this order, from leftmost bit to rightmost bit diff --git a/MSIRGB.DLL/logic/Lighting.h b/MSIRGB.DLL/logic/Lighting.h index 7d79f7f..044f3ef 100644 --- a/MSIRGB.DLL/logic/Lighting.h +++ b/MSIRGB.DLL/logic/Lighting.h @@ -62,6 +62,13 @@ namespace logic { void set_led_enabled(bool enable); bool set_colour(std::uint8_t index, Colour colour); std::optional get_colour(std::uint8_t index) const; + bool get_default_colour_channels_inverted_setting() const; + void set_r_channel_inverted(bool inverted); + void set_g_channel_inverted(bool inverted); + void set_b_channel_inverted(bool inverted); + bool is_r_channel_inverted() const; + bool is_g_channel_inverted() const; + bool is_b_channel_inverted() const; bool set_breathing_mode_enabled(bool enable); bool is_breathing_mode_enabled() const; bool set_step_duration(std::uint16_t step_duration); @@ -95,6 +102,9 @@ namespace logic { struct Batch { std::unordered_map colours; + std::optional r_channel_inverted; + std::optional g_channel_inverted; + std::optional b_channel_inverted; std::optional enabled; std::optional breathing_mode_enabled; std::optional step_duration; diff --git a/MSIRGB.GUI/MainWindowModel.cs b/MSIRGB.GUI/MainWindowModel.cs index 9c8ef92..0f72a73 100644 --- a/MSIRGB.GUI/MainWindowModel.cs +++ b/MSIRGB.GUI/MainWindowModel.cs @@ -45,6 +45,9 @@ public MainWindowModel() public void GetCurrentConfig(ref List colours, out ushort stepDuration, out bool breathingEnabled, + out bool invertedRChannel, + out bool invertedGChannel, + out bool invertedBChannel, out FlashingSpeed flashingSpeed) { foreach (byte index in Range(1, 8)) @@ -60,12 +63,19 @@ public void GetCurrentConfig(ref List colours, breathingEnabled = _lighting.IsBreathingModeEnabled(); + invertedRChannel = _lighting.IsRChannelInverted(); + invertedGChannel = _lighting.IsGChannelInverted(); + invertedBChannel = _lighting.IsBChannelInverted(); + flashingSpeed = (FlashingSpeed)_lighting.GetFlashingSpeed(); } public void ApplyConfig(List colours, ushort stepDuration, bool breathingEnabled, + bool invertedRChannel, + bool invertedGChannel, + bool invertedBChannel, FlashingSpeed flashingSpeed) { _lighting.BatchBegin(); @@ -76,6 +86,23 @@ public void ApplyConfig(List colours, c.R /= 0x11; // Colour must be passed with 12-bit depth c.G /= 0x11; c.B /= 0x11; + + if (invertedRChannel) // if inverting colour channels, transform colours from + // colour picker appropriately (which are never inverted) + { + c.R = (byte)(0x0F - c.R); + } + + if (invertedGChannel) + { + c.G = (byte)(0x0F - c.G); + } + + if (invertedBChannel) + { + c.B = (byte)(0x0F - c.B); + } + _lighting.SetColour(index, c); } @@ -87,6 +114,10 @@ public void ApplyConfig(List colours, _lighting.SetBreathingModeEnabled(breathingEnabled); + _lighting.SetRChannelInverted(invertedRChannel); + _lighting.SetGChannelInverted(invertedGChannel); + _lighting.SetBChannelInverted(invertedBChannel); + _lighting.BatchEnd(); } diff --git a/MSIRGB.GUI/MainWindowView.xaml b/MSIRGB.GUI/MainWindowView.xaml index 55e3fe3..b92b3ed 100644 --- a/MSIRGB.GUI/MainWindowView.xaml +++ b/MSIRGB.GUI/MainWindowView.xaml @@ -93,6 +93,41 @@ + + + + + + + + + + + + + diff --git a/MSIRGB.GUI/MainWindowViewModel.cs b/MSIRGB.GUI/MainWindowViewModel.cs index 60ba967..7d88976 100644 --- a/MSIRGB.GUI/MainWindowViewModel.cs +++ b/MSIRGB.GUI/MainWindowViewModel.cs @@ -43,6 +43,24 @@ public class MainWindowViewModel : DependencyObject typeof(MainWindowViewModel), new PropertyMetadata(false)); + public static readonly DependencyProperty InvertedRChannelProperty = DependencyProperty.Register( + "InvertedRChannel", + typeof(bool), + typeof(MainWindowViewModel), + new PropertyMetadata(false)); + + public static readonly DependencyProperty InvertedGChannelProperty = DependencyProperty.Register( + "InvertedGChannel", + typeof(bool), + typeof(MainWindowViewModel), + new PropertyMetadata(false)); + + public static readonly DependencyProperty InvertedBChannelProperty = DependencyProperty.Register( + "InvertedBChannel", + typeof(bool), + typeof(MainWindowViewModel), + new PropertyMetadata(false)); + public static readonly DependencyProperty FlashingSpeedIndexProperty = DependencyProperty.Register( "FlashingSpeedIndex", typeof(int), @@ -102,6 +120,27 @@ public bool BreathingModeEnabled set { SetValue(BreathingModeEnabledProperty, value); } } + + public bool InvertedRChannel + { + get { return (bool)GetValue(InvertedRChannelProperty); } + set { SetValue(InvertedRChannelProperty, value); } + } + + + public bool InvertedGChannel + { + get { return (bool)GetValue(InvertedGChannelProperty); } + set { SetValue(InvertedGChannelProperty, value); } + } + + + public bool InvertedBChannel + { + get { return (bool)GetValue(InvertedBChannelProperty); } + set { SetValue(InvertedBChannelProperty, value); } + } + public int FlashingSpeedSelectedIndex { get { return (int)GetValue(FlashingSpeedIndexProperty); } @@ -194,6 +233,9 @@ public void Apply() _model.ApplyConfig(colours, Convert.ToUInt16(StepDurationText), BreathingModeEnabled, + InvertedRChannel, + InvertedGChannel, + InvertedBChannel, FlashingSpeedList[FlashingSpeedSelectedIndex].Type); } @@ -231,6 +273,9 @@ public void LoadedEvent() _model.GetCurrentConfig(ref colours, out ushort stepDuration, out bool breathingEnabled, + out bool invertedRChannel, + out bool invertedGChannel, + out bool invertedBChannel, out MainWindowModel.FlashingSpeed flashingSpeed); foreach(Byte index in Range(1, 8)) @@ -242,6 +287,10 @@ public void LoadedEvent() BreathingModeEnabled = breathingEnabled; + InvertedRChannel = invertedRChannel; + InvertedGChannel = invertedGChannel; + InvertedBChannel = invertedBChannel; + FlashingSpeedSelectedIndex = FlashingSpeedList.IndexOf(FlashingSpeedList.Single(x => x.Type == flashingSpeed)); ListSelectedColourIndex = 0; diff --git a/MSIRGB.ScriptService/LuaBindings/LightingModule.cs b/MSIRGB.ScriptService/LuaBindings/LightingModule.cs index 46f5536..7aaed8b 100644 --- a/MSIRGB.ScriptService/LuaBindings/LightingModule.cs +++ b/MSIRGB.ScriptService/LuaBindings/LightingModule.cs @@ -75,6 +75,39 @@ public DynValue GetColour(byte index) DynValue.NewNumber(c.B) }); } + public bool GetDefaultColourChannelsInvertedSetting() + { + return _lighting.GetDefaultColourChannelsInvertedSetting(); + } + public void SetRChannelInverted(bool inverted) + { + _lighting.SetRChannelInverted(inverted); + } + + public void SetGChannelInverted(bool inverted) + { + _lighting.SetGChannelInverted(inverted); + } + + public void SetBChannelInverted(bool inverted) + { + _lighting.SetBChannelInverted(inverted); + } + + public bool IsRChannelInverted() + { + return _lighting.IsRChannelInverted(); + } + + public bool IsGChannelInverted() + { + return _lighting.IsGChannelInverted(); + } + + public bool IsBChannelInverted() + { + return _lighting.IsBChannelInverted(); + } public bool SetBreathingModeEnabled(bool enabled) { diff --git a/Scripts/Heartbeat.lua b/Scripts/Heartbeat.lua index 0123fbe..1896538 100644 --- a/Scripts/Heartbeat.lua +++ b/Scripts/Heartbeat.lua @@ -1,5 +1,5 @@ -- User-changeable variables -local speed = 130 -- seconds between each iteration of 'colours' +local speed = 130 -- milliseconds between each iteration of 'colours' local colours = { {0x6, 0x2, 0xa}, {0x6, 0x3, 0xa}, @@ -13,8 +13,13 @@ local colours = { -- local n = 1 +local defaultInvertedColourChannels = Lighting.GetDefaultColourChannelsInvertedSetting() + while true do Lighting.BatchBegin() + Lighting.SetRChannelInverted(defaultInvertedColourChannels) + Lighting.SetGChannelInverted(defaultInvertedColourChannels) + Lighting.SetBChannelInverted(defaultInvertedColourChannels) Lighting.SetBreathingModeEnabled(false) Lighting.SetFlashingSpeed(0) Lighting.SetStepDuration(511) diff --git a/Scripts/Hue Wheel.lua b/Scripts/Hue Wheel.lua index b501806..a8f49fa 100644 --- a/Scripts/Hue Wheel.lua +++ b/Scripts/Hue Wheel.lua @@ -8,8 +8,13 @@ local delay = 80 -- delay between each colour update, in milliseconds local colour_step = 98 -- ]0, 360], the higher, the smaller the step between colours -- +local defaultInvertedColourChannels = Lighting.GetDefaultColourChannelsInvertedSetting() local i = 0 while true do + Lighting.BatchBegin() + Lighting.SetRChannelInverted(defaultInvertedColourChannels) + Lighting.SetGChannelInverted(defaultInvertedColourChannels) + Lighting.SetBChannelInverted(defaultInvertedColourChannels) Lighting.SetStepDuration(511) Lighting.SetFlashingSpeed(0) Lighting.SetBreathingModeEnabled(false) @@ -20,7 +25,6 @@ while true do g = tonumber(("%x"):format(g * 15), 16) b = tonumber(("%x"):format(b * 15), 16) - Lighting.BatchBegin() for i = 1, 8 do Lighting.SetColour(i, r, g, b) end diff --git a/Scripts/Police Lights.lua b/Scripts/Police Lights.lua index fc0515c..a905921 100644 --- a/Scripts/Police Lights.lua +++ b/Scripts/Police Lights.lua @@ -4,6 +4,7 @@ local pulse_time = 0.4 -- how long each flashing pulse will take, in seconds (re local pulse_delay = 1 -- how long between each flashing pulse, in milliseconds local flash_colour = {["r"] = 0x2, ["g"] = 0xf, ["b"] = 0xf} local alt_flash_colour = {["r"] = 0xf, ["g"] = 0xf, ["b"] = 0x2} +local inverted_colours = true -- local flash = require('utils.custom_flash') @@ -28,8 +29,15 @@ local function change_colour() end end +local defaultInvertedColourChannels = Lighting.GetDefaultColourChannelsInvertedSetting() + +local invert = inverted_colours and (not defaultInvertedColourChannels) or (defaultInvertedColourChannels) + while true do Lighting.BatchBegin() + Lighting.SetRChannelInverted(invert) + Lighting.SetGChannelInverted(invert) + Lighting.SetBChannelInverted(invert) Lighting.SetFlashingSpeed(0) Lighting.SetBreathingModeEnabled(false) Lighting.BatchEnd() diff --git a/Scripts/Pumpkin.lua b/Scripts/Pumpkin.lua index 22d0537..3bcb665 100644 --- a/Scripts/Pumpkin.lua +++ b/Scripts/Pumpkin.lua @@ -4,13 +4,20 @@ local pumpkin_colour = {["r"] = 0xf, ["g"] = 0x2, ["b"] = 0x0} -- local Timer = require('base.timer') +local defaultInvertedColourChannels = Lighting.GetDefaultColourChannelsInvertedSetting() + function effect() + Lighting.BatchBegin() + Lighting.SetRChannelInverted(defaultInvertedColourChannels) + Lighting.SetGChannelInverted(defaultInvertedColourChannels) + Lighting.SetBChannelInverted(defaultInvertedColourChannels) Lighting.SetFlashingSpeed(0) Lighting.SetBreathingModeEnabled(true) for i = 1, 8 do Lighting.SetColour(i, pumpkin_colour.r, pumpkin_colour.g, pumpkin_colour.b) end + Lighting.BatchEnd() end Timer.Set(effect, Timer.DefaultInterval) \ No newline at end of file diff --git a/Scripts/Strobe.lua b/Scripts/Strobe.lua index aaed7aa..c865261 100644 --- a/Scripts/Strobe.lua +++ b/Scripts/Strobe.lua @@ -9,8 +9,13 @@ local flash_colour = {["r"] = 0x2, ["g"] = 0x7, ["b"] = 0xf} -- local flash = require('utils.custom_flash') +local defaultInvertedColourChannels = Lighting.GetDefaultColourChannelsInvertedSetting() + while true do Lighting.BatchBegin() + Lighting.SetRChannelInverted(defaultInvertedColourChannels) + Lighting.SetGChannelInverted(defaultInvertedColourChannels) + Lighting.SetBChannelInverted(defaultInvertedColourChannels) Lighting.SetFlashingSpeed(0) Lighting.SetBreathingModeEnabled(false)