diff --git a/.gitignore b/.gitignore index 0839667..390d006 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,12 @@ build/** !Images/* !.github/** -!HarmonyLinkLib/** +!LibHarmonyLink/** !HarmonyLinkTest/** +!HarmonyLinkTest_CPP/** # Blacklist specific build directories linuxbuild/ build/ +.idea/ +winbuild/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 02296e9..3a0e4c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,8 +53,9 @@ endforeach() # Add the library and executable directories -add_subdirectory(HarmonyLinkLib) +add_subdirectory(LibHarmonyLink) add_subdirectory(HarmonyLinkTest) +add_subdirectory(HarmonyLinkTest_CPP) # Add Google Test as a subdirectory #add_subdirectory(ThirdParty/googletest) 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/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 deleted file mode 100644 index d6575a5..0000000 --- a/HarmonyLinkLib/include/HarmonyLinkLib.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. - - -/** - * 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 "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(); -} diff --git a/HarmonyLinkLib/include/HarmonyLinkStruct.h b/HarmonyLinkLib/include/HarmonyLinkStruct.h deleted file mode 100644 index 362750b..0000000 --- a/HarmonyLinkLib/include/HarmonyLinkStruct.h +++ /dev/null @@ -1,27 +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 - -struct HarmonyLinkStruct -{ - // Virtual destructor is important for proper cleanup of derived types - virtual ~HarmonyLinkStruct() = default; - - // Method to deallocate the object - void free() const - { - delete this; - } -}; 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/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 deleted file mode 100644 index dcc9d33..0000000 --- a/HarmonyLinkLib/include/Version.h +++ /dev/null @@ -1,58 +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 "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 - } - }; -} 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/Mac/MacUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp deleted file mode 100644 index 001364c..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp +++ /dev/null @@ -1,20 +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 "MacUtilities.h" - -namespace HarmonyLinkLib -{ - -} \ No newline at end of file diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h deleted file mode 100644 index 237a0c5..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h +++ /dev/null @@ -1,25 +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/Unix/UnixUtilities.h" - -namespace HarmonyLinkLib -{ - class MacUtitities : public UnixUtilities { - public: - // Mac-specific overrides and additional functionality - }; -} 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/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/Utilities.h deleted file mode 100644 index d6114c8..0000000 --- a/HarmonyLinkLib/src/Utilities.h +++ /dev/null @@ -1,30 +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 "HarmonyLinkLib.h" - -namespace HarmonyLinkLib -{ - 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); - }; -} 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..a7c0d12 100644 --- a/HarmonyLinkTest/CMakeLists.txt +++ b/HarmonyLinkTest/CMakeLists.txt @@ -15,22 +15,29 @@ 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") +# Enable all compiler warnings and errors +if(MSVC) + add_compile_options(/W4 /WX) +else() + add_compile_options(-Wall -Wextra -pedantic -Werror) +endif() + # Add executable for static library add_executable(HarmonyLinkTestStatic ${TEST_SOURCES} ${TEST_HEADERS}) -target_link_libraries(HarmonyLinkTestStatic PRIVATE HarmonyLinkLibStatic) -target_compile_definitions(HarmonyLinkTestStatic PRIVATE HARMONYLINKLIB_STATIC) +target_link_libraries(HarmonyLinkTestStatic PRIVATE LibHarmonyLinkStatic) +target_compile_definitions(HarmonyLinkTestStatic PRIVATE HARMONYLINK_STATIC) # Add executable for shared library add_executable(HarmonyLinkTestShared ${TEST_SOURCES} ${TEST_HEADERS}) -target_link_libraries(HarmonyLinkTestShared PRIVATE HarmonyLinkLibShared) -target_compile_definitions(HarmonyLinkTestShared PRIVATE HARMONYLINKLIB_SHARED) +target_link_libraries(HarmonyLinkTestShared PRIVATE LibHarmonyLinkShared) +target_compile_definitions(HarmonyLinkTestShared PRIVATE HARMONYLINK_SHARED) # Set output directories for all build types foreach(TYPE IN ITEMS DEBUG RELEASE) @@ -54,5 +61,5 @@ endforeach() # Copy the DLL to the executable directory after building the shared test executable add_custom_command(TARGET HarmonyLinkTestShared POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - "$" + "$" "$") diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp b/HarmonyLinkTest/src/main.c similarity index 55% rename from HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp rename to HarmonyLinkTest/src/main.c index 490e869..8481c73 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp +++ b/HarmonyLinkTest/src/main.c @@ -12,27 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "LinuxUtilities.h" +#include +#include "LibHarmonyLink.h" - -#include -#include -#include "Platform/WineUtilities.h" - -namespace HarmonyLinkLib +int main(void) { - std::shared_ptr LinuxUtilities::get_battery_status() + wprintf(L"Hello from C!\n"); + + if (!HL_Init()) { - return WineUtilities::get_battery_status(); + wprintf(L"Error: Failed to initialise HarmonyLink!\n"); + return 1; } - std::shared_ptr LinuxUtilities::get_os_version() - { - return WineUtilities::get_linux_info(); - } + wprintf(L"Successfully Initialised HarmonyLink!\n"); - std::shared_ptr LinuxUtilities::get_cpu_info() - { - return WineUtilities::get_cpu_info(); - } + const wchar_t* IsLinux = HL_Is_Linux() ? L"True" : L"False"; + wprintf(L"Is Linux: %ls\n", IsLinux); + + const wchar_t* IsWine = HL_Is_Wine() ? L"True" : L"False"; + wprintf(L"Is Wine: %ls\n", IsWine); + + return 0; } diff --git a/HarmonyLinkTest_CPP/CMakeLists.txt b/HarmonyLinkTest_CPP/CMakeLists.txt new file mode 100644 index 0000000..65efc21 --- /dev/null +++ b/HarmonyLinkTest_CPP/CMakeLists.txt @@ -0,0 +1,65 @@ +# 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. + +cmake_minimum_required(VERSION 3.22.1) +project(HarmonyLinkTest) + +# Specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_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_HEADERS "src/*.h" "src/*.hpp") + +# Enable all compiler warnings and errors +if(MSVC) + add_compile_options(/W4 /WX) +else() + add_compile_options(-Wall -Wextra -pedantic -Werror) +endif() + +# Add executable for static library +add_executable(HarmonyLinkTestStatic_CPP ${TEST_SOURCES} ${TEST_HEADERS}) +target_link_libraries(HarmonyLinkTestStatic_CPP PRIVATE LibHarmonyLinkStatic) +target_compile_definitions(HarmonyLinkTestStatic_CPP PRIVATE HARMONYLINK_STATIC) + +# Add executable for shared library +add_executable(HarmonyLinkTestShared_CPP ${TEST_SOURCES} ${TEST_HEADERS}) +target_link_libraries(HarmonyLinkTestShared_CPP PRIVATE LibHarmonyLinkShared) +target_compile_definitions(HarmonyLinkTestShared_CPP PRIVATE HARMONYLINK_SHARED) + +# Set output directories for all build types +foreach(TYPE IN ITEMS DEBUG RELEASE) + string(TOUPPER ${TYPE} TYPE_UPPER) + + # Static test executable properties + set_target_properties(HarmonyLinkTestStatic_CPP PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/HarmonyLinkTestStatic_CPP" + LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}/HarmonyLinkTestStatic_CPP" + ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkTestStatic_CPP" + ) + + # Shared test executable properties + set_target_properties(HarmonyLinkTestShared_CPP PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/HarmonyLinkTestShared_CPP" + LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}/HarmonyLinkTestShared_CPP" + ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkTestShared_CPP" + ) +endforeach() + +# Copy the DLL to the executable directory after building the shared test executable +add_custom_command(TARGET HarmonyLinkTestShared_CPP POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$") diff --git a/HarmonyLinkTest/src/main.cpp b/HarmonyLinkTest_CPP/src/main.cpp similarity index 61% rename from HarmonyLinkTest/src/main.cpp rename to HarmonyLinkTest_CPP/src/main.cpp index e9eaf87..7680ffd 100644 --- a/HarmonyLinkTest/src/main.cpp +++ b/HarmonyLinkTest_CPP/src/main.cpp @@ -17,7 +17,7 @@ #include #include -#include "HarmonyLinkLib.h" +#include "LibHarmonyLink.h" // Include necessary headers for platform-specific functionality #ifdef BUILD_WINDOWS @@ -32,9 +32,11 @@ std::atomic quitFlag(false); +std::atomic HasError(false); + // Function to clear the screen cross-platform void clearScreen() { -#ifdef _WIN32 +#ifdef BUILD_WINDOWS system("cls"); #else std::cout << "\x1B[2J\x1B[H"; @@ -44,7 +46,7 @@ void clearScreen() { // Function to check if 'q' or 'Q' is pressed in Windows void checkForQuit() { - while (!quitFlag) { + while (!quitFlag || !HasError) { #ifdef BUILD_WINDOWS if (_kbhit()) { const char c = static_cast(_getch()); @@ -87,52 +89,66 @@ int main() { std::cout << "Hello, World!" << '\n'; + if (!LibHarmonyLink::HL_Init()) + { + printf("Failed to Initialize HarmonyLink!\n"); + + HasError = true; + return 1; + } + + printf("HarmonyLink Initialized!\n"); + std::thread inputThread(checkForQuit); - const bool isWine = HarmonyLinkLib::get_is_wine(); + const char* isLinux = LibHarmonyLink::HL_Is_Linux() ? "is" : "isn't"; + printf("This program %s running under Linux.\n", isLinux); + + const bool isWine = LibHarmonyLink::HL_Is_Wine(); const char* test = isWine ? "is" : "isn't"; - const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); + printf("This program %s running under wine.\n", test); - const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); + //const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); - const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); + //const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); + //const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); + + HasError = true; // This loop is to test how stable & expensive these functions are - while (!quitFlag) + while (!quitFlag || !HasError) { // Clear the screen clearScreen(); - std::wcout << "This program " << test << " running under wine.\n"; + //if (cpu_info) + //{ + // cpu_info->print(); + //} - if (cpu_info) - { - cpu_info->print(); - } + //if (os_info) + //{ + // os_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"); - } + //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(); - } + //if (const HarmonyLinkLib::FBattery* battery = HarmonyLinkLib::get_battery_status()) + //{ + // battery->print(); + // battery->free(); + //} - const bool is_docked = HarmonyLinkLib::get_is_docked(); + //const bool is_docked = HarmonyLinkLib::get_is_docked(); - const char* dock_check_string = is_docked ? "is" : "isn't"; + //const char* dock_check_string = is_docked ? "is" : "isn't"; - wprintf(L"Device %hs docked\n", dock_check_string); + //wprintf(L"Device %hs docked\n", dock_check_string); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -142,20 +158,20 @@ int main() inputThread.join(); } - if (os_info) - { - os_info->free(); - } + //if (os_info) + //{ + // os_info->free(); + //} - if (device_info) - { - device_info->free(); - } + //if (device_info) + //{ + // device_info->free(); + //} - if (cpu_info) - { - cpu_info->free(); - } + //if (cpu_info) + //{ + // cpu_info->free(); + //} return 0; } diff --git a/HarmonyLinkLib/CMakeLists.txt b/LibHarmonyLink/CMakeLists.txt similarity index 58% rename from HarmonyLinkLib/CMakeLists.txt rename to LibHarmonyLink/CMakeLists.txt index 03440bf..fd1c097 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/LibHarmonyLink/CMakeLists.txt @@ -12,21 +12,11 @@ # limitations under the License. cmake_minimum_required(VERSION 3.10) -project(HarmonyLinkLib VERSION 2.1.1) +project(LibHarmonyLink VERSION 2.1.1 LANGUAGES C) -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,15 +40,11 @@ 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") -set(ORIGINAL_FILENAME "HarmonyLinkLib.dll") -set(PRODUCT_NAME "HarmonyLinkLib") +set(INTERNAL_NAME "LibHarmonyLink") +set(ORIGINAL_FILENAME "LibHarmonyLink.dll") +set(PRODUCT_NAME "LibHarmonyLink") set(COMMENTS "") # Configure version.rc file for shared library @@ -66,63 +52,54 @@ 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/LibHarmonyLink.c + src/Version.c + src/Utilities.c + src/Wine.c + + src/Structs/Battery.c + src/Structs/CPUInfo.c + src/Structs/StringArray.c + src/Structs/Device.c + src/Structs/OSInfo.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/Core.h + include/LibHarmonyLink.h + include/Version.h + include/Utilities.h + include/Wine.h + + include/Enums/Device.h + include/Enums/Platform.h + include/Enums/SteamDeck.h + + include/Structs/Battery.h + include/Structs/CPUInfo.h + include/Structs/StringArray.h + include/Structs/Device.h + include/Structs/OSInfo.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 @@ -144,48 +121,54 @@ elseif(UNIX) endif() endif() +# Detect the compiler name +get_filename_component(COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME) + +# Replace forbidden characters in file names (optional, if needed) +string(REPLACE "." "_" COMPILER_NAME ${COMPILER_NAME}) +string(REPLACE "/" "_" COMPILER_NAME ${COMPILER_NAME}) +string(REPLACE "\\" "_" COMPILER_NAME ${COMPILER_NAME}) + +# Enable all compiler warnings and errors +if(MSVC) + add_compile_options(/W4 /WX) +else() + add_compile_options(-Wall -Wextra -pedantic -Werror) +endif() + # Create the shared library -add_library(HarmonyLinkLibShared SHARED ${LIB_SOURCES} ${SHARED_SOURCES}) -target_include_directories(HarmonyLinkLibShared +add_library(LibHarmonyLinkShared SHARED ${LIB_SOURCES} ${LIB_INCLUDES} ${SHARED_SOURCES}) +target_include_directories(LibHarmonyLinkShared PRIVATE "${PROJECT_SOURCE_DIR}/src" PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" ) -target_compile_definitions(HarmonyLinkLibShared PRIVATE HARMONYLINKLIB_SHARED) +target_compile_definitions(LibHarmonyLinkShared PRIVATE HARMONYLINK_SHARED) +set_target_properties(LibHarmonyLinkShared PROPERTIES OUTPUT_NAME "LibHarmonyLink_${COMPILER_NAME}") # Create the static library -add_library(HarmonyLinkLibStatic STATIC ${LIB_SOURCES}) -target_include_directories(HarmonyLinkLibStatic +add_library(LibHarmonyLinkStatic STATIC ${LIB_SOURCES} ${LIB_INCLUDES}) +target_include_directories(LibHarmonyLinkStatic PRIVATE "${PROJECT_SOURCE_DIR}/src" PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" ) -target_compile_definitions(HarmonyLinkLibStatic PRIVATE HARMONYLINKLIB_STATIC) - -# Include fmt headers -target_include_directories(HarmonyLinkLibStatic PRIVATE ${FMT_HEADERS}) +target_compile_definitions(LibHarmonyLinkStatic PRIVATE HARMONYLINK_STATIC) +set_target_properties(LibHarmonyLinkStatic PROPERTIES OUTPUT_NAME "LibHarmonyLink_${COMPILER_NAME}") # Set output directories for all build types foreach(TYPE IN ITEMS DEBUG RELEASE) string(TOUPPER ${TYPE} TYPE_UPPER) - set_target_properties(HarmonyLinkLibShared PROPERTIES + set_target_properties(LibHarmonyLinkShared PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/HarmonyLinkLib" LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}/HarmonyLinkLib" ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkLib" ) - set_target_properties(HarmonyLinkLibStatic PROPERTIES + set_target_properties(LibHarmonyLinkStatic PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkLibStatic" ) 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/Resources/Version.rc.in b/LibHarmonyLink/Resources/Version.rc.in similarity index 100% rename from HarmonyLinkLib/Resources/Version.rc.in rename to LibHarmonyLink/Resources/Version.rc.in diff --git a/HarmonyLinkLib/include/Core.h b/LibHarmonyLink/include/Core.h similarity index 74% rename from HarmonyLinkLib/include/Core.h rename to LibHarmonyLink/include/Core.h index 94a32d2..f561b77 100644 --- a/HarmonyLinkLib/include/Core.h +++ b/LibHarmonyLink/include/Core.h @@ -16,15 +16,15 @@ // Use a preprocessor definition to switch between export and import declarations #ifdef _WIN32 - #ifdef HARMONYLINKLIB_STATIC - #define HARMONYLINKLIB_API + #ifdef HARMONYLINK_STATIC + #define HARMONYLINK_API #else - #ifdef HARMONYLINKLIB_SHARED - #define HARMONYLINKLIB_API __declspec(dllexport) + #ifdef HARMONYLINK_SHARED + #define HARMONYLINK_API __declspec(dllexport) #else - #define HARMONYLINKLIB_API __declspec(dllimport) + #define HARMONYLINK_API __declspec(dllimport) #endif #endif #else - #define HARMONYLINKLIB_API + #define HARMONYLINK_API #endif diff --git a/LibHarmonyLink/include/Enums/Device.h b/LibHarmonyLink/include/Enums/Device.h new file mode 100644 index 0000000..66e749c --- /dev/null +++ b/LibHarmonyLink/include/Enums/Device.h @@ -0,0 +1,52 @@ +// 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 "Core.h" + +// Undefine the LINUX macro to avoid conflicts with the enum definition. +#undef LINUX + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef enum { + EDevice_UNKNOWN, + EDevice_DESKTOP, + EDevice_LAPTOP, + EDevice_HANDHELD, + + EDevice_STEAM_DECK, + // EDevice_ROG_ALLY + // EDevice_AYONEO_SLIDE + // etc... +} EDevice; + +HARMONYLINK_API const char* Device_ToString(EDevice device) { + switch (device) { + case EDevice_DESKTOP: return "DESKTOP"; + case EDevice_LAPTOP: return "LAPTOP"; + case EDevice_HANDHELD: return "HANDHELD"; + case EDevice_STEAM_DECK: return "STEAM_DECK"; + default: return "UNKNOWN"; + } +} + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/Enums/Platform.h b/LibHarmonyLink/include/Enums/Platform.h new file mode 100644 index 0000000..247eff9 --- /dev/null +++ b/LibHarmonyLink/include/Enums/Platform.h @@ -0,0 +1,46 @@ +// 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 "Core.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef enum { + EPlatform_UNKNOWN, + EPlatform_WINDOWS, + EPlatform_LINUX, + EPlatform_MAC, + EPlatform_UNIX, +} EPlatform; + +// Helper functions to convert enums to strings (must be implemented somewhere in your code) +HARMONYLINK_API const char* Platform_ToString(EPlatform platform) { + switch (platform) { + case EPlatform_WINDOWS: return "WINDOWS"; + case EPlatform_LINUX: return "LINUX"; + case EPlatform_MAC: return "MAC"; + case EPlatform_UNIX: return "UNIX"; + default: return "UNKNOWN"; + } +} + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/Enums/SteamDeck.h b/LibHarmonyLink/include/Enums/SteamDeck.h new file mode 100644 index 0000000..b6fe09e --- /dev/null +++ b/LibHarmonyLink/include/Enums/SteamDeck.h @@ -0,0 +1,44 @@ +// 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 "Core.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef enum { + 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; + +HARMONYLINK_API const char* SteamDeck_ToString(ESteamDeck steam_deck_model) { + switch (steam_deck_model) { + case ESteamDeck_NONE: return "NONE"; + case ESteamDeck_LCD: return "STEAMDECK_LCD"; + case ESteamDeck_OLED: return "STEAMDECK_OLED"; + // Add other cases as needed + default: return "UNKNOWN"; + } +} + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/LibHarmonyLink.h b/LibHarmonyLink/include/LibHarmonyLink.h new file mode 100644 index 0000000..9a7d790 --- /dev/null +++ b/LibHarmonyLink/include/LibHarmonyLink.h @@ -0,0 +1,90 @@ +// 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 "Core.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +/** + * @brief Initializes the HarmonyLink library. + * + * This function initializes the HarmonyLink library by printing the version, + * detecting if the application is running under Wine or on Linux. + * + * @return Returns true on successful initialization. + */ +HARMONYLINK_API bool HL_Init(void); +/** + * @brief Checks if the HarmonyLink library is running under Wine. + * + * This function returns the result of Get_IsWine. + * + * @return Returns true if the HarmonyLink library is running under Wine, false otherwise. + */ +HARMONYLINK_API bool HL_Is_Wine(void); + +/** + * @brief Checks if the HarmonyLink library is running on Linux. + * + * This function returns the result of Get_IsLinux. + * + * @return Returns true if the HarmonyLink library is running on Linux, false otherwise. + */ +HARMONYLINK_API bool HL_Is_Linux(void); + +/** + * @brief Handles the detection of Linux. + * + * This function detects if the application is running on Linux and caches the result. + * If the application is not running on Linux, it checks if it is running under Wine. + */ +void Handle_Detect_Linux(void); + +/** + * @brief Handles the detection of Wine. + * + * This function detects if the application is running under Wine and caches the result. + */ +void Handle_Detect_Wine(void); + +/** + * @brief Checks if the application is running under Wine. + * + * This function returns the cached result of the Wine detection. If the result + * is not cached, it will call Handle_Detect_Wine to detect and cache the result. + * + * @return Returns true if the application is running under Wine, false otherwise. + */ +bool Get_IsWine(void); + +/** + * @brief Checks if the application is running on Linux. + * + * This function returns the cached result of the Linux detection. If the result + * is not cached, it will call Handle_Detect_Linux to detect and cache the result. + * + * @return Returns true if the application is running on Linux, false otherwise. + */ +bool Get_IsLinux(void); + +#ifdef __cplusplus +} +} +#endif diff --git a/HarmonyLinkLib/include/Enums/EDevice.h b/LibHarmonyLink/include/Structs/Battery.h similarity index 58% rename from HarmonyLinkLib/include/Enums/EDevice.h rename to LibHarmonyLink/include/Structs/Battery.h index c11919d..0fe6614 100644 --- a/HarmonyLinkLib/include/Enums/EDevice.h +++ b/LibHarmonyLink/include/Structs/Battery.h @@ -14,24 +14,27 @@ #pragma once -// Undefine the LINUX macro to avoid conflicts with the enum definition. -#undef LINUX +#include -#include +#include "Core.h" -// Enum class for representing different types of devices -namespace HarmonyLinkLib -{ - enum class EDevice : uint8_t - { - UNKNOWN, - DESKTOP, - LAPTOP, - HANDHELD, - - STEAM_DECK, - // ROG_ALLY - // AYONEO_SLIDE - // etc... - }; +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct { + bool has_battery; + bool is_connected_to_ac; + unsigned char battery_percent; +} FBattery; + +HARMONYLINK_API FBattery* HL_FBattery_Init(bool has_battery, bool is_connected_to_ac, unsigned char battery_percent); + +HARMONYLINK_API void HL_FBattery_print(const FBattery *self); + +#ifdef __cplusplus } +} +#endif + diff --git a/LibHarmonyLink/include/Structs/CPUInfo.h b/LibHarmonyLink/include/Structs/CPUInfo.h new file mode 100644 index 0000000..36d9d13 --- /dev/null +++ b/LibHarmonyLink/include/Structs/CPUInfo.h @@ -0,0 +1,57 @@ +// 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/Structs/CPUInfo.h + +#pragma once + +#include +#include + +#include "Core.h" +#include "Structs/StringArray.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct FCPUInfo { + char* VendorID; + char* Model_Name; + unsigned int Physical_Cores; + unsigned int Logical_Cores; + StringArray flagsInfo; +} FCPUInfo; + +// Initialize FCPUInfo +FCPUInfo* FCPUInfo_Init(const char *vendorID, const char *modelName, unsigned int physicalCores, unsigned int logicalCores, + size_t flagsCount); + +// Print FlagsInfo +HARMONYLINK_API void HL_FlagsInfo_Print(const FCPUInfo *cpuInfo); + +// Print FCPUInfo +HARMONYLINK_API void HL_FCPUInfo_Print(const FCPUInfo *cpuInfo); + +// Free FCPUInfo +HARMONYLINK_API void HL_FCPUInfo_Free(FCPUInfo *cpuInfo); + +// Check if a flag exists in FlagsInfo +HARMONYLINK_API bool HL_FlagsInfo_Contains(const FCPUInfo *cpuInfo, const char *flag); + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/Structs/Device.h b/LibHarmonyLink/include/Structs/Device.h new file mode 100644 index 0000000..546f936 --- /dev/null +++ b/LibHarmonyLink/include/Structs/Device.h @@ -0,0 +1,47 @@ +// 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 "Core.h" +#include "Enums/Platform.h" +#include "Enums/Device.h" +#include "Enums/SteamDeck.h" + +#define DEFAULT_INITIAL_FLAGS_SIZE 4 + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct { + EPlatform platform; + EDevice device; + ESteamDeck steam_deck_model; +} FDevice; + +// Initialize FlagsInfo +FDevice* Device_Init(EPlatform platform, EDevice device, ESteamDeck steam_deck_model); + +// Print FlagsInfo +HARMONYLINK_API void HL_Device_Print(const FDevice* Device); + +// Free FlagsInfo +HARMONYLINK_API void HL_Device_Free(FDevice* Device); + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/Structs/OSInfo.h b/LibHarmonyLink/include/Structs/OSInfo.h new file mode 100644 index 0000000..e160a6a --- /dev/null +++ b/LibHarmonyLink/include/Structs/OSInfo.h @@ -0,0 +1,49 @@ +// 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 "Core.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct { + char* name; + char* version; + unsigned int id; + char* version_id; + char* version_codename; + char* pretty_name; + char* variant_id; +} FOSVerInfo; + +// Initialize FCPUInfo +FOSVerInfo* FOSVerInfo_Init(char* name, char* version, unsigned int id, char* version_id, char* version_codename, char* pretty_name, char* variant_id); + +// Print FlagsInfo +HARMONYLINK_API void HL_FOSVerInfo_Print(const FOSVerInfo* OSVerInfo); + +// Free FCPUInfo +HARMONYLINK_API void HL_FOSVerInfo_Free(FOSVerInfo* OSVerInfo); + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/include/Structs/StringArray.h b/LibHarmonyLink/include/Structs/StringArray.h new file mode 100644 index 0000000..af9beea --- /dev/null +++ b/LibHarmonyLink/include/Structs/StringArray.h @@ -0,0 +1,61 @@ +// 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/Structs/StringArray.h + +#pragma once + +#include +#include + +#include "Core.h" + +#define DEFAULT_INITIAL_FLAGS_SIZE 4 + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct StringArray { + char **data; // Array of strings (flags) + size_t FlagsCount; // Number of flags + size_t AllocatedSize; // Number of allocated slots +} StringArray; + +// Initialize FlagsInfo +void StringArray_Init(StringArray *flagsInfo, size_t overrideInitialSize); + +// Print FlagsInfo +HARMONYLINK_API void HL_StringArray_Print(const StringArray *flagsInfo); + +// Free FlagsInfo +HARMONYLINK_API void HL_StringArray_Free(StringArray *flagsInfo); + +// Check if a flag exists in FlagsInfo +HARMONYLINK_API bool HL_StringArray_Contains(const StringArray *flagsInfo, const char *flag); + +// Add a flag to FlagsInfo +void StringArray_AddFlag(StringArray *flagsInfo, const char *flag); + +// Remove a flag from FlagsInfo by value +void StringArray_Remove(StringArray *flagsInfo, const char *flag); + +// Resize FlagsInfo array +void StringArray_Resize(StringArray *flagsInfo, size_t newSize); + +#ifdef __cplusplus +} +} +#endif diff --git a/HarmonyLinkLib/include/Enums/EPlatform.h b/LibHarmonyLink/include/Utilities.h similarity index 70% rename from HarmonyLinkLib/include/Enums/EPlatform.h rename to LibHarmonyLink/include/Utilities.h index ffa2be7..cffd96e 100644 --- a/HarmonyLinkLib/include/Enums/EPlatform.h +++ b/LibHarmonyLink/include/Utilities.h @@ -3,7 +3,7 @@ // 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 @@ -12,19 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include -#include +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif -// Enum class for representing different operating platforms -namespace HarmonyLinkLib -{ - enum class EPlatform : uint8_t - { - UNKNOWN, - WINDOWS, - LINUX, - MAC, - UNIX, - }; +// Utility function to convert char* to wchar_t* +wchar_t *convertToWideChar(const char *str); + +#ifdef __cplusplus } +} +#endif diff --git a/HarmonyLinkLib/include/Structs/FDevice.h b/LibHarmonyLink/include/Version.h similarity index 58% rename from HarmonyLinkLib/include/Structs/FDevice.h rename to LibHarmonyLink/include/Version.h index b574d6a..d238e47 100644 --- a/HarmonyLinkLib/include/Structs/FDevice.h +++ b/LibHarmonyLink/include/Version.h @@ -14,19 +14,27 @@ #pragma once -#include +#include +#include "Core.h" -#include "Enums/EDevice.h" -#include "Enums/EPlatform.h" -#include "Enums/ESteamDeck.h" +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif -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; - }; +HARMONYLINK_API char* HL_version_get_string(void); + +HARMONYLINK_API char* HL_version_build_timestamp(void); + +HARMONYLINK_API char* HL_git_branch(void); + +HARMONYLINK_API char* HL_git_commit_timestamp(void); + +HARMONYLINK_API bool HL_is_debug(void); + +HARMONYLINK_API void HL_version_print(void); + +#ifdef __cplusplus } +} +#endif diff --git a/HarmonyLinkLib/include/Version.h.in b/LibHarmonyLink/include/Version.h.in similarity index 69% rename from HarmonyLinkLib/include/Version.h.in rename to LibHarmonyLink/include/Version.h.in index 08881c5..9b03890 100644 --- a/HarmonyLinkLib/include/Version.h.in +++ b/LibHarmonyLink/include/Version.h.in @@ -15,11 +15,11 @@ // Version.h.in #pragma once -#define HARMONYLINK_VERSION_MAJOR @HarmonyLinkLib_VERSION_MAJOR@ -#define HARMONYLINK_VERSION_MINOR @HarmonyLinkLib_VERSION_MINOR@ -#define HARMONYLINK_VERSION_PATCH @HarmonyLinkLib_VERSION_PATCH@ -#define HARMONYLINK_VERSION_TWEAK @HarmonyLinkLib_VERSION_TWEAK@ -#define HARMONYLINK_VERSION "@HarmonyLinkLib_VERSION@" +#define HARMONYLINK_VERSION_MAJOR @LibHarmonyLink_VERSION_MAJOR@ +#define HARMONYLINK_VERSION_MINOR @LibHarmonyLink_VERSION_MINOR@ +#define HARMONYLINK_VERSION_PATCH @LibHarmonyLink_VERSION_PATCH@ +#define HARMONYLINK_VERSION_TWEAK @LibHarmonyLink_VERSION_TWEAK@ +#define HARMONYLINK_VERSION "@LibHarmonyLink_VERSION@" #define GIT_BRANCH_NAME "@GIT_BRANCH_NAME@" #define GIT_COMMIT_TIMESTAMP "@GIT_COMMIT_TIMESTAMP@" diff --git a/HarmonyLinkLib/src/Version.cpp b/LibHarmonyLink/include/Wine.h similarity index 77% rename from HarmonyLinkLib/src/Version.cpp rename to LibHarmonyLink/include/Wine.h index d340da1..9614ee4 100644 --- a/HarmonyLinkLib/src/Version.cpp +++ b/LibHarmonyLink/include/Wine.h @@ -12,4 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "Version.h" +#pragma once + +#include +#include "Core.h" + +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +bool Detect_Wine(void); + +#ifdef __cplusplus +} +} +#endif diff --git a/LibHarmonyLink/src/LibHarmonyLink.c b/LibHarmonyLink/src/LibHarmonyLink.c new file mode 100644 index 0000000..18bf5ec --- /dev/null +++ b/LibHarmonyLink/src/LibHarmonyLink.c @@ -0,0 +1,84 @@ +// 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 "LibHarmonyLink.h" + +#include "Version.h" +#include "Wine.h" + +static bool bIsWine = false; +static bool bCachedIsWine = false; + +static bool bIsLinux = false; +static bool bCachedIsLinux = false; + +bool HL_Init(void) +{ + HL_version_print(); + Handle_Detect_Wine(); + Handle_Detect_Linux(); + return 1; +} + +void Handle_Detect_Wine(void) +{ +#ifdef BUILD_WINDOWS + bIsWine = Detect_Wine(); +#else + bIsWine = false; +#endif + +bCachedIsWine = true; +} + +bool Get_IsWine(void) +{ + if (!bCachedIsWine) + { + Handle_Detect_Wine(); + } + + return bIsWine; +} + +bool Get_IsLinux(void) +{ + if (!bCachedIsLinux) + { + Handle_Detect_Linux(); + } + + return bIsLinux; +} + +void Handle_Detect_Linux(void) +{ +#ifdef BUILD_LINUX + bIsLinux = true; +#else + bIsLinux = Get_IsWine(); +#endif + +bCachedIsLinux = true; +} + +bool HL_Is_Wine(void) +{ + return Get_IsWine(); +} +bool HL_Is_Linux(void) +{ + return Get_IsLinux(); +} diff --git a/LibHarmonyLink/src/Structs/Battery.c b/LibHarmonyLink/src/Structs/Battery.c new file mode 100644 index 0000000..56d69a2 --- /dev/null +++ b/LibHarmonyLink/src/Structs/Battery.c @@ -0,0 +1,42 @@ +// 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 "Structs/Battery.h" + +#include +#include +#include + +FBattery* HL_FBattery_Init(bool has_battery, bool is_connected_to_ac, unsigned char battery_percent) { + FBattery* battery = (FBattery*)malloc(sizeof(FBattery)); + + if (battery == NULL) { + fprintf(stderr, "Memory allocation failed for FCPUInfo.\n"); + return NULL; + //exit(EXIT_FAILURE); + } + + battery->has_battery = has_battery; + battery->battery_percent = is_connected_to_ac; + battery->is_connected_to_ac = battery_percent; + + return battery; +} + +void FBattery_print(const FBattery* self) +{ + 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/LibHarmonyLink/src/Structs/CPUInfo.c b/LibHarmonyLink/src/Structs/CPUInfo.c new file mode 100644 index 0000000..c88e999 --- /dev/null +++ b/LibHarmonyLink/src/Structs/CPUInfo.c @@ -0,0 +1,83 @@ +// 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 "Structs/CPUInfo.h" +#include "Utilities.h" + +#include +#include + +FCPUInfo* FCPUInfo_Init(const char *vendorID, const char *modelName, unsigned int physicalCores, + unsigned int logicalCores, size_t flagsCount) { + FCPUInfo *cpuInfo = (FCPUInfo*)malloc(sizeof(FCPUInfo)); + + if (cpuInfo == NULL) { + fprintf(stderr, "Memory allocation failed for FCPUInfo.\n"); + exit(EXIT_FAILURE); + } +#if defined(BUILD_WINDOWS) + cpuInfo->VendorID = _strdup(vendorID); + cpuInfo->Model_Name = _strdup(modelName); +#else + cpuInfo->VendorID = strdup(vendorID); + cpuInfo->Model_Name = strdup(modelName); +#endif + + cpuInfo->Physical_Cores = physicalCores; + cpuInfo->Logical_Cores = logicalCores; + StringArray_Init(&cpuInfo->flagsInfo, flagsCount); + + return cpuInfo; +} + +void HL_FlagsInfo_Print(const FCPUInfo* cpuInfo) { + if (!cpuInfo) + { + fprintf(stderr, "cpuInfo is nullptr!\n"); + return; + } + + HL_StringArray_Print(&cpuInfo->flagsInfo); +} + +void HL_FCPUInfo_Print(const FCPUInfo *cpuInfo) { + wchar_t* wVendorID = convertToWideChar(cpuInfo->VendorID); + wchar_t* wModelName = convertToWideChar(cpuInfo->Model_Name); + + wprintf(L"VendorID: %ls\n", wVendorID); + wprintf(L"Model Name: %ls\n", wModelName); + wprintf(L"Physical Cores: %u\n", cpuInfo->Physical_Cores); + wprintf(L"Logical Cores: %u\n", cpuInfo->Logical_Cores); + wprintf(L"Flags:\n"); + HL_StringArray_Print(&cpuInfo->flagsInfo); + + free(wVendorID); + free(wModelName); +} + +bool HL_FlagsInfo_Contains(const FCPUInfo* cpuInfo, const char* flag) { + if (!cpuInfo) + { + fprintf(stderr, "cpuInfo is nullptr!\n"); + return false; + } + + return HL_StringArray_Contains(&cpuInfo->flagsInfo, flag); +} + +void HL_FCPUInfo_Free(FCPUInfo *cpuInfo) { + free(cpuInfo->VendorID); + free(cpuInfo->Model_Name); + HL_StringArray_Free(&cpuInfo->flagsInfo); +} diff --git a/LibHarmonyLink/src/Structs/Device.c b/LibHarmonyLink/src/Structs/Device.c new file mode 100644 index 0000000..082218b --- /dev/null +++ b/LibHarmonyLink/src/Structs/Device.c @@ -0,0 +1,58 @@ +// 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 "Structs/Device.h" +#include "Utilities.h" + +#include +#include + +FDevice* Device_Init(EPlatform platform, EDevice device, ESteamDeck steam_deck_model) { + FDevice* newDevice = (FDevice*)malloc(sizeof(FDevice)); + if (newDevice != NULL) { + newDevice->platform = platform; + newDevice->device = device; + newDevice->steam_deck_model = steam_deck_model; + } + return newDevice; +} + +void HL_Device_Print(const FDevice *Device) { + if (Device == NULL) { + wprintf(L"Device is NULL\n"); + return; + } + + // Assuming that EPlatform, EDevice, and ESteamDeck have corresponding string representations + // which should be implemented for a proper print function + + wchar_t* platformStr = convertToWideChar(Platform_ToString(Device->platform)); + wchar_t* deviceStr = convertToWideChar(Device_ToString(Device->device)); + wchar_t* steamDeckStr = convertToWideChar(SteamDeck_ToString(Device->steam_deck_model)); + + wprintf(L"Device Information:\n"); + wprintf(L"Platform: %ls\n", platformStr); + wprintf(L"Device: %ls\n", deviceStr); + wprintf(L"Steam Deck Model: %ls\n", steamDeckStr); + + free(platformStr); + free(deviceStr); + free(steamDeckStr); +} + +void HL_Device_Free(FDevice *Device) { + if (Device != NULL) { + free(Device); + } +} diff --git a/LibHarmonyLink/src/Structs/OSInfo.c b/LibHarmonyLink/src/Structs/OSInfo.c new file mode 100644 index 0000000..d3493ac --- /dev/null +++ b/LibHarmonyLink/src/Structs/OSInfo.c @@ -0,0 +1,55 @@ +// 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 "Structs/OSInfo.h" + +#ifdef _WIN32 +#define strdup _strdup +#endif + +FOSVerInfo* FOSVerInfo_Init(char* name, char* version, unsigned int id, char* version_id, char* version_codename, char* pretty_name, + char* variant_id) { + FOSVerInfo* OSVerInfo = (FOSVerInfo*)malloc(sizeof(FOSVerInfo)); + + if (OSVerInfo == NULL) { + fprintf(stderr, "Memory allocation failed for FOSVerInfo.\n"); + return NULL; + //exit(EXIT_FAILURE); + } + + OSVerInfo->name = strdup(name); + OSVerInfo->version = strdup(version); + OSVerInfo->id = id; + OSVerInfo->version_id = strdup(version_id); + OSVerInfo->version_codename = strdup(version_codename); + OSVerInfo->pretty_name = strdup(pretty_name); + OSVerInfo->variant_id = strdup(variant_id); + + return OSVerInfo; +} + +void HL_FOSVerInfo_Free(FOSVerInfo* osVerInfo) { + if (!osVerInfo) return; + + free(osVerInfo->name); + free(osVerInfo->version); + free(osVerInfo->version_id); + free(osVerInfo->version_codename); + free(osVerInfo->pretty_name); + free(osVerInfo->variant_id); + free(osVerInfo); +} diff --git a/LibHarmonyLink/src/Structs/StringArray.c b/LibHarmonyLink/src/Structs/StringArray.c new file mode 100644 index 0000000..5165193 --- /dev/null +++ b/LibHarmonyLink/src/Structs/StringArray.c @@ -0,0 +1,121 @@ +// 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 "Structs/StringArray.h" +#include "Utilities.h" + +#include +#include + +// Initialize FlagsInfo with optional initial size +void StringArray_Init(StringArray *flagsInfo, size_t overrideInitialSize) { + size_t initialSize = DEFAULT_INITIAL_FLAGS_SIZE; + + if (overrideInitialSize > 0) { + initialSize = overrideInitialSize; + } + + flagsInfo->FlagsCount = 0; + flagsInfo->AllocatedSize = initialSize; + flagsInfo->data = (char**)malloc(initialSize * sizeof(char*)); + for (size_t i = 0; i < initialSize; ++i) { + flagsInfo->data[i] = NULL; + } +} + +void StringArray_AddFlag(StringArray *flagsInfo, const char *flag) { + // Check if we need to resize the array + if (flagsInfo->FlagsCount >= flagsInfo->AllocatedSize) { + StringArray_Resize(flagsInfo, flagsInfo->AllocatedSize * 2); + } +#if defined(BUILD_WINDOWS) + flagsInfo->data[flagsInfo->FlagsCount] = _strdup(flag); +#else + flagsInfo->data[flagsInfo->FlagsCount] = strdup(flag); +#endif + flagsInfo->FlagsCount++; +} + +void HL_StringArray_Print(const StringArray *flagsInfo) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + if (flagsInfo->data[i] != NULL) { + wchar_t* wstr = convertToWideChar(flagsInfo->data[i]); + wprintf(L" %ls\n", wstr); + free(wstr); + } + } +} + +void HL_StringArray_Free(StringArray *flagsInfo) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + free(flagsInfo->data[i]); + } + free(flagsInfo->data); +} + +void StringArray_Remove(StringArray *flagsInfo, const char *flag) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + if (flagsInfo->data[i] && strcmp(flagsInfo->data[i], flag) == 0) { + free(flagsInfo->data[i]); + for (size_t j = i; j < flagsInfo->FlagsCount - 1; ++j) { + flagsInfo->data[j] = flagsInfo->data[j + 1]; + } + flagsInfo->data[flagsInfo->FlagsCount - 1] = NULL; + flagsInfo->FlagsCount--; + break; + } + } +} + +bool HL_StringArray_Contains(const StringArray *flagsInfo, const char *flag) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + if (flagsInfo->data[i] && strcmp(flagsInfo->data[i], flag) == 0) { + return true; + } + } + return false; +} + +// Resize FlagsInfo array +void StringArray_Resize(StringArray* flagsInfo, size_t newSize) { + // Count the number of non-null pointers + size_t nonNullCount = 0; + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + if (flagsInfo->data[i] != NULL) { + nonNullCount++; + } + } + + // Check if the new size is smaller than the number of non-null pointers + if (newSize < nonNullCount) { + fprintf(stderr, "Resize failed. New size is smaller than the number of non-null pointers.\n"); + return; + } + + char** temp = realloc(flagsInfo->data, newSize * sizeof(char*)); + if (temp != NULL) { + flagsInfo->data = temp; + if (newSize > flagsInfo->AllocatedSize) { + // Initialize new elements to NULL + for (size_t i = flagsInfo->AllocatedSize; i < newSize; ++i) { + flagsInfo->data[i] = NULL; + } + } + flagsInfo->AllocatedSize = newSize; + } else { + // Handle realloc failure + fprintf(stderr, "Realloc failed. Memory not reallocated.\n"); + exit(EXIT_FAILURE); + } +} diff --git a/LibHarmonyLink/src/Utilities.c b/LibHarmonyLink/src/Utilities.c new file mode 100644 index 0000000..5434fee --- /dev/null +++ b/LibHarmonyLink/src/Utilities.c @@ -0,0 +1,44 @@ +// 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 + +wchar_t* convertToWideChar(const char* str) { + size_t len = 0; + +#if defined(BUILD_WINDOWS) + // Use mbstowcs_s on Windows + mbstowcs_s(&len, NULL, 0, str, 0); +#else + // Use mbstowcs on Linux + len = mbstowcs(NULL, str, 0) + 1; +#endif + + // Allocate memory for the wide string + wchar_t* wstr = (wchar_t*)malloc(len * sizeof(wchar_t)); + if (wstr == NULL) { + return NULL; // Handle memory allocation failure + } + +#if defined(BUILD_WINDOWS) + // Use mbstowcs_s on Windows + mbstowcs_s(&len, wstr, len, str, len - 1); +#else + // Use mbstowcs on Linux + mbstowcs(wstr, str, len); +#endif + + return wstr; +} diff --git a/LibHarmonyLink/src/Version.c b/LibHarmonyLink/src/Version.c new file mode 100644 index 0000000..01e0a4b --- /dev/null +++ b/LibHarmonyLink/src/Version.c @@ -0,0 +1,57 @@ +// 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 "Version.h" + +#include +#include +#include +#include + +char* HL_version_get_string(void) +{ + return HARMONYLINK_VERSION; +} + +char* HL_version_build_timestamp(void) +{ + return __TIMESTAMP__; +} + +char* HL_git_branch(void) +{ + return GIT_BRANCH_NAME; +} + +char* HL_git_commit_timestamp(void) +{ + return GIT_COMMIT_TIMESTAMP; +} + +bool HL_is_debug(void) +{ +#ifdef DEBUG_MODE + return true; +#else + return false; +#endif +} + +void HL_version_print(void) { + wprintf(L"HarmonyLink V%hs Copyright (C) 2023 Jordon Brooks\n", HL_version_get_string()); + wprintf(L"Build Timestamp: %hs\n", HL_version_build_timestamp()); + wprintf(L"Git Branch: %hs\n", HL_git_branch()); + wprintf(L"Git Commit Timestamp: %hs\n", HL_git_commit_timestamp()); + wprintf(L"Build type: %ls\n", HL_is_debug() ? L"True" : L"False"); +} diff --git a/LibHarmonyLink/src/Wine.c b/LibHarmonyLink/src/Wine.c new file mode 100644 index 0000000..f2e3b1c --- /dev/null +++ b/LibHarmonyLink/src/Wine.c @@ -0,0 +1,41 @@ +// 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 "Wine.h" + +#include +#include +#ifdef BUILD_WINDOWS +#include +#endif + +bool Detect_Wine(void) +{ + bool isWine = false; + +#ifdef BUILD_WINDOWS + printf("Detecting wine...\n"); + bool HasFound = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != NULL; + + if (!HasFound) + HasFound = GetProcAddress(GetModuleHandleA("ntdll.dll"), "proton_get_version") != NULL; + + printf("wine %s found\n", HasFound ? "has been" : "not"); + + isWine = HasFound; // Cache the result +#else + isWine = false; // In non-Windows builds, always set isWine to false +#endif + return isWine; // Return the cached result +} \ No newline at end of file