diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 2b94b673b..bfa85bf56 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -354,6 +354,8 @@ + + diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs index dbc939d47..d57e6e47c 100644 --- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs @@ -33,7 +33,8 @@ namespace Artemis.DeviceProviders.CoolerMaster } public override void Disable() - { + { + CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L); CmSdk.EnableLedControl(false); Thread.Sleep(500); } diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs index 36a9f5b72..e00a811b7 100644 --- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs @@ -34,13 +34,14 @@ namespace Artemis.DeviceProviders.CoolerMaster public override void Disable() { + CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_S); CmSdk.EnableLedControl(false); Thread.Sleep(500); } public override bool CanEnable() { - CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L); + CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_S); // Doesn't seem reliable but better than nothing I suppose return CmSdk.IsDevicePlug(); diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs index e72ac7bc2..ca842fd0e 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs @@ -1,8 +1,8 @@ using System; using System.Drawing; -using System.Linq; using System.Threading; using CUE.NET; +using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using Ninject.Extensions.Logging; @@ -10,10 +10,13 @@ namespace Artemis.DeviceProviders.Corsair { public class CorsairHeadset : DeviceProvider { + private readonly ImageBrush _headsetBrush; + public CorsairHeadset(ILogger logger) { Logger = logger; Type = DeviceType.Headset; + _headsetBrush = new ImageBrush(); } public ILogger Logger { get; set; } @@ -27,7 +30,10 @@ namespace Artemis.DeviceProviders.Corsair Logger.Debug("Attempted to enable Corsair headset. CanUse: {0}", CanUse); if (CanUse) + { CueSDK.UpdateMode = UpdateMode.Manual; + CueSDK.HeadsetSDK.Brush = _headsetBrush; + } return CanUse; } @@ -44,21 +50,7 @@ namespace Artemis.DeviceProviders.Corsair if (bitmap.Width != bitmap.Height) throw new ArgumentException("Bitmap must be a perfect square"); - var leds = CueSDK.HeadsetSDK.Leds.Count(); - var step = (double)bitmap.Width / leds; - - var ledIndex = 0; - // Color each LED according to one of the pixels - foreach (var corsairLed in CueSDK.HeadsetSDK.Leds) - { - var col = ledIndex == 0 - ? bitmap.GetPixel(0, 0) - : bitmap.GetPixel((int)((ledIndex + 1) * step - 1), (int)((ledIndex + 1) * step - 1)); - - corsairLed.Color = col; - ledIndex++; - } - + _headsetBrush.Image = bitmap; CueSDK.HeadsetSDK.Update(); } diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs index 091dd3e8a..301f07781 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs @@ -1,8 +1,8 @@ using System; using System.Drawing; -using System.Linq; using System.Threading; using CUE.NET; +using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using Ninject.Extensions.Logging; @@ -10,10 +10,13 @@ namespace Artemis.DeviceProviders.Corsair { public class CorsairMouse : DeviceProvider { + private readonly ImageBrush _mouseBrush; + public CorsairMouse(ILogger logger) { Logger = logger; Type = DeviceType.Mouse; + _mouseBrush = new ImageBrush(); } public ILogger Logger { get; set; } @@ -27,7 +30,10 @@ namespace Artemis.DeviceProviders.Corsair Logger.Debug("Attempted to enable Corsair mice. CanUse: {0}", CanUse); if (CanUse) + { CueSDK.UpdateMode = UpdateMode.Manual; + CueSDK.MouseSDK.Brush = _mouseBrush; + } return CanUse; } @@ -44,21 +50,7 @@ namespace Artemis.DeviceProviders.Corsair if (bitmap.Width != bitmap.Height) throw new ArgumentException("Bitmap must be a perfect square"); - var leds = CueSDK.MouseSDK.Leds.Count(); - var step = (double)bitmap.Width / leds; - - var ledIndex = 0; - // Color each LED according to one of the pixels - foreach (var corsairLed in CueSDK.MouseSDK.Leds) - { - var col = ledIndex == 0 - ? bitmap.GetPixel(0, 0) - : bitmap.GetPixel((int)((ledIndex + 1) * step - 1), (int)((ledIndex + 1) * step - 1)); - - corsairLed.Color = col; - ledIndex++; - } - + _mouseBrush.Image = bitmap; CueSDK.MouseSDK.Update(); } diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs index cceb75d62..0a3ae1283 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs @@ -1,8 +1,8 @@ using System; using System.Drawing; -using System.Linq; using System.Threading; using CUE.NET; +using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using Ninject.Extensions.Logging; @@ -10,10 +10,13 @@ namespace Artemis.DeviceProviders.Corsair { public class CorsairMousemat : DeviceProvider { + private readonly ImageBrush _mousematBrush; + public CorsairMousemat(ILogger logger) { Logger = logger; Type = DeviceType.Mousemat; + _mousematBrush = new ImageBrush(); } public ILogger Logger { get; set; } @@ -27,7 +30,10 @@ namespace Artemis.DeviceProviders.Corsair Logger.Debug("Attempted to enable Corsair mousemat. CanUse: {0}", CanUse); if (CanUse) + { CueSDK.UpdateMode = UpdateMode.Manual; + CueSDK.MousematSDK.Brush = _mousematBrush; + } return CanUse; } @@ -39,46 +45,12 @@ namespace Artemis.DeviceProviders.Corsair public override void UpdateDevice(Bitmap bitmap) { - if (!CanUse || (bitmap == null)) + if (!CanUse || bitmap == null) return; if (bitmap.Width != bitmap.Height) throw new ArgumentException("Bitmap must be a perfect square"); - - var yStep = (double)bitmap.Width / 4; - var xStep = (double)bitmap.Width / 6; - - // This approach will break if any mousemats with different LED amounts are released, for now it will do. - var ledIndex = 0; - // Color each LED according to one of the pixels - foreach (var corsairLed in CueSDK.MousematSDK.Leds.OrderBy(l => l.ToString())) - { - Color col; - // Left side - if (ledIndex < 5) - { - col = ledIndex == 0 - ? bitmap.GetPixel(0, (int)(ledIndex * yStep)) - : bitmap.GetPixel(0, (int)(ledIndex * yStep) - 1); - } - // Bottom - else if (ledIndex < 10) - { - // Start at index 1 because the corner belongs to the left side - var zoneIndex = ledIndex - 4; - col = bitmap.GetPixel((int)(zoneIndex * xStep), bitmap.Height - 1); - } - // Right side - else - { - var zoneIndex = ledIndex - 10; - col = zoneIndex == 4 - ? bitmap.GetPixel(bitmap.Height - 1, bitmap.Height - (int)(zoneIndex * yStep)) - : bitmap.GetPixel(bitmap.Height - 1, bitmap.Height - 1 - (int)(zoneIndex * yStep)); - } - - corsairLed.Color = col; - ledIndex++; - } + + _mousematBrush.Image = bitmap; CueSDK.MousematSDK.Update(); } diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index f31a22913..3b5aca4f4 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -1,12 +1,10 @@ using System; -using System.Drawing; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Artemis.DeviceProviders; +using Artemis.Models; using Artemis.ViewModels; using Ninject.Extensions.Logging; -using Color = System.Drawing.Color; namespace Artemis.Managers { @@ -58,7 +56,7 @@ namespace Artemis.Managers Render(); - int sleep = (int)(40f - ((DateTime.Now.Ticks - preUpdateTicks) / 10000f)); + int sleep = (int)(40f - (DateTime.Now.Ticks - preUpdateTicks) / 10000f); if (sleep > 0) Thread.Sleep(sleep); } @@ -161,7 +159,7 @@ namespace Artemis.Managers var keyboardOnly = !mice.Any() && !headsets.Any() && !generics.Any() && !mousemats.Any(); // Setup the frame for this tick - using (var frame = new RenderFrame(_deviceManager.ActiveKeyboard, mice.Any(), headsets.Any(), generics.Any(), mousemats.Any())) + using (var frame = new FrameModel(_deviceManager.ActiveKeyboard, mice.Any(), headsets.Any(), generics.Any(), mousemats.Any())) { if (renderModule.IsInitialized) renderModule.Render(frame, keyboardOnly); @@ -173,6 +171,9 @@ namespace Artemis.Managers overlayModel.Render(frame, keyboardOnly); } + // Render the frame's drawing context to bitmaps + frame.RenderBitmaps(); + // Update the keyboard _deviceManager.ActiveKeyboard?.DrawBitmap(frame.KeyboardBitmap); @@ -200,72 +201,4 @@ namespace Artemis.Managers RenderCompleted?.Invoke(this, EventArgs.Empty); } } - - public class RenderFrame : IDisposable - { - public RenderFrame(KeyboardProvider keyboard, bool renderMice, bool renderHeadsets, bool renderGenerics, bool renderMousemats) - { - if (keyboard == null) - return; - - KeyboardBitmap = keyboard.KeyboardBitmap(); - KeyboardBitmap.SetResolution(96, 96); - using (var g = Graphics.FromImage(KeyboardBitmap)) - { - g.Clear(Color.Black); - } - - if (renderMice) - { - MouseBitmap = new Bitmap(10, 10); - MouseBitmap.SetResolution(96, 96); - using (var g = Graphics.FromImage(MouseBitmap)) - { - g.Clear(Color.Black); - } - } - if (renderHeadsets) - { - HeadsetBitmap = new Bitmap(10, 10); - HeadsetBitmap.SetResolution(96, 96); - using (var g = Graphics.FromImage(HeadsetBitmap)) - { - g.Clear(Color.Black); - } - } - if (renderGenerics) - { - GenericBitmap = new Bitmap(10, 10); - GenericBitmap.SetResolution(96, 96); - using (var g = Graphics.FromImage(GenericBitmap)) - { - g.Clear(Color.Black); - } - } - if (renderMousemats) - { - MousematBitmap = new Bitmap(10, 10); - MousematBitmap.SetResolution(96, 96); - using (var g = Graphics.FromImage(MousematBitmap)) - { - g.Clear(Color.Black); - } - } - } - - public Bitmap KeyboardBitmap { get; set; } - public Bitmap MouseBitmap { get; set; } - public Bitmap HeadsetBitmap { get; set; } - public Bitmap GenericBitmap { get; set; } - public Bitmap MousematBitmap { get; set; } - - public void Dispose() - { - KeyboardBitmap?.Dispose(); - MouseBitmap?.Dispose(); - HeadsetBitmap?.Dispose(); - GenericBitmap?.Dispose(); - MousematBitmap?.Dispose(); - } - } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/DeviceVisualModel.cs b/Artemis/Artemis/Models/DeviceVisualModel.cs new file mode 100644 index 000000000..87bae4ea8 --- /dev/null +++ b/Artemis/Artemis/Models/DeviceVisualModel.cs @@ -0,0 +1,63 @@ +using System.Drawing; +using System.Windows; +using System.Windows.Media; +using Artemis.DeviceProviders; +using Artemis.Profiles.Layers.Interfaces; +using Color = System.Drawing.Color; + +namespace Artemis.Models +{ + public class DeviceVisualModel : DrawingVisual + { + private readonly int _x; + private readonly KeyboardProvider _keyboard; + + public DeviceVisualModel(DrawType drawType, int x) + { + _x = x; + + DrawType = drawType; + VisualBitmapScalingMode = BitmapScalingMode.LowQuality; + } + + public DeviceVisualModel(KeyboardProvider keyboard, int x) + { + _x = x; + _keyboard = keyboard; + + DrawType = DrawType.Keyboard; + VisualBitmapScalingMode = BitmapScalingMode.LowQuality; + } + + public DrawType DrawType { get; } + + public Rect RelativeRect => DrawType == DrawType.Keyboard + ? new Rect(_x, 0, _keyboard.Width * 4, _keyboard.Height * 4) + : new Rect(_x, 0, 20, 20); + + public Rect Rect => DrawType == DrawType.Keyboard + ? new Rect(0, 0, _keyboard.Width * 4, _keyboard.Height * 4) + : new Rect(0, 0, 20, 20); + + public Rectangle RelativeRectangle => DrawType == DrawType.Keyboard + ? new Rectangle(_x, 0, _keyboard.Width * 4, _keyboard.Height * 4) + : new Rectangle(_x, 0, 20, 20); + + public Bitmap GetBitmapFromFrame(Bitmap frame) + { + var bitmap = DrawType == DrawType.Keyboard + ? new Bitmap(_keyboard.Width * 4, _keyboard.Height * 4) + : new Bitmap(20, 20); + bitmap.SetResolution(96, 96); + + using (var g = Graphics.FromImage(bitmap)) + { + g.Clear(Color.Black); + g.DrawImage(frame, new Rectangle(0, 0, bitmap.Width, bitmap.Height), RelativeRectangle, + GraphicsUnit.Pixel); + } + + return bitmap; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Models/FrameModel.cs b/Artemis/Artemis/Models/FrameModel.cs new file mode 100644 index 000000000..c3e1a1026 --- /dev/null +++ b/Artemis/Artemis/Models/FrameModel.cs @@ -0,0 +1,109 @@ +using System; +using System.Drawing; +using System.Windows; +using System.Windows.Media; +using Artemis.DeviceProviders; +using Artemis.Profiles.Layers.Interfaces; +using Artemis.Utilities; +using Color = System.Windows.Media.Color; +using Pen = System.Windows.Media.Pen; + +namespace Artemis.Models +{ + public class FrameModel : IDisposable + { + private readonly Rect _rect; + + public FrameModel(KeyboardProvider keyboard, bool renderMice, bool renderHeadsets, bool renderGenerics, + bool renderMousemats) + { + if (keyboard == null) + return; + + // Setup bitmaps + var x = 0; + if (renderMice) + { + MouseModel = new DeviceVisualModel(DrawType.Mouse, x); + x += 20; + } + if (renderHeadsets) + { + HeadsetModel = new DeviceVisualModel(DrawType.Headset, x); + x += 20; + } + if (renderGenerics) + { + GenericModel = new DeviceVisualModel(DrawType.Generic, x); + x += 20; + } + if (renderMousemats) + { + MousematModel = new DeviceVisualModel(DrawType.Mousemat, x); + x += 20; + } + + KeyboardModel = new DeviceVisualModel(keyboard, x); + + // If not rendering anything but keyboard, use keyboard height, else default to 40 + var height = 20; + if (keyboard.Height * 4 > height) + height = keyboard.Height * 4; + _rect = new Rect(0, 0, x + keyboard.Width * 4, height); + } + + public DeviceVisualModel MouseModel { get; } + public DeviceVisualModel HeadsetModel { get; } + public DeviceVisualModel GenericModel { get; } + public DeviceVisualModel MousematModel { get; } + public DeviceVisualModel KeyboardModel { get; } + + public Bitmap KeyboardBitmap { get; private set; } + public Bitmap MouseBitmap { get; private set; } + public Bitmap HeadsetBitmap { get; private set; } + public Bitmap GenericBitmap { get; private set; } + public Bitmap MousematBitmap { get; private set; } + + public void Dispose() + { + KeyboardBitmap?.Dispose(); + MouseBitmap?.Dispose(); + HeadsetBitmap?.Dispose(); + GenericBitmap?.Dispose(); + MousematBitmap?.Dispose(); + } + + public void RenderBitmaps() + { + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) + { + c.PushClip(new RectangleGeometry(_rect)); + c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, _rect); + + if (MouseModel != null) + c.DrawRectangle(new VisualBrush(MouseModel), new Pen(), MouseModel.RelativeRect); + if (HeadsetModel != null) + c.DrawRectangle(new VisualBrush(HeadsetModel), new Pen(), HeadsetModel.RelativeRect); + if (GenericModel != null) + c.DrawRectangle(new VisualBrush(GenericModel), new Pen(), GenericModel.RelativeRect); + if (MousematModel != null) + c.DrawRectangle(new VisualBrush(MousematModel), new Pen(), MousematModel.RelativeRect); + c.DrawRectangle(new VisualBrush(KeyboardModel), new Pen(), KeyboardModel.RelativeRect); + + c.Pop(); + } + + var frameBitmap = ImageUtilities.DrawingVisualToBitmap(visual, _rect); + if (MouseModel != null) + MouseBitmap = MouseModel.GetBitmapFromFrame(frameBitmap); + if (HeadsetModel != null) + HeadsetBitmap = HeadsetModel.GetBitmapFromFrame(frameBitmap); + if (GenericModel != null) + GenericBitmap = GenericModel.GetBitmapFromFrame(frameBitmap); + if (MousematModel != null) + MousematBitmap = MousematModel.GetBitmapFromFrame(frameBitmap); + KeyboardBitmap = KeyboardModel.GetBitmapFromFrame(frameBitmap); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Abstract/ModuleModel.cs b/Artemis/Artemis/Modules/Abstract/ModuleModel.cs index 809865cc5..0404b0d84 100644 --- a/Artemis/Artemis/Modules/Abstract/ModuleModel.cs +++ b/Artemis/Artemis/Modules/Abstract/ModuleModel.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.Windows; using Artemis.DAL; using Artemis.Events; using Artemis.Managers; +using Artemis.Models; using Artemis.Profiles; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -145,7 +145,7 @@ namespace Artemis.Modules.Abstract public abstract void Update(); - public virtual void Render(RenderFrame frame, bool keyboardOnly) + public virtual void Render(FrameModel frameModel, bool keyboardOnly) { if (ProfileModel == null || DataModel == null || DeviceManager.ActiveKeyboard == null) return; @@ -159,44 +159,19 @@ namespace Artemis.Modules.Abstract var preview = PreviewLayers != null; // Render the keyboard layer-by-layer - var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(); - using (var g = Graphics.FromImage(frame.KeyboardBitmap)) - { - ProfileModel?.DrawLayers(g, layers, DrawType.Keyboard, DataModel, keyboardRect, preview); - } + ProfileModel?.DrawLayers(frameModel.KeyboardModel, layers, DataModel, preview); // Render mice layer-by-layer - var devRec = new Rect(0, 0, 10, 10); - if (frame.MouseBitmap != null) - { - using (var g = Graphics.FromImage(frame.MouseBitmap)) - { - ProfileModel?.DrawLayers(g, layers, DrawType.Mouse, DataModel, devRec, preview); - } - } + if (frameModel.MouseModel != null) + ProfileModel?.DrawLayers(frameModel.MouseModel, layers, DataModel, preview); // Render headsets layer-by-layer - if (frame.HeadsetBitmap != null) - { - using (var g = Graphics.FromImage(frame.HeadsetBitmap)) - { - ProfileModel?.DrawLayers(g, layers, DrawType.Headset, DataModel, devRec, preview); - } - } + if (frameModel.HeadsetModel != null) + ProfileModel?.DrawLayers(frameModel.HeadsetModel, layers, DataModel, preview); // Render generic devices layer-by-layer - if (frame.GenericBitmap != null) - { - using (var g = Graphics.FromImage(frame.GenericBitmap)) - { - ProfileModel?.DrawLayers(g, layers, DrawType.Generic, DataModel, devRec, preview); - } - } + if (frameModel.GenericModel != null) + ProfileModel?.DrawLayers(frameModel.GenericModel, layers, DataModel, preview); // Render mousemats layer-by-layer - if (frame.MousematBitmap != null) - { - using (var g = Graphics.FromImage(frame.MousematBitmap)) - { - ProfileModel?.DrawLayers(g, layers, DrawType.Mousemat, DataModel, devRec, preview); - } - } + if (frameModel.MousematModel != null) + ProfileModel?.DrawLayers(frameModel.MousematModel, layers, DataModel, preview); // Trace debugging if (DateTime.Now.AddSeconds(-2) <= _lastTrace || Logger == null) diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs index 5358b8072..34ae2f8b9 100644 --- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs +++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs @@ -13,7 +13,6 @@ namespace Artemis.Modules.Games.RocketLeague private Memory _memory; private GamePointersCollection _pointer; - public RocketLeagueModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager) { Settings = SettingsProvider.Load(); @@ -24,14 +23,14 @@ namespace Artemis.Modules.Games.RocketLeague //var offset = new GamePointersCollection //{ // Game = "RocketLeague", - // GameVersion = "1.26", + // GameVersion = "1.27", // GameAddresses = new List // { // new GamePointer // { // Description = "Boost", - // BasePointer = new IntPtr(0x01666C38), - // Offsets = new[] { 0x58, 0x668, 0x73C, 0x224} + // BasePointer = new IntPtr(0x016D5084), + // Offsets = new[] {0xC4, 0x214, 0x320, 0x73C, 0x224} // } // } //}; @@ -54,7 +53,7 @@ namespace Artemis.Modules.Games.RocketLeague { Updater.GetPointers(); _pointer = SettingsProvider.Load().RocketLeague; - + base.Enable(); } @@ -68,7 +67,7 @@ namespace Artemis.Modules.Games.RocketLeague _memory = new Memory(tempProcess); } - + if (ProfileModel == null || DataModel == null || _memory == null) return; diff --git a/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs b/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs index 03602bf9d..06c45100d 100644 --- a/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs +++ b/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.Windows; using Artemis.DAL; using Artemis.Managers; +using Artemis.Models; using Artemis.Modules.Abstract; using Artemis.Utilities; using Point = System.Windows.Point; @@ -90,9 +91,9 @@ namespace Artemis.Modules.General.Bubbles } } - public override void Render(RenderFrame frame, bool keyboardOnly) + public override void Render(FrameModel frameModel, bool keyboardOnly) { - using (var g = Graphics.FromImage(frame.KeyboardBitmap)) + using (var g = Graphics.FromImage(frameModel.KeyboardBitmap)) { foreach (var bubble in _bubbles) bubble.Draw(g); diff --git a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileDataModel.cs b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileDataModel.cs index 443be1c79..548f568e8 100644 --- a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileDataModel.cs +++ b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileDataModel.cs @@ -70,7 +70,9 @@ namespace Artemis.Modules.General.GeneralProfile [MoonSharpUserData] public class PerformanceDataModel { - public int RAMUsage { get; set; } + public float RamTotal { get; set; } + public float RamUsed { get; set; } + public float RamFree { get; set; } } [MoonSharpUserData] diff --git a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileModel.cs b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileModel.cs index 4f7bea4e5..20421f45a 100644 --- a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileModel.cs +++ b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileModel.cs @@ -63,10 +63,12 @@ namespace Artemis.Modules.General.GeneralProfile private void UpdateDay(GeneralProfileDataModel dataModel) { var now = DateTime.Now; - dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH")); - dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh")); - dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm")); - dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss")); + dataModel.CurrentTime.Hours24 = now.Hour; + dataModel.CurrentTime.Minutes = now.Minute; + dataModel.CurrentTime.Seconds = now.Second; + dataModel.CurrentTime.Hours12 = now.Hour >= 13 + ? now.Hour - 12 + : now.Hour; } #endregion @@ -105,7 +107,7 @@ namespace Artemis.Modules.General.GeneralProfile // Update microphone, only bother with OverallPeak if (_defaultRecording != null) dataModel.Audio.Recording.OverallPeak = _recordingInfo.PeakValue; - + if (_defaultPlayback == null) return; @@ -176,16 +178,16 @@ namespace Artemis.Modules.General.GeneralProfile dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue(); if (_cores[7] != null) dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue(); - - //From Ted - Let's get overall RAM and CPU usage here dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue(); - var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB(); - var tot = PerformanceInfo.GetTotalMemoryInMiB(); - var percentFree = phav / (decimal) tot * 100; - var percentOccupied = 100 - percentFree; - - dataModel.Performance.RAMUsage = (int) percentOccupied; + // Get RAM usage + var memoryStatus = new PerformanceInfo.MEMORYSTATUSEX(); + var gotMemoryStatus = PerformanceInfo.GlobalMemoryStatusEx(memoryStatus); + if (!gotMemoryStatus) + return; + dataModel.Performance.RamTotal = (memoryStatus.ullTotalPhys / 1024f) / 1024f; + dataModel.Performance.RamFree = (memoryStatus.ullAvailPhys / 1024f) / 1024f; + dataModel.Performance.RamUsed = dataModel.Performance.RamTotal - dataModel.Performance.RamFree; } public static PerformanceCounter GetOverallPerformanceCounter() diff --git a/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs b/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs index ef88e7064..be448e3a5 100644 --- a/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs +++ b/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs @@ -4,45 +4,28 @@ using System.Runtime.InteropServices; namespace Artemis.Modules.General.GeneralProfile { internal static class PerformanceInfo - { - [DllImport("psapi.dll", SetLastError = true)] + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class MEMORYSTATUSEX + { + public uint dwLength; + public uint dwMemoryLoad; + public ulong ullTotalPhys; + public ulong ullAvailPhys; + public ulong ullTotalPageFile; + public ulong ullAvailPageFile; + public ulong ullTotalVirtual; + public ulong ullAvailVirtual; + public ulong ullAvailExtendedVirtual; + public MEMORYSTATUSEX() + { + this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); + } + } + + [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation, - [In] int size); - - public static long GetPhysicalAvailableMemoryInMiB() - { - var pi = new PerformanceInformation(); - if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi))) - return Convert.ToInt64(pi.PhysicalAvailable.ToInt64()*pi.PageSize.ToInt64()/1048576); - return -1; - } - - public static long GetTotalMemoryInMiB() - { - var pi = new PerformanceInformation(); - if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi))) - return Convert.ToInt64(pi.PhysicalTotal.ToInt64()*pi.PageSize.ToInt64()/1048576); - return -1; - } - - [StructLayout(LayoutKind.Sequential)] - public struct PerformanceInformation - { - public int Size; - public IntPtr CommitTotal; - public IntPtr CommitLimit; - public IntPtr CommitPeak; - public IntPtr PhysicalTotal; - public IntPtr PhysicalAvailable; - public IntPtr SystemCache; - public IntPtr KernelTotal; - public IntPtr KernelPaged; - public IntPtr KernelNonPaged; - public IntPtr PageSize; - public int HandlesCount; - public int ProcessCount; - public int ThreadCount; - } + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs index 72414dfef..e1a3a7051 100644 --- a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs +++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs @@ -1,6 +1,7 @@ using Artemis.DAL; using Artemis.Events; using Artemis.Managers; +using Artemis.Models; using Artemis.Modules.Abstract; using Artemis.Modules.General.GeneralProfile; using CSCore.CoreAudioAPI; @@ -51,10 +52,10 @@ namespace Artemis.Modules.Overlays.OverlayProfile dataModel.Audio.Volume = _endPointVolume.GetMasterVolumeLevelScalar(); } - public override void Render(RenderFrame frame, bool keyboardOnly) + public override void Render(FrameModel frameModel, bool keyboardOnly) { if (Settings.IsEnabled) - base.Render(frame, keyboardOnly); + base.Render(frameModel, keyboardOnly); } public override void Dispose() diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs index c9d205db3..2396277b4 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs @@ -18,7 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Generic public string Name => "Generic (Logitech)"; public bool ShowInEdtor => false; public DrawType DrawType => DrawType.Generic; - public int DrawScale => 1; + public int DrawScale => 2; public ImageSource DrawThumbnail(LayerModel layer) { diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs index e972efe59..6f965893c 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs @@ -9,7 +9,6 @@ using Artemis.Profiles.Layers.Models; using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels; -using Artemis.ViewModels.Profiles; namespace Artemis.Profiles.Layers.Types.Headset { @@ -18,7 +17,7 @@ namespace Artemis.Profiles.Layers.Types.Headset public string Name => "Headset"; public bool ShowInEdtor => false; public DrawType DrawType => DrawType.Headset; - public int DrawScale => 1; + public int DrawScale => 2; public ImageSource DrawThumbnail(LayerModel layer) { diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs index 865e4277e..700f7c59b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs @@ -9,7 +9,6 @@ using Artemis.Profiles.Layers.Models; using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels; -using Artemis.ViewModels.Profiles; namespace Artemis.Profiles.Layers.Types.Mouse { @@ -18,7 +17,7 @@ namespace Artemis.Profiles.Layers.Types.Mouse public string Name => "Mouse"; public bool ShowInEdtor => false; public DrawType DrawType => DrawType.Mouse; - public int DrawScale => 1; + public int DrawScale => 2; public ImageSource DrawThumbnail(LayerModel layer) { diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs index 6612779eb..3650dc22b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs @@ -9,7 +9,6 @@ using Artemis.Profiles.Layers.Models; using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels; -using Artemis.ViewModels.Profiles; namespace Artemis.Profiles.Layers.Types.Mousemat { @@ -18,7 +17,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat public string Name => "Mousemat"; public bool ShowInEdtor => false; public DrawType DrawType => DrawType.Mousemat; - public int DrawScale => 1; + public int DrawScale => 2; public ImageSource DrawThumbnail(LayerModel layer) { @@ -41,7 +40,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat } // Otherwise draw the rectangle with its applied dimensions and brush - var rect = layerModel.LayerRect(1); + var rect = layerModel.LayerRect(DrawScale); // Can't meddle with the original brush because it's frozen. var brush = layerModel.Brush.Clone(); diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index 75635ea2f..3bd9311b4 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -8,6 +8,7 @@ using System.Windows.Media; using Artemis.DeviceProviders; using Artemis.Events; using Artemis.Managers; +using Artemis.Models; using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -98,44 +99,36 @@ namespace Artemis.Profiles /// /// Draw all the given layers on the given rect /// - /// The graphics to draw on + /// /// The layers to render - /// The type of device to draw for /// The data model to base the layer's properties on - /// A rectangle matching the current keyboard's size on a scale of 4, used for clipping /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties - internal void DrawLayers(Graphics g, List renderLayers, DrawType drawType, ModuleDataModel dataModel, - Rect rect, bool preview) + internal void DrawLayers(DeviceVisualModel deviceVisualModel, List renderLayers, + ModuleDataModel dataModel, bool preview) { - renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList(); + renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == deviceVisualModel.DrawType).ToList(); if (!renderLayers.Any()) return; - var visual = new DrawingVisual(); - using (var c = visual.RenderOpen()) + // Setup the DrawingVisual's size + using (var c = deviceVisualModel.RenderOpen()) { - // Setup the DrawingVisual's size - c.PushClip(new RectangleGeometry(rect)); - c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect); + c.PushClip(new RectangleGeometry(deviceVisualModel.Rect)); + c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, deviceVisualModel.Rect); // Update the layers foreach (var layerModel in renderLayers) layerModel.Update(dataModel, preview, true); - RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null)); + RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, null)); // Draw the layers foreach (var layerModel in renderLayers) layerModel.Draw(dataModel, c, preview, true); - RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c)); + RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, c)); // Remove the clip c.Pop(); } - - using (var bmp = ImageUtilities.DrawingVisualToBitmap(visual, rect)) - { - g.DrawImage(bmp, new PointF(0, 0)); - } } private void RaiseDeviceUpdatedEvent(ProfileDeviceEventsArg e) diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs index 51c699e25..71bc16df9 100644 --- a/Artemis/Artemis/Utilities/ImageUtilities.cs +++ b/Artemis/Artemis/Utilities/ImageUtilities.cs @@ -1,4 +1,5 @@ -using System.Drawing; +using System.Diagnostics; +using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Windows; @@ -66,8 +67,9 @@ namespace Artemis.Utilities // RenderTargetBitmap construction is expensive, only do it when needed if (_rBmp?.PixelHeight != height || _rBmp?.PixelWidth != width) _rBmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); + else + _rBmp.Clear(); - _rBmp.Clear(); _rBmp.Render(visual); return GetBitmap(_rBmp); } diff --git a/Artemis/Artemis/ViewModels/DebugViewModel.cs b/Artemis/Artemis/ViewModels/DebugViewModel.cs index 6a27a94a8..9d6ac8855 100644 --- a/Artemis/Artemis/ViewModels/DebugViewModel.cs +++ b/Artemis/Artemis/ViewModels/DebugViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Managers; +using Artemis.Models; using Artemis.Utilities; using Caliburn.Micro; @@ -123,7 +124,7 @@ namespace Artemis.ViewModels RazerDisplay = drawnDisplay; } - public void DrawFrame(RenderFrame frame) + public void DrawFrame(FrameModel frameModel) { // No point updating the display if the view isn't visible if (!IsActive) @@ -133,17 +134,17 @@ namespace Artemis.ViewModels if (_deviceManager.ActiveKeyboard != null) { var rect = _deviceManager.ActiveKeyboard.KeyboardRectangle(1); - Keyboard = ImageUtilities.BitmapToDrawingImage(frame.KeyboardBitmap, rect); + Keyboard = ImageUtilities.BitmapToDrawingImage(frameModel.KeyboardBitmap, rect); } - if (frame.MouseBitmap != null) - Mouse = ImageUtilities.BitmapToDrawingImage(frame.MouseBitmap, new Rect(0, 0, 10, 10)); - if (frame.HeadsetBitmap != null) - Headset = ImageUtilities.BitmapToDrawingImage(frame.HeadsetBitmap, new Rect(0, 0, 10, 10)); - if (frame.MousematBitmap != null) - Mousemat = ImageUtilities.BitmapToDrawingImage(frame.MousematBitmap, new Rect(0, 0, 10, 10)); - if (frame.GenericBitmap != null) - Generic = ImageUtilities.BitmapToDrawingImage(frame.GenericBitmap, new Rect(0, 0, 10, 10)); + if (frameModel.MouseBitmap != null) + Mouse = ImageUtilities.BitmapToDrawingImage(frameModel.MouseBitmap, new Rect(0, 0, 10, 10)); + if (frameModel.HeadsetBitmap != null) + Headset = ImageUtilities.BitmapToDrawingImage(frameModel.HeadsetBitmap, new Rect(0, 0, 10, 10)); + if (frameModel.MousematBitmap != null) + Mousemat = ImageUtilities.BitmapToDrawingImage(frameModel.MousematBitmap, new Rect(0, 0, 10, 10)); + if (frameModel.GenericBitmap != null) + Generic = ImageUtilities.BitmapToDrawingImage(frameModel.GenericBitmap, new Rect(0, 0, 10, 10)); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml b/Artemis/Artemis/Views/ProfileEditorView.xaml index 313a3eadf..b5166c220 100644 --- a/Artemis/Artemis/Views/ProfileEditorView.xaml +++ b/Artemis/Artemis/Views/ProfileEditorView.xaml @@ -14,15 +14,15 @@ - - - + + + - + @@ -43,7 +43,8 @@ BorderThickness="3" Width="800" Height="400"> - + -