diff --git a/.gitignore b/.gitignore index 0839667..2e489f4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ build/** # Blacklist specific build directories linuxbuild/ build/ +.idea/ diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 03440bf..95ca22a 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -14,19 +14,9 @@ cmake_minimum_required(VERSION 3.10) project(HarmonyLinkLib VERSION 2.1.1) -include(FetchContent) - -# Fetch fmt library -FetchContent_Declare( - fmt - GIT_REPOSITORY https://github.com/fmtlib/fmt.git - GIT_TAG 10.2.1 # Specify the desired version of {fmt} -) - -FetchContent_MakeAvailable(fmt) - -set_target_properties(fmt PROPERTIES FOLDER External) -set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +# Specify the C++ standard +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) # Find the current Git branch and the last commit timestamp find_package(Git QUIET) @@ -50,10 +40,6 @@ endif() configure_file(include/Version.h.in Version.generated.h) -# Specify the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) - # Define metadata variables set(FILE_DESCRIPTION "Enhances handheld gaming with intelligent hardware recognition, dynamic adaptability, and robust API access for Windows and Linux, including Steam Deck and Wine support.") set(INTERNAL_NAME "HarmonyLinkLib") @@ -66,63 +52,43 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Resources/Version.rc.in ${CMAKE_CURRE # Explicitly list source files set(COMMON_SOURCES - "src/Platform/IPlatformUtilities.cpp" - "src/HarmonyLinkLib.cpp" - "src/Version.cpp" - "src/dllmain.cpp" - "src/Platform/WineUtilities.cpp" - "src/Utilities.cpp" + "src/dllmain.c" + "src/HarmonyLinkLib.c" + "src/Version.c" + + "src/Structs/Battery.c" ) # Explicitly list include files set(COMMON_INCLUDES "include/Core.h" - "include/Structs/FBattery.h" - "include/Structs/FOSVerInfo.h" - "include/Structs/FDevice.h" - "include/Structs/FCPUInfo.h" - "include/Enums/EDevice.h" - "include/Enums/EPlatform.h" - "include/Enums/ESteamDeck.h" - "include/FString.h" "include/HarmonyLinkLib.h" "include/Version.h" - "src/Platform/IPlatformUtilities.h" - "src/Platform/WineUtilities.h" - "src/Utilities.h" -) - -# Adding fmt headers explicitly -set(FMT_HEADERS - "${fmt_SOURCE_DIR}/include/fmt" + + "include/Enums/Device.h" + "include/Enums/Platform.h" + "include/Enums/SteamDeck.h" + + "include/Structs/Battery.h" ) set(WINDOWS_SOURCES - "src/Platform/Windows/WindowsUtilities.cpp" ) set(WINDOWS_INCLUDES - "src/Platform/Windows/WindowsUtilities.h" ) set(LINUX_SOURCES - "src/Platform/Unix/Linux/LinuxUtilities.cpp" - "src/Platform/Unix/UnixUtilities.cpp" ) set(LINUX_INCLUDES - "src/Platform/Unix/Linux/LinuxUtilities.h" - "src/Platform/Unix/UnixUtilities.h" + ) set(MAC_SOURCES - "src/Platform/Unix/Mac/MacUtilities.cpp" - "src/Platform/Unix/UnixUtilities.cpp" ) set(MAC_INCLUDES - "src/Platform/Unix/Mac/MacUtilities.h" - "src/Platform/Unix/UnixUtilities.h" ) # Platform-specific definitions @@ -166,9 +132,6 @@ target_include_directories(HarmonyLinkLibStatic ) target_compile_definitions(HarmonyLinkLibStatic PRIVATE HARMONYLINKLIB_STATIC) -# Include fmt headers -target_include_directories(HarmonyLinkLibStatic PRIVATE ${FMT_HEADERS}) - # Set output directories for all build types foreach(TYPE IN ITEMS DEBUG RELEASE) string(TOUPPER ${TYPE} TYPE_UPPER) @@ -182,10 +145,6 @@ foreach(TYPE IN ITEMS DEBUG RELEASE) ) endforeach() -target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt) -target_link_libraries(HarmonyLinkLibShared PRIVATE fmt) if (UNIX) - target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) - target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) endif() diff --git a/HarmonyLinkLib/include/Enums/EDevice.h b/HarmonyLinkLib/include/Enums/Device.h similarity index 69% rename from HarmonyLinkLib/include/Enums/EDevice.h rename to HarmonyLinkLib/include/Enums/Device.h index c11919d..8ee0946 100644 --- a/HarmonyLinkLib/include/Enums/EDevice.h +++ b/HarmonyLinkLib/include/Enums/Device.h @@ -17,21 +17,15 @@ // Undefine the LINUX macro to avoid conflicts with the enum definition. #undef LINUX -#include - -// Enum class for representing different types of devices -namespace HarmonyLinkLib +typedef enum { - enum class EDevice : uint8_t - { - UNKNOWN, - DESKTOP, - LAPTOP, - HANDHELD, + EDevice_UNKNOWN, + EDevice_DESKTOP, + EDevice_LAPTOP, + EDevice_HANDHELD, - STEAM_DECK, - // ROG_ALLY - // AYONEO_SLIDE - // etc... - }; -} + EDevice_STEAM_DECK, + // EDevice_ROG_ALLY + // EDevice_AYONEO_SLIDE + // etc... +} EDevice; diff --git a/HarmonyLinkLib/include/Enums/ESteamDeck.h b/HarmonyLinkLib/include/Enums/ESteamDeck.h deleted file mode 100644 index 9fbad64..0000000 --- a/HarmonyLinkLib/include/Enums/ESteamDeck.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -// Enum class for representing different types of devices -namespace HarmonyLinkLib -{ - enum class ESteamDeck : uint8_t - { - NONE, // Device is not a steam deck - UNKNOWN, // Device is a steam deck but model cannot be determined - LCD, - OLED, - }; -} diff --git a/HarmonyLinkLib/src/Version.cpp b/HarmonyLinkLib/include/Enums/Platform.h similarity index 80% rename from HarmonyLinkLib/src/Version.cpp rename to HarmonyLinkLib/include/Enums/Platform.h index d340da1..c077d8c 100644 --- a/HarmonyLinkLib/src/Version.cpp +++ b/HarmonyLinkLib/include/Enums/Platform.h @@ -12,4 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "Version.h" +#pragma once + +typedef enum +{ + EPlatform_UNKNOWN, + EPlatform_WINDOWS, + EPlatform_LINUX, + EPlatform_MAC, + EPlatform_UNIX, +} EPlatform; diff --git a/HarmonyLinkLib/include/HarmonyLinkStruct.h b/HarmonyLinkLib/include/Enums/SteamDeck.h similarity index 71% rename from HarmonyLinkLib/include/HarmonyLinkStruct.h rename to HarmonyLinkLib/include/Enums/SteamDeck.h index 362750b..142504e 100644 --- a/HarmonyLinkLib/include/HarmonyLinkStruct.h +++ b/HarmonyLinkLib/include/Enums/SteamDeck.h @@ -14,14 +14,10 @@ #pragma once -struct HarmonyLinkStruct +typedef enum { - // Virtual destructor is important for proper cleanup of derived types - virtual ~HarmonyLinkStruct() = default; - - // Method to deallocate the object - void free() const - { - delete this; - } -}; + ESteamDeck_NONE, // Device is not a steam deck + ESteamDeck_UNKNOWN, // Device is a steam deck but model cannot be determined + ESteamDeck_LCD, + ESteamDeck_OLED, +} ESteamDeck; diff --git a/HarmonyLinkLib/include/FString.h b/HarmonyLinkLib/include/FString.h deleted file mode 100644 index 68ae766..0000000 --- a/HarmonyLinkLib/include/FString.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include -#include - -#include "Core.h" // Replace with actual API export macro - -/** - * @file FString.h - * @brief FString Class - Custom String Management for DLL Export - * - * The FString class is a custom string management class designed to safely encapsulate - * string handling and memory management, especially for use in DLLs (Dynamic Link Libraries). - * It resolves the common issue of exporting classes containing standard library types, - * such as std::string, across DLL boundaries, which can lead to compiler warnings or errors. - * - * Features: - * - Implements basic string operations such as construction, destruction, copy, and move semantics. - * - Utilizes smart pointers (std::unique_ptr) for automatic memory management, reducing the risk of memory leaks. - * - Provides a simple interface for interacting with character strings, similar to std::string. - * - Includes both deep copy semantics for safety and move semantics for performance in object transfers. - * - * Usage: - * FString can be used as a safer alternative to std::string for classes that are exported from a DLL. - * It handles memory allocation/deallocation automatically and provides a basic set of string operations. - * - * Example: - * FString myString("Hello, world!"); - * std::cout << myString.c_str() << std::endl; // Output: Hello, world! - * - * Note: - * - The class is currently designed with basic functionality. Additional features such as - * string concatenation, substring, and comparison operations can be added as needed. - * - Ensure that the HarmonyLinkLibApi.h (or equivalent) file correctly defines the export macro - * for DLL usage. - * - */ - namespace HarmonyLinkLib - { - class HARMONYLINKLIB_API FString { - public: - FString() : data_(new char[1]) { - data_[0] = '\0'; - } - - FString(const char* str) { - const size_t len = strlen(str); - data_ = new char[len + 1]; - memcpy(data_, str, len + 1); - } - - // Copy constructor - FString(const FString& other) { - const size_t len = strlen(other.data_); - data_ = new char[len + 1]; - memcpy(data_, other.data_, len + 1); - } - - ~FString() { - delete[] data_; - } - - // Copy assignment operator - FString& operator=(const FString& other) { - if (this != &other) { - delete[] data_; - const size_t len = strlen(other.data_); - data_ = new char[len + 1]; - memcpy(data_, other.data_, len + 1); - } - return *this; - } - - // Concatenation operator for FString objects - FString operator+(const FString& other) const { - size_t thisLen = strlen(this->data_); - size_t otherLen = strlen(other.data_); - char* concatenated = new char[thisLen + otherLen + 1]; - - memcpy(concatenated, this->data_, thisLen); - memcpy(concatenated + thisLen, other.data_, otherLen + 1); - - FString result(concatenated); - delete[] concatenated; - return result; - } - - // Concatenation operator for const char* - FString operator+(const char* other) const { - return *this + FString(other); - } - - // Friend function to allow concatenation with const char* on the left-hand side - friend FString operator+(const char* lhs, const FString& rhs) { - return FString(lhs) + rhs; - } - - // Move constructor - FString(FString&& other) noexcept : data_(other.data_) { - other.data_ = nullptr; - } - - FString(const std::string& str) { - const size_t len = str.length(); - data_ = new char[len + 1]; - memcpy(data_, str.c_str(), len + 1); - } - - // Move assignment operator - FString& operator=(FString&& other) noexcept { - if (this != &other) { - delete[] data_; - data_ = other.data_; - other.data_ = nullptr; - } - return *this; - } - - bool operator==(const FString& other) const { - return strcmp(data_, other.data_) == 0; - } - - // Method to get a lowercase version of the string - static FString to_lower(FString& from) - { - for (size_t i = 0; i < strlen(from.data_); ++i) { - from.data_[i] = static_cast(std::tolower(static_cast(from.data_[i]))); - } - return from; - } - - // Overloaded static method to handle const char* - static FString to_lower(const char* from) { - FString temp_string(from); // Create an FString from const char* - return to_lower(temp_string); // Reuse the existing to_lower method - } - - const char* c_str() const { - return data_; - } - - private: - char* data_ = nullptr; - }; - } - -namespace std { - template<> - struct hash { - size_t operator()(const HarmonyLinkLib::FString& s) const { - size_t hashValue = 5381; // Starting value recommended by the djb2 algorithm - const char* str = s.c_str(); - - for (size_t i = 0; str[i] != '\0'; ++i) { - hashValue = ((hashValue << 5) + hashValue) + static_cast(str[i]); - // Equivalent to hashValue * 33 + str[i] - } - - return hashValue; - } - }; -} diff --git a/HarmonyLinkLib/include/HarmonyLinkLib.h b/HarmonyLinkLib/include/HarmonyLinkLib.h index d6575a5..9930ffd 100644 --- a/HarmonyLinkLib/include/HarmonyLinkLib.h +++ b/HarmonyLinkLib/include/HarmonyLinkLib.h @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Jordon Brooks +// Copyright (c) 2024 Jordon Brooks // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,49 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. - -/** - * IMPORTANT REMINDER: - * Do NOT use standard output functions like std::cout and printf anywhere in this codebase. - * - * Reason: - * Unreal Engine 5's packaging tool encounters issues with these functions, leading to - * packaging failures. The engine sets stdout to UTF-8, which can cause conflicts with - * these standard functions, resulting in a "SECURE CRT: Invalid parameter detected" error - * during packaging. - * - * This issue once required an extensive debugging effort that lasted over 8 hours. - * To prevent similar issues in the future and ensure smooth packaging, always use - * wide-character versions of these functions, such as wprintf and std::wcout, when working - * within the DLL. These functions are compatible with the UTF-8 setting in Unreal Engine 5. - * - */ - - #pragma once +#include #include "Core.h" -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FDevice.h" -#include "Structs/FOSVerInfo.h" - -class IPlatformUtilities; - -namespace HarmonyLinkLib -{ - extern "C" HARMONYLINKLIB_API bool get_is_wine(); - - extern "C" HARMONYLINKLIB_API bool get_is_linux(); - - extern "C" HARMONYLINKLIB_API bool get_is_docked(); - - extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info(); - - extern "C" HARMONYLINKLIB_API FDevice* get_device_info(); - - extern "C" HARMONYLINKLIB_API FOSVerInfo* get_os_version(); - - extern "C" HARMONYLINKLIB_API FBattery* get_battery_status(); -} +HARMONYLINKLIB_API bool HarmonyLink_Init(void); diff --git a/HarmonyLinkLib/include/Enums/EPlatform.h b/HarmonyLinkLib/include/Structs/Battery.h similarity index 72% rename from HarmonyLinkLib/include/Enums/EPlatform.h rename to HarmonyLinkLib/include/Structs/Battery.h index ffa2be7..0ee37b3 100644 --- a/HarmonyLinkLib/include/Enums/EPlatform.h +++ b/HarmonyLinkLib/include/Structs/Battery.h @@ -14,17 +14,16 @@ #pragma once -#include +#include -// Enum class for representing different operating platforms -namespace HarmonyLinkLib +#include "Core.h" + +typedef struct { - enum class EPlatform : uint8_t - { - UNKNOWN, - WINDOWS, - LINUX, - MAC, - UNIX, - }; -} + bool has_battery; + bool is_connected_to_ac; + unsigned char battery_percent; +} FBattery; + +HARMONYLINKLIB_API void FBattery_print(const FBattery* self); + diff --git a/HarmonyLinkLib/include/Structs/FBattery.h b/HarmonyLinkLib/include/Structs/FBattery.h deleted file mode 100644 index 3a40095..0000000 --- a/HarmonyLinkLib/include/Structs/FBattery.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include - -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FBattery : HarmonyLinkStruct - { - bool has_battery; - bool is_connected_to_ac; - uint8_t battery_percent; - - void to_string() const { - std::wcout << "Battery present: " << (has_battery ? "'Yes'" : "'No'") << '\n'; - std::wcout << "Connected to AC: " << (is_connected_to_ac ? "'Yes'" : "'No'") << '\n'; - std::wcout << "Battery percent: '" << static_cast(battery_percent) << "%'" << '\n'; - } - }; -} diff --git a/HarmonyLinkLib/include/Structs/FCPUInfo.h b/HarmonyLinkLib/include/Structs/FCPUInfo.h deleted file mode 100644 index 827bc40..0000000 --- a/HarmonyLinkLib/include/Structs/FCPUInfo.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include -#include "FString.h" - -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FCPUInfo : HarmonyLinkStruct - { - FString VendorID; - FString Model_Name; - uint32_t Physical_Cores = 0; - uint32_t Logical_Cores = 0; - std::unordered_set Flags; - - void print() const - { - wprintf(L"VendorID: '%hs'\n", VendorID.c_str()); - wprintf(L"Model_Name: '%hs'\n", Model_Name.c_str()); - wprintf(L"Physical_Cores: '%d'\n", Physical_Cores); - wprintf(L"Logical_Cores: '%d'\n", Logical_Cores); - - // Initialize a string to hold all flags - std::string allFlags; - for (const auto& flag : Flags) { - allFlags += std::string(flag.c_str()) + " "; // Append each flag followed by a space - } - - // Remove the trailing space - if (!allFlags.empty()) { - allFlags.pop_back(); - } - - wprintf(L"Flags: '%hs'\n", allFlags.c_str()); - } - }; -} diff --git a/HarmonyLinkLib/include/Structs/FDevice.h b/HarmonyLinkLib/include/Structs/FDevice.h deleted file mode 100644 index b574d6a..0000000 --- a/HarmonyLinkLib/include/Structs/FDevice.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -#include "Enums/EDevice.h" -#include "Enums/EPlatform.h" -#include "Enums/ESteamDeck.h" - -namespace HarmonyLinkLib -{ - // Struct to represent a specific device with both platform and device type - struct FDevice : HarmonyLinkStruct - { - EPlatform platform = EPlatform::UNKNOWN; - EDevice device = EDevice::UNKNOWN; - ESteamDeck steam_deck_model = ESteamDeck::NONE; - }; -} diff --git a/HarmonyLinkLib/include/Structs/FOSVerInfo.h b/HarmonyLinkLib/include/Structs/FOSVerInfo.h deleted file mode 100644 index a308a22..0000000 --- a/HarmonyLinkLib/include/Structs/FOSVerInfo.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "FString.h" -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FOSVerInfo : HarmonyLinkStruct { - // 'name' represents the operating system's name, e.g., "Ubuntu" in Linux or "Windows" in Windows systems. - FString name; - - // 'version' is a numerical representation of the OS version. In Linux, it might be the kernel version, - // whereas in Windows, it could be the major version number like 10 for Windows 10. - uint32_t version = 0; - - // 'id' is a unique identifier for the OS. In Linux, it might be a lower-case string like "ubuntu". - // In Windows, this could map to the edition ID, such as "Professional". - FString id; - - // 'version_id' is a string representing the specific version of the OS. - // For example, "20.04" in Ubuntu or "1909" in Windows 10. - FString version_id; - - // 'version_codename' is a codename for the OS version, if available. - // This is common in Linux distributions (e.g., "focal" for Ubuntu 20.04) but not typically used in Windows. - FString version_codename; - - // 'pretty_name' is a more readable version of the name, potentially including the version and codename. - // For example, "Ubuntu 20.04 LTS (Focal Fossa)" or "Windows 10 Pro". - FString pretty_name; - - // 'variant_id' is an identifier for the specific variant of the OS, if available. - // For example, in Linux distributions, this might be "desktop" for the desktop edition, - // "server" for the server edition, or "core" for a minimal installation. It helps distinguish - // between different flavors or editions of the same version. - // On the Steam Deck, this is set to "steamdeck". - FString variant_id; - - void print() const - { - wprintf(L"Name: '%hs'\n", name.c_str()); - wprintf(L"Version: '%d'\n", version); - wprintf(L"ID: '%hs'\n", id.c_str()); - wprintf(L"Version ID: '%hs'\n", version_id.c_str()); - wprintf(L"Version Codename: '%hs'\n", version_codename.c_str()); - wprintf(L"Pretty Name: '%hs'\n", pretty_name.c_str()); - wprintf(L"Variant ID: '%hs'\n", variant_id.c_str()); - } -}; -} diff --git a/HarmonyLinkLib/include/Version.h b/HarmonyLinkLib/include/Version.h index dcc9d33..74f6179 100644 --- a/HarmonyLinkLib/include/Version.h +++ b/HarmonyLinkLib/include/Version.h @@ -14,45 +14,11 @@ #pragma once +#include #include "Core.h" -#include -#include "FString.h" - -namespace HarmonyLinkLib -{ - class HARMONYLINKLIB_API version - { - public: - version() = default; - - static FString ToString() - { - return HARMONYLINK_VERSION; - } - - static FString get_build_timestamp() - { - return {__TIMESTAMP__}; - } - - static FString get_git_branch() - { - return {GIT_BRANCH_NAME}; - } - - static FString get_git_commit_timestamp() - { - return {GIT_COMMIT_TIMESTAMP}; - } - - static bool is_debug() - { -#ifdef DEBUG_MODE - return true; -#else - return false; -#endif - } - }; -} +HARMONYLINKLIB_API char* get_version_string(void); +HARMONYLINKLIB_API char* get_version_build_timestamp(void); +HARMONYLINKLIB_API char* get_git_branch(void); +HARMONYLINKLIB_API char* get_git_commit_timestamp(void); +HARMONYLINKLIB_API bool get_is_debug(void); diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.c similarity index 54% rename from HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp rename to HarmonyLinkLib/src/HarmonyLinkLib.c index 490e869..9d1f950 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp +++ b/HarmonyLinkLib/src/HarmonyLinkLib.c @@ -12,27 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "LinuxUtilities.h" +#include "HarmonyLinkLib.h" +#include +#include "Version.h" -#include -#include -#include "Platform/WineUtilities.h" - -namespace HarmonyLinkLib +bool HarmonyLink_Init(void) { - std::shared_ptr LinuxUtilities::get_battery_status() - { - return WineUtilities::get_battery_status(); - } - - std::shared_ptr LinuxUtilities::get_os_version() - { - return WineUtilities::get_linux_info(); - } - - std::shared_ptr LinuxUtilities::get_cpu_info() - { - return WineUtilities::get_cpu_info(); - } + wprintf(L"HarmonyLink V%hs Copyright (C) 2023 Jordon Brooks\n", get_version_string()); + wprintf(L"Build Timestamp: %hs\n", get_version_build_timestamp()); + wprintf(L"Git Branch: %hs\n", get_git_branch()); + wprintf(L"Git Commit Timestamp: %hs\n", get_git_commit_timestamp()); + wprintf(L"Build type: %ls\n", get_is_debug() ? L"True" : L"False"); + return 1; } diff --git a/HarmonyLinkLib/src/HarmonyLinkLib.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.cpp deleted file mode 100644 index 91ccc2c..0000000 --- a/HarmonyLinkLib/src/HarmonyLinkLib.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "HarmonyLinkLib.h" - -#include -#include "Platform/IPlatformUtilities.h" - -namespace HarmonyLinkLib -{ - std::shared_ptr PlatformUtilities = IPlatformUtilities::GetInstance(); - - bool get_is_wine() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_running_under_wine(); - } - - bool get_is_linux() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_linux(); - } - - bool get_is_docked() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_docked(); - } - - FCPUInfo* get_cpu_info() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr cpu_info = PlatformUtilities->get_cpu_info(); - if (!cpu_info) - { - return nullptr; - } - - FCPUInfo* new_cpu_info = new FCPUInfo(*cpu_info); - return new_cpu_info; - } - - FDevice* get_device_info() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr device = PlatformUtilities->get_device(); - if (!device) - { - return nullptr; - } - - FDevice* new_device = new FDevice(*device); - return new_device; - } - - FOSVerInfo* get_os_version() - { - - - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr os_version_info = PlatformUtilities->get_os_version(); - if (!os_version_info) - { - return nullptr; - } - - FOSVerInfo* new_os_info = new FOSVerInfo(*os_version_info); - return new_os_info; - } - - FBattery* get_battery_status() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr new_battery = PlatformUtilities->get_battery_status(); - if (!new_battery) - { - return nullptr; - } - - FBattery* battery = new FBattery(*new_battery); - return battery; - } -} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp deleted file mode 100644 index 735eeab..0000000 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "IPlatformUtilities.h" - -#include -#include -#include - -#include "Utilities.h" - -#include "WineUtilities.h" -#if BUILD_WINDOWS -#include "Windows/WindowsUtilities.h" -#elif BUILD_LINUX -#include "Unix/Linux/LinuxUtilities.h" -#elif BUILD_MAC -#include "Unix/Mac/MacUtilities.h" -#elif BUILD_UNIX -#include "Unix/Mac/MacUtilities.h" -#endif - -namespace HarmonyLinkLib -{ - static std::shared_ptr INSTANCE = nullptr; - - std::shared_ptr& IPlatformUtilities::GetInstance() - { - if (!INSTANCE) - { - #if BUILD_WINDOWS - INSTANCE = std::make_shared(); - #elif BUILD_LINUX - INSTANCE = std::make_shared(); - #elif BUILD_MAC - INSTANCE = std::make_shared(); - #elif BUILD_UNIX - INSTANCE = std::make_shared(); - // ... other platform checks - #else - std::wcout << "Platform is not supported.\n" - #endif - } - - return INSTANCE; - } - - bool IPlatformUtilities::is_running_under_wine() - { - return WineUtilities::is_wine_present(); - } - - bool IPlatformUtilities::is_linux() - { - #ifdef BUILD_LINUX - return true; - #else - return is_running_under_wine(); - #endif - } - - bool IPlatformUtilities::is_steam_deck() - { - const std::shared_ptr device = get_device(); - - return device && device->device == EDevice::STEAM_DECK; - } - - bool IPlatformUtilities::is_docked() - { - static constexpr uint8_t CHARGING_SCORE = 3; - static constexpr uint8_t EXTERNAL_MONITOR_SCORE = 4; - static constexpr uint8_t STEAM_DECK_RESOLUTION_SCORE = 3; - static constexpr uint8_t KEYBOARD_DETECTION_SCORE = 1; - static constexpr uint8_t MOUSE_DETECTION_SCORE = 2; - static constexpr uint8_t CONTROLLER_DETECTION_SCORE = 3; - static constexpr uint8_t FINAL_TARGET_DETECTION_SCORE = 9; - - - const std::shared_ptr device = get_device(); - - if (!device) - { - std::wcout << "Error: failed to get device.\n"; - return false; - } - - if (device->device != EDevice::STEAM_DECK) - { - std::wcout << "Error: Dock detection is currently only supported on Steam Decks.\n"; - return false; - } - - uint8_t score = 0; - - Utilities::DebugPrint("Detected: ", false); - - if (is_charging()) - { - Utilities::DebugPrint("Charging, ", false); - score += CHARGING_SCORE; - } - - if (get_is_external_monitor_connected()) - { - Utilities::DebugPrint("External monitor, ", false); - score += EXTERNAL_MONITOR_SCORE; - } - - if (get_is_steam_deck_native_resolution()) - { - Utilities::DebugPrint("Non-native resolution, ", false); - score += STEAM_DECK_RESOLUTION_SCORE; - } - - if (get_keyboard_detected()) - { - Utilities::DebugPrint("keyboard ", false); - score += KEYBOARD_DETECTION_SCORE; - } - - if (get_mouse_detected()) - { - Utilities::DebugPrint("mouse, ", false); - score += MOUSE_DETECTION_SCORE; - } - - if (get_external_controller_detected()) - { - Utilities::DebugPrint("external controller, ", false); - score += CONTROLLER_DETECTION_SCORE; - } - - Utilities::DebugPrint(fmt::format("Score: {}/{}", score, FINAL_TARGET_DETECTION_SCORE).c_str()); - - return score >= FINAL_TARGET_DETECTION_SCORE; - } - - std::shared_ptr IPlatformUtilities::get_device() - { - FDevice new_device; - - if (is_linux()) - { - new_device.platform = EPlatform::LINUX; - } - else - { - new_device.platform = EPlatform::WINDOWS; - } - - const std::shared_ptr battery_status = get_battery_status(); - - if (battery_status && !battery_status->has_battery) - { - new_device.device = EDevice::DESKTOP; - } - else - { - new_device.device = EDevice::LAPTOP; - } - - const ESteamDeck steam_deck_model = detect_steam_deck(new_device); - - if (steam_deck_model != ESteamDeck::NONE) { - new_device.device = EDevice::STEAM_DECK; - new_device.steam_deck_model = steam_deck_model; - } - return std::make_shared(new_device); - } - - // Helper function to check if the device is a Steam Deck - ESteamDeck IPlatformUtilities::detect_steam_deck(const FDevice& device) { - // Check if the device is already identified as a Steam Deck - if (device.device == EDevice::STEAM_DECK && device.steam_deck_model != ESteamDeck::NONE) { - return device.steam_deck_model; - } - - ESteamDeck steam_deck_model = ESteamDeck::NONE; - - // Retrieve and process CPU information - const std::shared_ptr cpu_info = get_cpu_info(); - if (!cpu_info) { - wprintf(L"CPU information not available.\n"); - } else { - // Convert the CPU model name to lower case once - FString cpu_model_lower = FString::to_lower(cpu_info->Model_Name); - - // Map of CPU models to their corresponding Steam Deck models - static const std::unordered_map model_map = { - {FString::to_lower("amd custom apu 0405"), ESteamDeck::LCD}, - {FString::to_lower("amd custom apu 0932"), ESteamDeck::OLED} - }; - - auto iterator = model_map.find(cpu_model_lower); - if (iterator != model_map.end()) { - steam_deck_model = iterator->second; - wprintf(L"Steam Deck detected by CPU model name: %hs.\n", cpu_model_lower.c_str()); - } - } - - // Check for Steam Deck by OS version only if no model has been detected yet - if (steam_deck_model == ESteamDeck::NONE) - { - if (const std::shared_ptr version = get_os_version()) - { - if (version->variant_id == "steamdeck" && version->name == "SteamOS") - { - // Use UNKNOWN if OS matches but CPU model doesn't fit known profiles - steam_deck_model = ESteamDeck::UNKNOWN; - wprintf(L"Steam Deck OS detected but model is unknown.\n"); - } - } - else - { - wprintf(L"OS version information not available.\n"); - } - } - - return steam_deck_model; - } - - bool IPlatformUtilities::is_connected_to_ac() - { - const std::shared_ptr battery = get_battery_status(); - return battery && battery->is_connected_to_ac; - } - - bool IPlatformUtilities::is_charging() - { - const std::shared_ptr battery = get_battery_status(); - return battery && battery->has_battery && battery->is_connected_to_ac; - } -} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h deleted file mode 100644 index e6f034f..0000000 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Enums/ESteamDeck.h" -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FDevice.h" -#include "Structs/FOSVerInfo.h" - -namespace HarmonyLinkLib -{ - class IPlatformUtilities { - public: - static std::shared_ptr& GetInstance(); - - IPlatformUtilities() = default; - IPlatformUtilities(const IPlatformUtilities& other) = default; - IPlatformUtilities(IPlatformUtilities&& other) = default; - IPlatformUtilities& operator=(const IPlatformUtilities& other) = default; - IPlatformUtilities& operator=(IPlatformUtilities&& other) = default; - virtual ~IPlatformUtilities() = default; - - // General OS-level functions - virtual bool is_running_under_wine(); - virtual bool is_linux(); - virtual bool is_steam_deck(); - virtual bool is_docked(); - - virtual std::shared_ptr get_device(); - virtual std::shared_ptr get_cpu_info() = 0; - virtual std::shared_ptr get_battery_status() = 0; - virtual std::shared_ptr get_os_version() = 0; - virtual bool get_is_external_monitor_connected() = 0; - virtual bool get_keyboard_detected() = 0; - virtual bool get_mouse_detected() = 0; - virtual bool get_external_controller_detected() = 0; - virtual bool get_is_steam_deck_native_resolution() = 0; - //virtual bool get_is_ethernet_connected() = 0; - //virtual bool get_is_external_input_detected() = 0; - - ESteamDeck detect_steam_deck(const FDevice& device); - bool is_connected_to_ac(); - bool is_charging(); - - // Add more virtual functions for other OS interactions here - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h deleted file mode 100644 index ee1f516..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Structs/FOSVerInfo.h" - -#include "Platform/Unix/UnixUtilities.h" - -namespace HarmonyLinkLib -{ - class LinuxUtilities : public UnixUtilities { - public: - // Implementation for other Linux-specific functions - std::shared_ptr get_battery_status() override; - - std::shared_ptr get_os_version() override; - - std::shared_ptr get_cpu_info() override; - - bool is_linux() override - { - return true; - } - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp deleted file mode 100644 index 0d3b777..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "UnixUtilities.h" - -namespace HarmonyLinkLib -{ - bool UnixUtilities::is_running_under_wine() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return false; - } - - std::shared_ptr UnixUtilities::get_cpu_info() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - std::shared_ptr UnixUtilities::get_battery_status() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - std::shared_ptr UnixUtilities::get_os_version() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - bool UnixUtilities::get_is_external_monitor_connected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_keyboard_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_mouse_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_external_controller_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_is_steam_deck_native_resolution() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } -} \ No newline at end of file diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h deleted file mode 100644 index 8a06546..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Platform/IPlatformUtilities.h" -namespace HarmonyLinkLib -{ - // This is more of a "catch all" for all unix-based systems - // that don't have their own implementations. - class UnixUtilities : public IPlatformUtilities { - public: - bool is_running_under_wine() override; - - std::shared_ptr get_cpu_info() override; - std::shared_ptr get_battery_status() override; - std::shared_ptr get_os_version() override; - - bool get_is_external_monitor_connected() override; - - bool get_keyboard_detected() override; - - bool get_mouse_detected() override; - - bool get_external_controller_detected() override; - - bool get_is_steam_deck_native_resolution() override; - - // Implementation for other Unix/Linux-specific functions - }; -} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp deleted file mode 100644 index dfd7aa8..0000000 --- a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "WindowsUtilities.h" - -#include -#include - -#include -#pragma comment(lib, "XInput.lib") - -#include "Platform/WineUtilities.h" -#include - -namespace HarmonyLinkLib -{ - std::shared_ptr WindowsUtilities::get_battery_status() - { - if (is_linux()) - { - return WineUtilities::get_battery_status(); - } - FBattery result; - - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) { - result.has_battery = status.BatteryFlag != 128; // 128 indicates no battery - result.is_connected_to_ac = status.ACLineStatus == 1; - result.battery_percent = result.has_battery ? status.BatteryLifePercent : 0; - } else { - std::wcout << "Failed to get power statistics.\n"; - } - - return std::make_shared(result); - } - - std::shared_ptr WindowsUtilities::get_cpu_info() - { - if (is_linux()) - { - return WineUtilities::get_cpu_info(); - } - - return {}; - } - - std::shared_ptr WindowsUtilities::get_os_version() - { - if (is_linux()) - { - return WineUtilities::get_linux_info(); - } - - OSVERSIONINFOEX os_version_info; - ZeroMemory(&os_version_info, sizeof(OSVERSIONINFOEX)); - os_version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - if (!GetVersionEx(reinterpret_cast(&os_version_info))) { - // Handle error if needed - return nullptr; - } - - FOSVerInfo os_version; - - HKEY h_key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_READ, &h_key) == ERROR_SUCCESS) - { - DWORD dw_size; - DWORD dw_type; - char sz_product_name[256]; - dw_size = sizeof(sz_product_name); - if (RegQueryValueEx(h_key, TEXT("ProductName"), nullptr, &dw_type, reinterpret_cast(sz_product_name), &dw_size) == ERROR_SUCCESS) - { - os_version.pretty_name = sz_product_name; - } - RegCloseKey(h_key); - } - - std::stringstream version; - version << os_version_info.dwMajorVersion << "." << os_version_info.dwMinorVersion; - os_version.version_id = version.str(); - - os_version.name = "Windows"; - os_version.version = os_version_info.dwBuildNumber; // Build number as the version - - return std::make_shared(os_version); - } - - bool WindowsUtilities::get_is_external_monitor_connected() - { - // SM_CMONITORS returns the count of all display monitors. - const int monitorCount = GetSystemMetrics(SM_CMONITORS); - - // More than one monitor implies an external monitor is connected. - return monitorCount > 1; - } - - bool WindowsUtilities::get_keyboard_detected() - { - UINT n_devices; - std::vector devices; - - GetRawInputDeviceList(devices.data(), &n_devices, sizeof(RAWINPUTDEVICELIST)); - - if (n_devices == 0) - { - return false; - } - - return std::any_of(devices.begin(), devices.end(), [](const RAWINPUTDEVICELIST& device) - { - return device.dwType == RIM_TYPEKEYBOARD; - }); - } - - bool WindowsUtilities::get_mouse_detected() - { - UINT n_devices; - std::vector devices; - - GetRawInputDeviceList(devices.data(), &n_devices, sizeof(RAWINPUTDEVICELIST)); - - if (n_devices == 0) - { - return false; - } - - return std::any_of(devices.begin(), devices.end(), [](const RAWINPUTDEVICELIST& device) - { - return device.dwType == RIM_TYPEMOUSE; - }); - } - - bool WindowsUtilities::get_external_controller_detected() - { - static_assert(XUSER_MAX_COUNT <= UINT8_MAX, "XUSER_MAX_COUNT exceeds uint8_t size"); - - uint8_t connectedGamepads = 0; - - for (DWORD i = 0; i < XUSER_MAX_COUNT; ++i) { - XINPUT_STATE state; - ZeroMemory(&state, sizeof(XINPUT_STATE)); - - if (XInputGetState(i, &state) == ERROR_SUCCESS) { - connectedGamepads++; - } - } - - return connectedGamepads > 1; - } - - bool WindowsUtilities::get_is_steam_deck_native_resolution() - { - DEVMODE devMode; - devMode.dmSize = sizeof(DEVMODE); - - // Get the current display settings for the primary monitor - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode)) { - // Check if the resolution is higher than 800p (1280x800) - if (devMode.dmPelsWidth > 1280 || devMode.dmPelsHeight > 800) { - return true; - } - } - return false; - } -} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h deleted file mode 100644 index 809b204..0000000 --- a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Platform/IPlatformUtilities.h" - -namespace HarmonyLinkLib -{ - class WindowsUtilities : public IPlatformUtilities - { - public: - std::shared_ptr get_battery_status() override; - - std::shared_ptr get_cpu_info() override; - - std::shared_ptr get_os_version() override; - - bool get_is_external_monitor_connected() override; - - bool get_keyboard_detected() override; - - bool get_mouse_detected() override; - - bool get_external_controller_detected() override; - - bool get_is_steam_deck_native_resolution() override; - }; -} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.cpp b/HarmonyLinkLib/src/Platform/WineUtilities.cpp deleted file mode 100644 index efe48a3..0000000 --- a/HarmonyLinkLib/src/Platform/WineUtilities.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "WineUtilities.h" - -#include -#include -#include -#include -#include - -#ifdef BUILD_WINDOWS -#include -#endif - -namespace HarmonyLinkLib -{ - bool force_detect_wine = false; - - std::shared_ptr HarmonyLinkLib::WineUtilities::get_battery_status() - { - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FBattery result = {}; - for (int i = 0; i <= 9; ++i) { - if (std::string bat_path = append + "/sys/class/power_supply/BAT" + std::to_string(i); std::filesystem::exists(bat_path)) { - result.has_battery = true; - - std::ifstream status_file(bat_path + "/status"); - std::string status; - if (status_file.is_open() && std::getline(status_file, status)) { - if (status == "Charging" || status == "AC") { - result.is_connected_to_ac = true; - } - } - - std::ifstream capacity_file(bat_path + "/capacity"); - if (capacity_file.is_open() && std::getline(capacity_file, status)) { - result.battery_percent = static_cast(std::stoi(status)); - break; // assuming you only need data from the first battery found - } - } - } - - return std::make_shared(result); - } - - std::shared_ptr WineUtilities::get_cpu_info() - { - std::wcout << "Getting cpu info\n"; - - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FCPUInfo cpu_info; - - std::ifstream file(append + "/proc/cpuinfo"); - std::unordered_map hashmap; - - if (file) { - std::string line; - while (std::getline(file, line)) { - std::istringstream line_stream(line); - std::string key, value; - if (std::getline(line_stream, key, ':')) { - key.erase(key.find_last_not_of(" \t") + 1); // Trim trailing whitespace from key - if (std::getline(line_stream, value)) { - value.erase(0, value.find_first_not_of(" \t")); // Trim leading whitespace from value - - // Aggregate flags - if (key == "flags") { - std::istringstream flag_stream(value); - std::string flag; - while (flag_stream >> flag) { - flag.erase(flag.find_last_not_of(" \t") + 1); // Trim trailing whitespace from flag - cpu_info.Flags.insert(HarmonyLinkLib::FString(flag)); - //printf("Flag detected: %s\n", flag.c_str()); - } - } else { - hashmap[key] = value; - } - } - } - } - file.close(); - } - - // Now you can access the values using the keys: - cpu_info.VendorID = hashmap["vendor_id"]; - cpu_info.Model_Name = hashmap["model name"]; - - try { - cpu_info.Physical_Cores = std::stoi(hashmap["cpu cores"].c_str()); - } catch (const std::invalid_argument& ia) { - std::wcerr << "Invalid argument: " << ia.what() << '\n'; - } catch (const std::out_of_range& oor) { - std::wcerr << "Out of Range error: " << oor.what() << '\n'; - } - - cpu_info.Logical_Cores = (cpu_info.Flags.find("ht") != cpu_info.Flags.end()) ? cpu_info.Physical_Cores * 2 : cpu_info.Physical_Cores; - - return std::make_shared(cpu_info); - } - - std::shared_ptr WineUtilities::get_linux_info() - { - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FOSVerInfo os_info; - - std::ifstream file(append + "/etc/os-release"); - std::unordered_map hashmap; - - if (file) { - std::string line; - while (std::getline(file, line)) { - std::istringstream lineStream(line); - std::string key, value; - if (std::getline(lineStream, key, '=')) { - if (std::getline(lineStream, value)) { - // Remove leading and trailing whitespace - size_t firstNonSpace = value.find_first_not_of(" \t"); - size_t lastNonSpace = value.find_last_not_of(" \t"); - if (firstNonSpace != std::string::npos && lastNonSpace != std::string::npos) { - value = value.substr(firstNonSpace, lastNonSpace - firstNonSpace + 1); - } else { - value.clear(); // If value is all whitespace, make it empty - } - - // Check for double quotes and remove them - if (!value.empty() && value.front() == '"' && value.back() == '"') { - value = value.substr(1, value.length() - 2); - } - - hashmap[key] = value; - } - } - } - file.close(); - } - - // Now you can access the values using the keys: - os_info.name = hashmap["NAME"]; - os_info.id = hashmap["ID"]; - os_info.version_id = hashmap["VERSION_ID"]; - os_info.version_codename = hashmap["VERSION_CODENAME"]; - os_info.pretty_name = hashmap["PRETTY_NAME"]; - - try { - os_info.version = std::stoi(hashmap["VERSION"].c_str()); - } catch (const std::invalid_argument& ia) { - std::cerr << "Invalid argument: " << ia.what() << '\n'; - // Handle the error, perhaps by setting a default value or leaving the field unchanged - } catch (const std::out_of_range& oor) { - std::cerr << "Out of Range error: " << oor.what() << '\n'; - // Handle the error, perhaps by setting a default value or leaving the field unchanged - } - - return std::make_shared(os_info); - } - - bool WineUtilities::is_wine_present() - { - static bool isWineCached = false; // Static variable to store the cached result - static bool isWine = false; // Static variable to indicate if the caching has been done - - if (!isWineCached) - { - // Only detect wine if force_detect_wine is true or if we haven't cached the result yet -#ifdef BUILD_WINDOWS - std::wcout << "Detecting wine...\n"; - bool HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "wine_get_version") != nullptr; - - if (!HasFound) - HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "proton_get_version") != nullptr; - - wprintf(L"wine %s found\n", HasFound ? L"has been" : L"not"); - - isWine = HasFound; // Cache the result -#else - isWine = false; // In non-Windows builds, always set isWine to false -#endif - isWineCached = true; // Indicate that the result is now cached - } - - return isWine; // Return the cached result - } - - bool WineUtilities::force_detect_wine_presence() - { - force_detect_wine = true; - return is_wine_present(); - } -} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.h b/HarmonyLinkLib/src/Platform/WineUtilities.h deleted file mode 100644 index 5e5bdae..0000000 --- a/HarmonyLinkLib/src/Platform/WineUtilities.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FOSVerInfo.h" - -namespace HarmonyLinkLib -{ - class WineUtilities - { - public: - static std::shared_ptr get_battery_status(); - - static std::shared_ptr get_cpu_info(); - - /** - * @brief Retrieves Linux OS version information from a specified file. - * - * This function parses a file (typically a Linux OS release file) at the given location - * to extract operating system version information. It reads key-value pairs from the file, - * processes them to handle whitespace and quotes, and then stores them in an FOSVerInfo - * structure. If the file location is invalid or the file cannot be opened, it returns an - * empty FOSVerInfo structure. Errors during parsing, such as invalid format or out of range - * values, are handled with exception catching. In Windows builds where Wine is detected, - * this function can use the file location 'Z:/etc/os-release' to retrieve the underlying - * Linux system information. - * - * @param file_location The location of the file containing OS version information. - * @return A shared pointer to a structure containing the parsed OS version information. - */ - static std::shared_ptr get_linux_info(); - - /** - * @brief Detects the presence of Wine or Proton in Windows builds. - * - * This function assesses if the application is running under Wine or Proton by - * querying specific functions in the 'ntdll.dll' module. It is only active in - * Windows builds, returning false for non-Windows builds. - * - * @return bool True if Wine or Proton is detected, false otherwise. - */ - static bool is_wine_present(); - - static bool force_detect_wine_presence(); - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h b/HarmonyLinkLib/src/Structs/Battery.c similarity index 63% rename from HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h rename to HarmonyLinkLib/src/Structs/Battery.c index 237a0c5..020a0d7 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h +++ b/HarmonyLinkLib/src/Structs/Battery.c @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include "Structs/Battery.h" -#include "Platform/Unix/UnixUtilities.h" +#include -namespace HarmonyLinkLib +void FBattery_print(const FBattery* self) { - class MacUtitities : public UnixUtilities { - public: - // Mac-specific overrides and additional functionality - }; + wprintf(L"Battery present: %ls\n", self->has_battery ? L"'Yes'" : L"'No'"); + wprintf(L"Connected to AC: %ls\n", self->is_connected_to_ac ? L"'Yes'" : L"'No'"); + wprintf(L"Battery percent: %ls\n", self->battery_percent ? L"'Yes'" : L"'No'"); } diff --git a/HarmonyLinkLib/src/Utilities.cpp b/HarmonyLinkLib/src/Utilities.cpp deleted file mode 100644 index 608437c..0000000 --- a/HarmonyLinkLib/src/Utilities.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "Utilities.h" - -#include - -#include "FString.h" - -void HarmonyLinkLib::Utilities::DebugPrint(const FString& String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << String.c_str(); - - if (AddNewline) - { - std::wcout << L"\n"; - } -#endif -} - -void HarmonyLinkLib::Utilities::DebugPrint(const char* String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << std::wstring(String, String + std::strlen(String)); - - if (AddNewline) { - std::wcout << L"\n"; - } -#endif -} - -void HarmonyLinkLib::Utilities::DebugPrint(const wchar_t* String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << String; - - if (AddNewline) { - std::wcout << L"\n"; - } -#endif -} diff --git a/HarmonyLinkLib/src/Utilities.h b/HarmonyLinkLib/src/Version.c similarity index 59% rename from HarmonyLinkLib/src/Utilities.h rename to HarmonyLinkLib/src/Version.c index d6114c8..b844b0c 100644 --- a/HarmonyLinkLib/src/Utilities.h +++ b/HarmonyLinkLib/src/Version.c @@ -12,19 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include "Version.h" -#include "HarmonyLinkLib.h" +#include -namespace HarmonyLinkLib +char* get_version_string(void) { - class FString; - - class Utilities - { - public: - static void DebugPrint(const FString& String, bool AddNewline = true); - static void DebugPrint(const char* String, bool AddNewline = true); - static void DebugPrint(const wchar_t* String, bool AddNewline = true); - }; + return HARMONYLINK_VERSION; +} + +char* get_version_build_timestamp(void) +{ + return __TIMESTAMP__; +} + +char* get_git_branch(void) +{ + return GIT_BRANCH_NAME; +} + +char* get_git_commit_timestamp(void) +{ + return GIT_COMMIT_TIMESTAMP; +} + +bool get_is_debug(void) +{ +#ifdef DEBUG_MODE + return true; +#else + return false; +#endif } diff --git a/HarmonyLinkLib/src/dllmain.c b/HarmonyLinkLib/src/dllmain.c new file mode 100644 index 0000000..e69de29 diff --git a/HarmonyLinkLib/src/dllmain.cpp b/HarmonyLinkLib/src/dllmain.cpp deleted file mode 100644 index 5e6df48..0000000 --- a/HarmonyLinkLib/src/dllmain.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include "Version.h" - -namespace HarmonyLinkLib -{ - void HarmonyLinkInit() - { - std::wcout << "HarmonyLink V" << version::ToString().c_str() << " Copyright (C) 2023 Jordon Brooks\n"; - } -} - - -#if BUILD_WINDOWS -#include - -// Standard DLL entry point -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - // Code to run when the DLL is loaded - HarmonyLinkLib::HarmonyLinkInit(); - break; - case DLL_THREAD_ATTACH: - // Code to run when a thread is created during the DLL's lifetime - case DLL_THREAD_DETACH: - // Code to run when a thread ends normally. - case DLL_PROCESS_DETACH: - // Code to run when the DLL is unloaded - default: - break; - } - return TRUE; // Successful DLL_PROCESS_ATTACH. -} -#endif - -#if BUILD_UNIX -__attribute__((constructor)) -static void onLibraryLoad() { - // Code to run when the library is loaded - HarmonyLinkLib::HarmonyLinkInit(); -} - -__attribute__((destructor)) -static void onLibraryUnload() { - // Code to run when the library is unloaded -} -#endif diff --git a/HarmonyLinkTest/CMakeLists.txt b/HarmonyLinkTest/CMakeLists.txt index 949ea4f..31dd770 100644 --- a/HarmonyLinkTest/CMakeLists.txt +++ b/HarmonyLinkTest/CMakeLists.txt @@ -15,11 +15,11 @@ cmake_minimum_required(VERSION 3.10) project(HarmonyLinkTest) # Specify the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) # Automatically add all .cpp and .h/.hpp files in the src directory -file(GLOB_RECURSE TEST_SOURCES "src/*.cpp") +file(GLOB_RECURSE TEST_SOURCES "src/*.c") file(GLOB_RECURSE TEST_HEADERS "src/*.h" "src/*.hpp") # Add executable for static library diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp b/HarmonyLinkTest/src/main.c similarity index 67% rename from HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp rename to HarmonyLinkTest/src/main.c index 001364c..245d90e 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp +++ b/HarmonyLinkTest/src/main.c @@ -12,9 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "MacUtilities.h" +#include +#include "HarmonyLinkLib.h" -namespace HarmonyLinkLib +int main(void) { + wprintf(L"Hello from C!\n"); -} \ No newline at end of file + if (!HarmonyLink_Init()) + { + wprintf(L"Error: Failed to initialise HarmonyLink!\n"); + return 1; + } + + wprintf(L"Successfully Initialised HarmonyLink!\n"); + + return 0; +} diff --git a/HarmonyLinkTest/src/main.cpp b/HarmonyLinkTest/src/main.cpp deleted file mode 100644 index e9eaf87..0000000 --- a/HarmonyLinkTest/src/main.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include -#include - -#include "HarmonyLinkLib.h" - -// Include necessary headers for platform-specific functionality -#ifdef BUILD_WINDOWS -#include // For _kbhit() and _getch() -#include // For system("cls") -#else -#include // For read() -#include // For termios -#include // For getchar() -#include // For F_GETFL, F_SETFL and O_NONBLOCK -#endif - -std::atomic quitFlag(false); - -// Function to clear the screen cross-platform -void clearScreen() { -#ifdef _WIN32 - system("cls"); -#else - std::cout << "\x1B[2J\x1B[H"; -#endif -} - - -// Function to check if 'q' or 'Q' is pressed in Windows -void checkForQuit() { - while (!quitFlag) { -#ifdef BUILD_WINDOWS - if (_kbhit()) { - const char c = static_cast(_getch()); - if (c == 'q' || c == 'Q') { - quitFlag = true; - break; - } - } -#else - struct termios oldt, newt; - int ch; - int oldf; - - tcgetattr(STDIN_FILENO, &oldt); - newt = oldt; - newt.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - oldf = fcntl(STDIN_FILENO, F_GETFL, 0); - fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); - - ch = getchar(); - - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); - fcntl(STDIN_FILENO, F_SETFL, oldf); - - if (ch != EOF) { - ungetc(ch, stdin); - if (ch == 'q' || ch == 'Q') { - quitFlag = true; - break; - } - } -#endif - // Checks for input every roughly 60 frames - std::this_thread::sleep_for(std::chrono::milliseconds(16)); - } -} - -int main() -{ - std::cout << "Hello, World!" << '\n'; - - std::thread inputThread(checkForQuit); - - const bool isWine = HarmonyLinkLib::get_is_wine(); - const char* test = isWine ? "is" : "isn't"; - - const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); - - const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); - - const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); - - // This loop is to test how stable & expensive these functions are - while (!quitFlag) - { - // Clear the screen - clearScreen(); - - std::wcout << "This program " << test << " running under wine.\n"; - - if (cpu_info) - { - cpu_info->print(); - } - - if (os_info) - { - os_info->print(); - } - - if (device_info) - { - wprintf(L"Is SteamDeck: %s\n", device_info->device == HarmonyLinkLib::EDevice::STEAM_DECK ? L"true" : L"false"); - } - - // we can't do this before the loop because we need updated values - if (const HarmonyLinkLib::FBattery* battery = HarmonyLinkLib::get_battery_status()) - { - battery->to_string(); - battery->free(); - } - - const bool is_docked = HarmonyLinkLib::get_is_docked(); - - const char* dock_check_string = is_docked ? "is" : "isn't"; - - wprintf(L"Device %hs docked\n", dock_check_string); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - if (inputThread.joinable()) - { - inputThread.join(); - } - - if (os_info) - { - os_info->free(); - } - - if (device_info) - { - device_info->free(); - } - - if (cpu_info) - { - cpu_info->free(); - } - - return 0; -}