diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 632701d8b..0bd2cfdc5 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -437,6 +437,7 @@ + diff --git a/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs b/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs index b5e812495..501b5917f 100644 --- a/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs +++ b/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs @@ -2,6 +2,7 @@ using Artemis.DeviceProviders.Razer.Utilities; using Corale.Colore.Core; using Corale.Colore.Razer; +using Corale.Colore.Razer.Keyboard; using Constants = Corale.Colore.Razer.Keyboard.Constants; namespace Artemis.DeviceProviders.Razer @@ -42,7 +43,6 @@ namespace Artemis.DeviceProviders.Razer public override void DrawBitmap(Bitmap bitmap) { var razerArray = RazerUtilities.BitmapColorArray(bitmap, Height, Width); - Chroma.Instance.Keyboard.SetCustom(razerArray); } } diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index 135e8a0db..8126601c0 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -155,7 +155,7 @@ namespace Artemis.Managers headset.UpdateDevice(renderEffect.GenerateHeadsetBrush()); // debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e) - _events.PublishOnUIThread(new ChangeBitmap(bitmap)); + //_events.PublishOnUIThread(new ChangeBitmap(bitmap)); } } } diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs index 12b9c2879..4c12adc5d 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs @@ -4,5 +4,14 @@ namespace Artemis.Modules.Games.Overwatch { public class OverwatchDataModel : IGameDataModel { + public OverwatchStatus Status { get; set; } + } + + public enum OverwatchStatus + { + Unkown, + InMainMenu, + InCharacterSelection, + InGame } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs index cbcab9824..8366eaa76 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs @@ -1,25 +1,37 @@ -using System.Drawing; -using System.IO; -using System.IO.MemoryMappedFiles; +using System; +using System.Drawing; +using System.Linq.Dynamic; +using Artemis.Events; using Artemis.Managers; using Artemis.Models; using Artemis.Models.Profiles; +using Artemis.Utilities; +using Artemis.Utilities.DataReaders; +using Caliburn.Micro; using Brush = System.Windows.Media.Brush; +using Color = System.Windows.Media.Color; namespace Artemis.Modules.Games.Overwatch { public class OverwatchModel : GameModel { - public OverwatchModel(MainManager mainManager, OverwatchSettings settings) + private readonly IEventAggregator _events; + + public OverwatchModel(IEventAggregator events, MainManager mainManager, OverwatchSettings settings) : base(mainManager, settings, new OverwatchDataModel()) { + _events = events; Name = "Overwatch"; - ProcessName = "notepad"; + ProcessName = "Overwatch"; Scale = 4; Enabled = Settings.Enabled; Initialized = false; + + MmfReader = new MmfReader("overwatchMmf"); } + public MmfReader MmfReader { get; set; } + public int Scale { get; set; } public override void Dispose() @@ -35,41 +47,27 @@ namespace Artemis.Modules.Games.Overwatch public override void Update() { var gameDataModel = (OverwatchDataModel) GameDataModel; - var mffData = ReadMmf("overwatchMmf"); - if (mffData == null) + var colors = MmfReader.GetColorArray(); + if (colors == null) return; - var data = mffData.Split(' '); - } - private string ReadMmf(string overwatchmff) - { - try + var bitmap = new Bitmap(22, 6); + + using (var g = Graphics.FromImage(bitmap)) { - // opening not-persistent, pagefile-based memory-mapped file - using (var mmf = MemoryMappedFile.OpenExisting(overwatchmff)) + for (var y = 0; y < 6; y++) { - // open the stream to read from the file - using (var stream = mmf.CreateViewStream()) + for (var x = 0; x < 22; x++) { - // Read from the shared memory, just for this example we know there is a string - var reader = new BinaryReader(stream); - var res = string.Empty; - string str; - do - { - str = reader.ReadString(); - if (!string.IsNullOrEmpty(str) && str[0] != 0) - res = res + str; - } while (!string.IsNullOrEmpty(str)); - return res; + g.DrawRectangle(new Pen(ColorHelpers.ToDrawingColor(colors[y, x])), y, x, 1, 1 ); } } } - catch (FileNotFoundException) - { - return null; - //ignored - } + _events.PublishOnUIThread(new ChangeBitmap(bitmap)); + if (colors[0, 0].Equals(Color.FromRgb(55, 30, 0))) + gameDataModel.Status = OverwatchStatus.InMainMenu; + else if (colors[0, 0].Equals(Color.FromRgb(3, 5, 11))) + gameDataModel.Status = OverwatchStatus.InGame; } public override Bitmap GenerateBitmap() diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs index df080abfa..29a853d7f 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs @@ -8,7 +8,7 @@ namespace Artemis.Modules.Games.Overwatch public sealed class OverwatchViewModel : GameViewModel { public OverwatchViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory) - : base(main, new OverwatchModel(main, new OverwatchSettings()), events, pFactory) + : base(main, new OverwatchModel(events, main, new OverwatchSettings()), events, pFactory) { DisplayName = "Overwatch"; MainManager.EffectManager.EffectModels.Add(GameModel); diff --git a/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs b/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs new file mode 100644 index 000000000..7628374e1 --- /dev/null +++ b/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs @@ -0,0 +1,96 @@ +using System; +using System.IO; +using System.IO.MemoryMappedFiles; +using System.Linq; +using System.Text; +using System.Windows.Media; + +namespace Artemis.Utilities.DataReaders +{ + /// + /// A helper class for reading memory managed files + /// + public class MmfReader + { + private DateTime _lastFailure; + + public MmfReader(string mmfName) + { + MmfName = mmfName; + } + + public string MmfName { get; set; } + + /// + /// Turns the MMF into an color array + /// + /// + public Color[,] GetColorArray() + { + var mffString = ReadMmf(MmfName); + if (string.IsNullOrEmpty(mffString)) + return null; + var intermediateArray = mffString.Split('|'); + if (intermediateArray[0] == "1") + return null; + var array = intermediateArray[1].Substring(1).Split(' '); + if (!array.Any()) + return null; + + try + { + var colors = new Color[6, 22]; + foreach (var intermediate in array) + { + if (intermediate.Length > 16) + continue; + + // Can't parse to a byte directly since it may contain values >254 + var parts = intermediate.Split(',').Select(int.Parse).ToArray(); + if (parts[0] >= 5 && parts[1] >= 21) + continue; + + colors[parts[0], parts[1]] = Color.FromRgb((byte) parts[2], (byte) parts[3], (byte) parts[4]); + } + return colors; + } + catch (FormatException) + { + return null; + } + } + + /// + /// Reads the contents of the given MFF into a string + /// + /// + /// + private string ReadMmf(string fileName) + { + // Don't read the file within one second after failing + //if (DateTime.Now - _lastFailure > new TimeSpan(0, 0, 1)) + // return null; + + try + { + using (var mmf = MemoryMappedFile.OpenExisting(fileName)) + { + using (var stream = mmf.CreateViewStream()) + { + using (var binReader = new BinaryReader(stream)) + { + var allBytes = binReader.ReadBytes((int) stream.Length); + return Encoding.UTF8.GetString(allBytes, 0, allBytes.Length); + } + } + } + } + catch (FileNotFoundException) + { + _lastFailure = DateTime.Now; + return null; + //ignored + } + } + } +} \ No newline at end of file diff --git a/Artemis/Razer2Artemis/Logger.cpp b/Artemis/Razer2Artemis/Logger.cpp deleted file mode 100644 index 121fbcaae..000000000 --- a/Artemis/Razer2Artemis/Logger.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair -// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs. - -// The MIT License (MIT) -// -// Copyright (c) 2015 VRocker -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#include "Logger.h" - -#include -#include -#include - - -// Ok this looks butt-ugleh but its just to force the default log level to debug if we compile in debug -#ifdef _DEBUG -LogLevel CLogger::m_eLogLevel = LogLevel::Debug; -#else -LogLevel CLogger::m_eLogLevel = LogLevel::All; -#endif -FILE* CLogger::m_pFile = 0; - -void CLogger::InitLogging(const char* szFile) -{ - if (!m_pFile) - { - m_pFile = fopen(szFile, "a+"); - if (!m_pFile) - { - // Hum, we couldn't open the file for writing - printf("ERROR: Unable to open log file %s.\n", szFile); - } - } -} - -void CLogger::EndLogging(void) -{ - if (m_pFile) - { - fclose(m_pFile); - m_pFile = 0; - } -} - -void CLogger::OutputLog_s(const char* sz, const LogLevel eLevel) -{ - // If the level of this log entry is less important than what we are told to log, just return - if (eLevel < m_eLogLevel) - return; - - // If we don't have a file to write to, bail. - if (!m_pFile) - return; - - char szOutput[512] = { 0 }; - - time_t rawtime; - struct tm* timeinfo; - - time(&rawtime); - timeinfo = localtime(&rawtime); - - // Timestamp the log entry - size_t uiLen = sprintf(szOutput, "<%.2d/%.2d/%.2d - %.2d:%.2d:%.2d> %s\n", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, sz); - - // Write the text to the file - fwrite(szOutput, 1, uiLen, m_pFile); - // Flush the log file to the disk. May move this to a seperate function - fflush(m_pFile); - - // Output the text to any console that may be attached - printf("%s", szOutput); -} - -void CLogger::OutputLog(const char* sz, const LogLevel eLevel, ...) -{ - char szText[1024] = { 0 }; - va_list marker; - va_start(marker, eLevel); - vsprintf(szText, sz, marker); - va_end(marker); - - // Since this function is pretty much the same as the safer function, we'll just redirect it there - OutputLog_s(szText, eLevel); -} - diff --git a/Artemis/Razer2Artemis/Logger.h b/Artemis/Razer2Artemis/Logger.h deleted file mode 100644 index 0b8295fe6..000000000 --- a/Artemis/Razer2Artemis/Logger.h +++ /dev/null @@ -1,82 +0,0 @@ -// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair -// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs. - -// The MIT License (MIT) -// -// Copyright (c) 2015 VRocker -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once -#ifndef _LOGGER_H -#define _LOGGER_H - -#include - -enum class LogLevel -{ - Debug, - All, - Critical, - Warning, - Information, - User, - Internal, - None, - - // Just to force the compiler to treat the enum options as an int - FORCE_32BIT = 0x7fffffff -}; - -class CLogger -{ -public: - static LogLevel GetLogLevel(void) - { - return m_eLogLevel; - } - - static void SetLogLevel(const LogLevel e) - { -#ifndef _DEBUG - if (e == LogLevel::Debug) return; -#endif - m_eLogLevel = e; - } - - static void InitLogging(const char* szFile); - // Always remember to end logging when you are finished otherwise you will have file handles floating around - static void EndLogging(void); - - // Output the text to a log file. - static void OutputLog_s(const char* sz, const LogLevel eLevel); - static void OutputLog(const char* sz, const LogLevel eLevel, ...); - - static FILE* GetFile() - { - return m_pFile; - } - -private: - static LogLevel m_eLogLevel; - static FILE* m_pFile; -}; - -#endif - diff --git a/Artemis/Razer2Artemis/Razer2Artemis.vcxproj b/Artemis/Razer2Artemis/Razer2Artemis.vcxproj index a1fb26458..8ca1563b4 100644 --- a/Artemis/Razer2Artemis/Razer2Artemis.vcxproj +++ b/Artemis/Razer2Artemis/Razer2Artemis.vcxproj @@ -126,11 +126,9 @@ - - diff --git a/Artemis/Razer2Artemis/Razer2Artemis.vcxproj.filters b/Artemis/Razer2Artemis/Razer2Artemis.vcxproj.filters index 82c9ba469..50c0fa71c 100644 --- a/Artemis/Razer2Artemis/Razer2Artemis.vcxproj.filters +++ b/Artemis/Razer2Artemis/Razer2Artemis.vcxproj.filters @@ -23,17 +23,11 @@ Source Files - - Source Files - Header Files - - Header Files - Header Files diff --git a/Artemis/Razer2Artemis/main.cpp b/Artemis/Razer2Artemis/main.cpp index 8383b0a9b..dff201543 100644 --- a/Artemis/Razer2Artemis/main.cpp +++ b/Artemis/Razer2Artemis/main.cpp @@ -1,212 +1,165 @@ -// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair -// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs. - -// The MIT License (MIT) -// -// Copyright (c) 2015 VRocker -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - #include "main.h" #include #include -#include -#define WIN32_LEAN_AND_MEAN #include -#include "Logger.h" - #include -#include TCHAR szName[] = TEXT("overwatchMmf"); TCHAR szMsg[] = TEXT("Message from first process."); -#define BUF_SIZE 2000 + +#define WIN32_LEAN_AND_MEAN +#define BUF_SIZE 4096 static bool g_hasInitialised = false; const char* game = ""; -void cleanup() -{ - CLogger::EndLogging(); -} HANDLE hMapFile; BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID) { - switch (fdwReason) + if (fdwReason == DLL_PROCESS_ATTACH) { - case DLL_PROCESS_ATTACH: - { - atexit(cleanup); + // Get the process that loaded the DLL + TCHAR overwatchFind[] = _T("Overwatch"); + TCHAR szPath[MAX_PATH]; + GetModuleFileName(nullptr, szPath, MAX_PATH); - CLogger::InitLogging("Log.txt"); - CLogger::SetLogLevel(LogLevel::Debug); + if (_tcscmp(szPath, overwatchFind) != 0) + game = "overwatch"; - // Get the process that loaded the DLL - TCHAR overwatchFind[] = _T("Overwatch"); - TCHAR szPath[MAX_PATH]; - GetModuleFileName(nullptr, szPath, MAX_PATH); - - if (_tcscmp(szPath, overwatchFind) != 0) - game = "overwatch"; - - CLogger::OutputLog("Attached to process.", LogLevel::Debug); - - // Setup mmf - hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, BUF_SIZE, szName); - - if (hMapFile == nullptr) - { - CLogger::OutputLog("Could not create file mapping object (error %i)", LogLevel::Debug, GetLastError()); - } - } - break; - - case DLL_PROCESS_DETACH: - { - CLogger::OutputLog_s("Detached from process.", LogLevel::Debug); - CloseHandle(hMapFile); - cleanup(); - } - break; + // Setup mmf + hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, BUF_SIZE, szName); } return true; } -void WriteMmf(const char* msg) +template +std::string string_format(const std::string& format, Args ... args) +{ + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0' + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + + +void WriteMmf(std::string msg) { if (hMapFile == nullptr) { - CLogger::OutputLog_s("Could not write to mmf", LogLevel::Debug); return; } LPCTSTR pBuf; - pBuf = static_cast(MapViewOfFile(hMapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - BUF_SIZE)); + pBuf = static_cast(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE)); if (pBuf == nullptr) { - CLogger::OutputLog("Could not map view of file (error %i)", LogLevel::Debug, GetLastError()); CloseHandle(hMapFile); return; } - CopyMemory((PVOID)pBuf, msg, (_tcslen(msg) * sizeof(TCHAR))); + CopyMemory((PVOID)pBuf, msg.c_str(), msg.size()); UnmapViewOfFile(pBuf); } RZRESULT Init() { - CLogger::OutputLog_s("Razer Init called.", LogLevel::Debug); g_hasInitialised = true; return 0; } RZRESULT UnInit() { - CLogger::OutputLog_s("Razer UnInit called.", LogLevel::Debug); return 0; } RZRESULT CreateEffect(RZDEVICEID DeviceId, ChromaSDK::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - CLogger::OutputLog_s("Razer CreateEffect called.", LogLevel::Debug); return 0; } RZRESULT CreateKeyboardEffect(ChromaSDK::Keyboard::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - std::ostringstream os; - auto keys = *static_cast(pParam); + std::string res = ""; + if (Effect == Keyboard::CHROMA_CUSTOM) { + res += "0|"; + auto keys = *static_cast(pParam); - for (auto y = 0; y < 6; y++) - { - for (auto x = 0; x < 22; x++) + for (auto y = 0; y < 6; y++) { - auto r = (int) GetRValue(keys.Color[y][x]); - auto g = (int) GetGValue(keys.Color[y][x]); - auto b = (int) GetGValue(keys.Color[y][x]); - os << " [" << x << "][" << y << "](" << r << "," << g << "," << b << ")"; + for (auto x = 0; x < 22; x++) + { + auto r = GetRValue(keys.Color[y][x]); + auto g = GetGValue(keys.Color[y][x]); + auto b = GetBValue(keys.Color[y][x]); + res += string_format(" %d,%d,%d,%d,%d", y, x, r, g, b); + } + } + } + else if (Effect == Keyboard::CHROMA_CUSTOM_KEY) { + res += "1|"; + auto keys = *static_cast(pParam); + + for (auto y = 0; y < 6; y++) + { + for (auto x = 0; x < 22; x++) + { + auto r = GetRValue(keys.Color[y][x]); + auto g = GetGValue(keys.Color[y][x]); + auto b = GetBValue(keys.Color[y][x]); + res += string_format(" %d,%d,%d,%d,%d", y, x, r, g, b); + } } } - CLogger::OutputLog_s("Razer CreateKeyboardEffect called", LogLevel::Debug); - WriteMmf(os.str().c_str()); + WriteMmf(res); return 0; } RZRESULT CreateMouseEffect(ChromaSDK::Mouse::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - CLogger::OutputLog_s("Razer CreateMouseEffect called.", LogLevel::Debug); return 0; } RZRESULT CreateHeadsetEffect(ChromaSDK::Headset::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - CLogger::OutputLog_s("Razer CreateHeadsetEffect called.", LogLevel::Debug); return 0; } RZRESULT CreateMousepadEffect(ChromaSDK::Mousepad::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - CLogger::OutputLog_s("Razer CreateMousepadEffect called.", LogLevel::Debug); return 0; } RZRESULT CreateKeypadEffect(ChromaSDK::Keypad::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) { - CLogger::OutputLog_s("Razer CreateKeypadEffect called.", LogLevel::Debug); return 0; } RZRESULT DeleteEffect(RZEFFECTID EffectId) { - CLogger::OutputLog_s("Razer DeleteEffect called.", LogLevel::Debug); return 0; } RZRESULT SetEffect(RZEFFECTID EffectId) { - CLogger::OutputLog_s("Razer SetEffect called.", LogLevel::Debug); return 0; } RZRESULT RegisterEventNotification(HWND hWnd) { - CLogger::OutputLog_s("Razer RegisterEventNotification called.", LogLevel::Debug); return 0; } RZRESULT UnregisterEventNotification() { - CLogger::OutputLog_s("Razer UnregisterEventNotification called.", LogLevel::Debug); return 0; } RZRESULT QueryDevice(RZDEVICEID DeviceId, DEVICE_INFO_TYPE& DeviceInfo) { - CLogger::OutputLog_s("Razer QueryDevice called.", LogLevel::Debug); return 0; } diff --git a/Artemis/Razer2Artemis/utils.cpp b/Artemis/Razer2Artemis/utils.cpp new file mode 100644 index 000000000..bc57d5719 --- /dev/null +++ b/Artemis/Razer2Artemis/utils.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +using namespace std; + +template +string string_format(const std::string& format, Args ... args) +{ + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0' + unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} diff --git a/Artemis/Razer2Artemis/utils.h b/Artemis/Razer2Artemis/utils.h new file mode 100644 index 000000000..2f0482e24 --- /dev/null +++ b/Artemis/Razer2Artemis/utils.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include + +template +std::string string_format(const std::string& format, Args ... args) +{ + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0' + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +}