From d5b097c6ecb505d75992d7504d76d54b4ac76628 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Wed, 22 May 2024 13:42:37 +0100 Subject: [PATCH 01/18] Initial C version --- .gitignore | 1 + HarmonyLinkLib/CMakeLists.txt | 71 ++--- .../include/Enums/{EDevice.h => Device.h} | 26 +- HarmonyLinkLib/include/Enums/ESteamDeck.h | 29 --- .../Version.cpp => include/Enums/Platform.h} | 11 +- .../SteamDeck.h} | 16 +- HarmonyLinkLib/include/FString.h | 177 ------------- HarmonyLinkLib/include/HarmonyLinkLib.h | 46 +--- .../{Enums/EPlatform.h => Structs/Battery.h} | 23 +- HarmonyLinkLib/include/Structs/FBattery.h | 36 --- HarmonyLinkLib/include/Structs/FCPUInfo.h | 54 ---- HarmonyLinkLib/include/Structs/FDevice.h | 32 --- HarmonyLinkLib/include/Structs/FOSVerInfo.h | 64 ----- HarmonyLinkLib/include/Version.h | 46 +--- .../LinuxUtilities.cpp => HarmonyLinkLib.c} | 30 +-- HarmonyLinkLib/src/HarmonyLinkLib.cpp | 130 ---------- .../src/Platform/IPlatformUtilities.cpp | 245 ------------------ .../src/Platform/IPlatformUtilities.h | 60 ----- .../src/Platform/Unix/Linux/LinuxUtilities.h | 37 --- .../src/Platform/Unix/UnixUtilities.cpp | 72 ----- .../src/Platform/Unix/UnixUtilities.h | 42 --- .../src/Platform/Windows/WindowsUtilities.cpp | 177 ------------- .../src/Platform/Windows/WindowsUtilities.h | 40 --- HarmonyLinkLib/src/Platform/WineUtilities.cpp | 216 --------------- HarmonyLinkLib/src/Platform/WineUtilities.h | 60 ----- .../Mac/MacUtilities.h => Structs/Battery.c} | 13 +- HarmonyLinkLib/src/Utilities.cpp | 53 ---- HarmonyLinkLib/src/{Utilities.h => Version.c} | 40 ++- HarmonyLinkLib/src/dllmain.c | 0 HarmonyLinkLib/src/dllmain.cpp | 61 ----- HarmonyLinkTest/CMakeLists.txt | 6 +- .../src/main.c | 17 +- HarmonyLinkTest/src/main.cpp | 161 ------------ 33 files changed, 123 insertions(+), 1969 deletions(-) rename HarmonyLinkLib/include/Enums/{EDevice.h => Device.h} (69%) delete mode 100644 HarmonyLinkLib/include/Enums/ESteamDeck.h rename HarmonyLinkLib/{src/Version.cpp => include/Enums/Platform.h} (80%) rename HarmonyLinkLib/include/{HarmonyLinkStruct.h => Enums/SteamDeck.h} (71%) delete mode 100644 HarmonyLinkLib/include/FString.h rename HarmonyLinkLib/include/{Enums/EPlatform.h => Structs/Battery.h} (72%) delete mode 100644 HarmonyLinkLib/include/Structs/FBattery.h delete mode 100644 HarmonyLinkLib/include/Structs/FCPUInfo.h delete mode 100644 HarmonyLinkLib/include/Structs/FDevice.h delete mode 100644 HarmonyLinkLib/include/Structs/FOSVerInfo.h rename HarmonyLinkLib/src/{Platform/Unix/Linux/LinuxUtilities.cpp => HarmonyLinkLib.c} (54%) delete mode 100644 HarmonyLinkLib/src/HarmonyLinkLib.cpp delete mode 100644 HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp delete mode 100644 HarmonyLinkLib/src/Platform/IPlatformUtilities.h delete mode 100644 HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h delete mode 100644 HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp delete mode 100644 HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h delete mode 100644 HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp delete mode 100644 HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h delete mode 100644 HarmonyLinkLib/src/Platform/WineUtilities.cpp delete mode 100644 HarmonyLinkLib/src/Platform/WineUtilities.h rename HarmonyLinkLib/src/{Platform/Unix/Mac/MacUtilities.h => Structs/Battery.c} (63%) delete mode 100644 HarmonyLinkLib/src/Utilities.cpp rename HarmonyLinkLib/src/{Utilities.h => Version.c} (59%) create mode 100644 HarmonyLinkLib/src/dllmain.c delete mode 100644 HarmonyLinkLib/src/dllmain.cpp rename HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp => HarmonyLinkTest/src/main.c (67%) delete mode 100644 HarmonyLinkTest/src/main.cpp diff --git a/.gitignore b/.gitignore index 0839667..2e489f4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ build/** # Blacklist specific build directories linuxbuild/ build/ +.idea/ diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 03440bf..95ca22a 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -14,19 +14,9 @@ cmake_minimum_required(VERSION 3.10) project(HarmonyLinkLib VERSION 2.1.1) -include(FetchContent) - -# Fetch fmt library -FetchContent_Declare( - fmt - GIT_REPOSITORY https://github.com/fmtlib/fmt.git - GIT_TAG 10.2.1 # Specify the desired version of {fmt} -) - -FetchContent_MakeAvailable(fmt) - -set_target_properties(fmt PROPERTIES FOLDER External) -set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +# Specify the C++ standard +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) # Find the current Git branch and the last commit timestamp find_package(Git QUIET) @@ -50,10 +40,6 @@ endif() configure_file(include/Version.h.in Version.generated.h) -# Specify the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) - # Define metadata variables set(FILE_DESCRIPTION "Enhances handheld gaming with intelligent hardware recognition, dynamic adaptability, and robust API access for Windows and Linux, including Steam Deck and Wine support.") set(INTERNAL_NAME "HarmonyLinkLib") @@ -66,63 +52,43 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Resources/Version.rc.in ${CMAKE_CURRE # Explicitly list source files set(COMMON_SOURCES - "src/Platform/IPlatformUtilities.cpp" - "src/HarmonyLinkLib.cpp" - "src/Version.cpp" - "src/dllmain.cpp" - "src/Platform/WineUtilities.cpp" - "src/Utilities.cpp" + "src/dllmain.c" + "src/HarmonyLinkLib.c" + "src/Version.c" + + "src/Structs/Battery.c" ) # Explicitly list include files set(COMMON_INCLUDES "include/Core.h" - "include/Structs/FBattery.h" - "include/Structs/FOSVerInfo.h" - "include/Structs/FDevice.h" - "include/Structs/FCPUInfo.h" - "include/Enums/EDevice.h" - "include/Enums/EPlatform.h" - "include/Enums/ESteamDeck.h" - "include/FString.h" "include/HarmonyLinkLib.h" "include/Version.h" - "src/Platform/IPlatformUtilities.h" - "src/Platform/WineUtilities.h" - "src/Utilities.h" -) - -# Adding fmt headers explicitly -set(FMT_HEADERS - "${fmt_SOURCE_DIR}/include/fmt" + + "include/Enums/Device.h" + "include/Enums/Platform.h" + "include/Enums/SteamDeck.h" + + "include/Structs/Battery.h" ) set(WINDOWS_SOURCES - "src/Platform/Windows/WindowsUtilities.cpp" ) set(WINDOWS_INCLUDES - "src/Platform/Windows/WindowsUtilities.h" ) set(LINUX_SOURCES - "src/Platform/Unix/Linux/LinuxUtilities.cpp" - "src/Platform/Unix/UnixUtilities.cpp" ) set(LINUX_INCLUDES - "src/Platform/Unix/Linux/LinuxUtilities.h" - "src/Platform/Unix/UnixUtilities.h" + ) set(MAC_SOURCES - "src/Platform/Unix/Mac/MacUtilities.cpp" - "src/Platform/Unix/UnixUtilities.cpp" ) set(MAC_INCLUDES - "src/Platform/Unix/Mac/MacUtilities.h" - "src/Platform/Unix/UnixUtilities.h" ) # Platform-specific definitions @@ -166,9 +132,6 @@ target_include_directories(HarmonyLinkLibStatic ) target_compile_definitions(HarmonyLinkLibStatic PRIVATE HARMONYLINKLIB_STATIC) -# Include fmt headers -target_include_directories(HarmonyLinkLibStatic PRIVATE ${FMT_HEADERS}) - # Set output directories for all build types foreach(TYPE IN ITEMS DEBUG RELEASE) string(TOUPPER ${TYPE} TYPE_UPPER) @@ -182,10 +145,6 @@ foreach(TYPE IN ITEMS DEBUG RELEASE) ) endforeach() -target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt) -target_link_libraries(HarmonyLinkLibShared PRIVATE fmt) if (UNIX) - target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) - target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) endif() diff --git a/HarmonyLinkLib/include/Enums/EDevice.h b/HarmonyLinkLib/include/Enums/Device.h similarity index 69% rename from HarmonyLinkLib/include/Enums/EDevice.h rename to HarmonyLinkLib/include/Enums/Device.h index c11919d..8ee0946 100644 --- a/HarmonyLinkLib/include/Enums/EDevice.h +++ b/HarmonyLinkLib/include/Enums/Device.h @@ -17,21 +17,15 @@ // Undefine the LINUX macro to avoid conflicts with the enum definition. #undef LINUX -#include - -// Enum class for representing different types of devices -namespace HarmonyLinkLib +typedef enum { - enum class EDevice : uint8_t - { - UNKNOWN, - DESKTOP, - LAPTOP, - HANDHELD, + EDevice_UNKNOWN, + EDevice_DESKTOP, + EDevice_LAPTOP, + EDevice_HANDHELD, - STEAM_DECK, - // ROG_ALLY - // AYONEO_SLIDE - // etc... - }; -} + EDevice_STEAM_DECK, + // EDevice_ROG_ALLY + // EDevice_AYONEO_SLIDE + // etc... +} EDevice; diff --git a/HarmonyLinkLib/include/Enums/ESteamDeck.h b/HarmonyLinkLib/include/Enums/ESteamDeck.h deleted file mode 100644 index 9fbad64..0000000 --- a/HarmonyLinkLib/include/Enums/ESteamDeck.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -// Enum class for representing different types of devices -namespace HarmonyLinkLib -{ - enum class ESteamDeck : uint8_t - { - NONE, // Device is not a steam deck - UNKNOWN, // Device is a steam deck but model cannot be determined - LCD, - OLED, - }; -} diff --git a/HarmonyLinkLib/src/Version.cpp b/HarmonyLinkLib/include/Enums/Platform.h similarity index 80% rename from HarmonyLinkLib/src/Version.cpp rename to HarmonyLinkLib/include/Enums/Platform.h index d340da1..c077d8c 100644 --- a/HarmonyLinkLib/src/Version.cpp +++ b/HarmonyLinkLib/include/Enums/Platform.h @@ -12,4 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "Version.h" +#pragma once + +typedef enum +{ + EPlatform_UNKNOWN, + EPlatform_WINDOWS, + EPlatform_LINUX, + EPlatform_MAC, + EPlatform_UNIX, +} EPlatform; diff --git a/HarmonyLinkLib/include/HarmonyLinkStruct.h b/HarmonyLinkLib/include/Enums/SteamDeck.h similarity index 71% rename from HarmonyLinkLib/include/HarmonyLinkStruct.h rename to HarmonyLinkLib/include/Enums/SteamDeck.h index 362750b..142504e 100644 --- a/HarmonyLinkLib/include/HarmonyLinkStruct.h +++ b/HarmonyLinkLib/include/Enums/SteamDeck.h @@ -14,14 +14,10 @@ #pragma once -struct HarmonyLinkStruct +typedef enum { - // Virtual destructor is important for proper cleanup of derived types - virtual ~HarmonyLinkStruct() = default; - - // Method to deallocate the object - void free() const - { - delete this; - } -}; + ESteamDeck_NONE, // Device is not a steam deck + ESteamDeck_UNKNOWN, // Device is a steam deck but model cannot be determined + ESteamDeck_LCD, + ESteamDeck_OLED, +} ESteamDeck; diff --git a/HarmonyLinkLib/include/FString.h b/HarmonyLinkLib/include/FString.h deleted file mode 100644 index 68ae766..0000000 --- a/HarmonyLinkLib/include/FString.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include -#include - -#include "Core.h" // Replace with actual API export macro - -/** - * @file FString.h - * @brief FString Class - Custom String Management for DLL Export - * - * The FString class is a custom string management class designed to safely encapsulate - * string handling and memory management, especially for use in DLLs (Dynamic Link Libraries). - * It resolves the common issue of exporting classes containing standard library types, - * such as std::string, across DLL boundaries, which can lead to compiler warnings or errors. - * - * Features: - * - Implements basic string operations such as construction, destruction, copy, and move semantics. - * - Utilizes smart pointers (std::unique_ptr) for automatic memory management, reducing the risk of memory leaks. - * - Provides a simple interface for interacting with character strings, similar to std::string. - * - Includes both deep copy semantics for safety and move semantics for performance in object transfers. - * - * Usage: - * FString can be used as a safer alternative to std::string for classes that are exported from a DLL. - * It handles memory allocation/deallocation automatically and provides a basic set of string operations. - * - * Example: - * FString myString("Hello, world!"); - * std::cout << myString.c_str() << std::endl; // Output: Hello, world! - * - * Note: - * - The class is currently designed with basic functionality. Additional features such as - * string concatenation, substring, and comparison operations can be added as needed. - * - Ensure that the HarmonyLinkLibApi.h (or equivalent) file correctly defines the export macro - * for DLL usage. - * - */ - namespace HarmonyLinkLib - { - class HARMONYLINKLIB_API FString { - public: - FString() : data_(new char[1]) { - data_[0] = '\0'; - } - - FString(const char* str) { - const size_t len = strlen(str); - data_ = new char[len + 1]; - memcpy(data_, str, len + 1); - } - - // Copy constructor - FString(const FString& other) { - const size_t len = strlen(other.data_); - data_ = new char[len + 1]; - memcpy(data_, other.data_, len + 1); - } - - ~FString() { - delete[] data_; - } - - // Copy assignment operator - FString& operator=(const FString& other) { - if (this != &other) { - delete[] data_; - const size_t len = strlen(other.data_); - data_ = new char[len + 1]; - memcpy(data_, other.data_, len + 1); - } - return *this; - } - - // Concatenation operator for FString objects - FString operator+(const FString& other) const { - size_t thisLen = strlen(this->data_); - size_t otherLen = strlen(other.data_); - char* concatenated = new char[thisLen + otherLen + 1]; - - memcpy(concatenated, this->data_, thisLen); - memcpy(concatenated + thisLen, other.data_, otherLen + 1); - - FString result(concatenated); - delete[] concatenated; - return result; - } - - // Concatenation operator for const char* - FString operator+(const char* other) const { - return *this + FString(other); - } - - // Friend function to allow concatenation with const char* on the left-hand side - friend FString operator+(const char* lhs, const FString& rhs) { - return FString(lhs) + rhs; - } - - // Move constructor - FString(FString&& other) noexcept : data_(other.data_) { - other.data_ = nullptr; - } - - FString(const std::string& str) { - const size_t len = str.length(); - data_ = new char[len + 1]; - memcpy(data_, str.c_str(), len + 1); - } - - // Move assignment operator - FString& operator=(FString&& other) noexcept { - if (this != &other) { - delete[] data_; - data_ = other.data_; - other.data_ = nullptr; - } - return *this; - } - - bool operator==(const FString& other) const { - return strcmp(data_, other.data_) == 0; - } - - // Method to get a lowercase version of the string - static FString to_lower(FString& from) - { - for (size_t i = 0; i < strlen(from.data_); ++i) { - from.data_[i] = static_cast(std::tolower(static_cast(from.data_[i]))); - } - return from; - } - - // Overloaded static method to handle const char* - static FString to_lower(const char* from) { - FString temp_string(from); // Create an FString from const char* - return to_lower(temp_string); // Reuse the existing to_lower method - } - - const char* c_str() const { - return data_; - } - - private: - char* data_ = nullptr; - }; - } - -namespace std { - template<> - struct hash { - size_t operator()(const HarmonyLinkLib::FString& s) const { - size_t hashValue = 5381; // Starting value recommended by the djb2 algorithm - const char* str = s.c_str(); - - for (size_t i = 0; str[i] != '\0'; ++i) { - hashValue = ((hashValue << 5) + hashValue) + static_cast(str[i]); - // Equivalent to hashValue * 33 + str[i] - } - - return hashValue; - } - }; -} diff --git a/HarmonyLinkLib/include/HarmonyLinkLib.h b/HarmonyLinkLib/include/HarmonyLinkLib.h index d6575a5..9930ffd 100644 --- a/HarmonyLinkLib/include/HarmonyLinkLib.h +++ b/HarmonyLinkLib/include/HarmonyLinkLib.h @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Jordon Brooks +// Copyright (c) 2024 Jordon Brooks // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,49 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. - -/** - * IMPORTANT REMINDER: - * Do NOT use standard output functions like std::cout and printf anywhere in this codebase. - * - * Reason: - * Unreal Engine 5's packaging tool encounters issues with these functions, leading to - * packaging failures. The engine sets stdout to UTF-8, which can cause conflicts with - * these standard functions, resulting in a "SECURE CRT: Invalid parameter detected" error - * during packaging. - * - * This issue once required an extensive debugging effort that lasted over 8 hours. - * To prevent similar issues in the future and ensure smooth packaging, always use - * wide-character versions of these functions, such as wprintf and std::wcout, when working - * within the DLL. These functions are compatible with the UTF-8 setting in Unreal Engine 5. - * - */ - - #pragma once +#include #include "Core.h" -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FDevice.h" -#include "Structs/FOSVerInfo.h" - -class IPlatformUtilities; - -namespace HarmonyLinkLib -{ - extern "C" HARMONYLINKLIB_API bool get_is_wine(); - - extern "C" HARMONYLINKLIB_API bool get_is_linux(); - - extern "C" HARMONYLINKLIB_API bool get_is_docked(); - - extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info(); - - extern "C" HARMONYLINKLIB_API FDevice* get_device_info(); - - extern "C" HARMONYLINKLIB_API FOSVerInfo* get_os_version(); - - extern "C" HARMONYLINKLIB_API FBattery* get_battery_status(); -} +HARMONYLINKLIB_API bool HarmonyLink_Init(void); diff --git a/HarmonyLinkLib/include/Enums/EPlatform.h b/HarmonyLinkLib/include/Structs/Battery.h similarity index 72% rename from HarmonyLinkLib/include/Enums/EPlatform.h rename to HarmonyLinkLib/include/Structs/Battery.h index ffa2be7..0ee37b3 100644 --- a/HarmonyLinkLib/include/Enums/EPlatform.h +++ b/HarmonyLinkLib/include/Structs/Battery.h @@ -14,17 +14,16 @@ #pragma once -#include +#include -// Enum class for representing different operating platforms -namespace HarmonyLinkLib +#include "Core.h" + +typedef struct { - enum class EPlatform : uint8_t - { - UNKNOWN, - WINDOWS, - LINUX, - MAC, - UNIX, - }; -} + bool has_battery; + bool is_connected_to_ac; + unsigned char battery_percent; +} FBattery; + +HARMONYLINKLIB_API void FBattery_print(const FBattery* self); + diff --git a/HarmonyLinkLib/include/Structs/FBattery.h b/HarmonyLinkLib/include/Structs/FBattery.h deleted file mode 100644 index 3a40095..0000000 --- a/HarmonyLinkLib/include/Structs/FBattery.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include - -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FBattery : HarmonyLinkStruct - { - bool has_battery; - bool is_connected_to_ac; - uint8_t battery_percent; - - void to_string() const { - std::wcout << "Battery present: " << (has_battery ? "'Yes'" : "'No'") << '\n'; - std::wcout << "Connected to AC: " << (is_connected_to_ac ? "'Yes'" : "'No'") << '\n'; - std::wcout << "Battery percent: '" << static_cast(battery_percent) << "%'" << '\n'; - } - }; -} diff --git a/HarmonyLinkLib/include/Structs/FCPUInfo.h b/HarmonyLinkLib/include/Structs/FCPUInfo.h deleted file mode 100644 index 827bc40..0000000 --- a/HarmonyLinkLib/include/Structs/FCPUInfo.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include -#include "FString.h" - -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FCPUInfo : HarmonyLinkStruct - { - FString VendorID; - FString Model_Name; - uint32_t Physical_Cores = 0; - uint32_t Logical_Cores = 0; - std::unordered_set Flags; - - void print() const - { - wprintf(L"VendorID: '%hs'\n", VendorID.c_str()); - wprintf(L"Model_Name: '%hs'\n", Model_Name.c_str()); - wprintf(L"Physical_Cores: '%d'\n", Physical_Cores); - wprintf(L"Logical_Cores: '%d'\n", Logical_Cores); - - // Initialize a string to hold all flags - std::string allFlags; - for (const auto& flag : Flags) { - allFlags += std::string(flag.c_str()) + " "; // Append each flag followed by a space - } - - // Remove the trailing space - if (!allFlags.empty()) { - allFlags.pop_back(); - } - - wprintf(L"Flags: '%hs'\n", allFlags.c_str()); - } - }; -} diff --git a/HarmonyLinkLib/include/Structs/FDevice.h b/HarmonyLinkLib/include/Structs/FDevice.h deleted file mode 100644 index b574d6a..0000000 --- a/HarmonyLinkLib/include/Structs/FDevice.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -#include "Enums/EDevice.h" -#include "Enums/EPlatform.h" -#include "Enums/ESteamDeck.h" - -namespace HarmonyLinkLib -{ - // Struct to represent a specific device with both platform and device type - struct FDevice : HarmonyLinkStruct - { - EPlatform platform = EPlatform::UNKNOWN; - EDevice device = EDevice::UNKNOWN; - ESteamDeck steam_deck_model = ESteamDeck::NONE; - }; -} diff --git a/HarmonyLinkLib/include/Structs/FOSVerInfo.h b/HarmonyLinkLib/include/Structs/FOSVerInfo.h deleted file mode 100644 index a308a22..0000000 --- a/HarmonyLinkLib/include/Structs/FOSVerInfo.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "FString.h" -#include "HarmonyLinkStruct.h" - -namespace HarmonyLinkLib -{ - struct FOSVerInfo : HarmonyLinkStruct { - // 'name' represents the operating system's name, e.g., "Ubuntu" in Linux or "Windows" in Windows systems. - FString name; - - // 'version' is a numerical representation of the OS version. In Linux, it might be the kernel version, - // whereas in Windows, it could be the major version number like 10 for Windows 10. - uint32_t version = 0; - - // 'id' is a unique identifier for the OS. In Linux, it might be a lower-case string like "ubuntu". - // In Windows, this could map to the edition ID, such as "Professional". - FString id; - - // 'version_id' is a string representing the specific version of the OS. - // For example, "20.04" in Ubuntu or "1909" in Windows 10. - FString version_id; - - // 'version_codename' is a codename for the OS version, if available. - // This is common in Linux distributions (e.g., "focal" for Ubuntu 20.04) but not typically used in Windows. - FString version_codename; - - // 'pretty_name' is a more readable version of the name, potentially including the version and codename. - // For example, "Ubuntu 20.04 LTS (Focal Fossa)" or "Windows 10 Pro". - FString pretty_name; - - // 'variant_id' is an identifier for the specific variant of the OS, if available. - // For example, in Linux distributions, this might be "desktop" for the desktop edition, - // "server" for the server edition, or "core" for a minimal installation. It helps distinguish - // between different flavors or editions of the same version. - // On the Steam Deck, this is set to "steamdeck". - FString variant_id; - - void print() const - { - wprintf(L"Name: '%hs'\n", name.c_str()); - wprintf(L"Version: '%d'\n", version); - wprintf(L"ID: '%hs'\n", id.c_str()); - wprintf(L"Version ID: '%hs'\n", version_id.c_str()); - wprintf(L"Version Codename: '%hs'\n", version_codename.c_str()); - wprintf(L"Pretty Name: '%hs'\n", pretty_name.c_str()); - wprintf(L"Variant ID: '%hs'\n", variant_id.c_str()); - } -}; -} diff --git a/HarmonyLinkLib/include/Version.h b/HarmonyLinkLib/include/Version.h index dcc9d33..74f6179 100644 --- a/HarmonyLinkLib/include/Version.h +++ b/HarmonyLinkLib/include/Version.h @@ -14,45 +14,11 @@ #pragma once +#include #include "Core.h" -#include -#include "FString.h" - -namespace HarmonyLinkLib -{ - class HARMONYLINKLIB_API version - { - public: - version() = default; - - static FString ToString() - { - return HARMONYLINK_VERSION; - } - - static FString get_build_timestamp() - { - return {__TIMESTAMP__}; - } - - static FString get_git_branch() - { - return {GIT_BRANCH_NAME}; - } - - static FString get_git_commit_timestamp() - { - return {GIT_COMMIT_TIMESTAMP}; - } - - static bool is_debug() - { -#ifdef DEBUG_MODE - return true; -#else - return false; -#endif - } - }; -} +HARMONYLINKLIB_API char* get_version_string(void); +HARMONYLINKLIB_API char* get_version_build_timestamp(void); +HARMONYLINKLIB_API char* get_git_branch(void); +HARMONYLINKLIB_API char* get_git_commit_timestamp(void); +HARMONYLINKLIB_API bool get_is_debug(void); diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.c similarity index 54% rename from HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp rename to HarmonyLinkLib/src/HarmonyLinkLib.c index 490e869..9d1f950 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp +++ b/HarmonyLinkLib/src/HarmonyLinkLib.c @@ -12,27 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "LinuxUtilities.h" +#include "HarmonyLinkLib.h" +#include +#include "Version.h" -#include -#include -#include "Platform/WineUtilities.h" - -namespace HarmonyLinkLib +bool HarmonyLink_Init(void) { - std::shared_ptr LinuxUtilities::get_battery_status() - { - return WineUtilities::get_battery_status(); - } - - std::shared_ptr LinuxUtilities::get_os_version() - { - return WineUtilities::get_linux_info(); - } - - std::shared_ptr LinuxUtilities::get_cpu_info() - { - return WineUtilities::get_cpu_info(); - } + wprintf(L"HarmonyLink V%hs Copyright (C) 2023 Jordon Brooks\n", get_version_string()); + wprintf(L"Build Timestamp: %hs\n", get_version_build_timestamp()); + wprintf(L"Git Branch: %hs\n", get_git_branch()); + wprintf(L"Git Commit Timestamp: %hs\n", get_git_commit_timestamp()); + wprintf(L"Build type: %ls\n", get_is_debug() ? L"True" : L"False"); + return 1; } diff --git a/HarmonyLinkLib/src/HarmonyLinkLib.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.cpp deleted file mode 100644 index 91ccc2c..0000000 --- a/HarmonyLinkLib/src/HarmonyLinkLib.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "HarmonyLinkLib.h" - -#include -#include "Platform/IPlatformUtilities.h" - -namespace HarmonyLinkLib -{ - std::shared_ptr PlatformUtilities = IPlatformUtilities::GetInstance(); - - bool get_is_wine() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_running_under_wine(); - } - - bool get_is_linux() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_linux(); - } - - bool get_is_docked() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return false; - } - - return PlatformUtilities->is_docked(); - } - - FCPUInfo* get_cpu_info() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr cpu_info = PlatformUtilities->get_cpu_info(); - if (!cpu_info) - { - return nullptr; - } - - FCPUInfo* new_cpu_info = new FCPUInfo(*cpu_info); - return new_cpu_info; - } - - FDevice* get_device_info() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr device = PlatformUtilities->get_device(); - if (!device) - { - return nullptr; - } - - FDevice* new_device = new FDevice(*device); - return new_device; - } - - FOSVerInfo* get_os_version() - { - - - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr os_version_info = PlatformUtilities->get_os_version(); - if (!os_version_info) - { - return nullptr; - } - - FOSVerInfo* new_os_info = new FOSVerInfo(*os_version_info); - return new_os_info; - } - - FBattery* get_battery_status() - { - if (!PlatformUtilities) - { - std::wcout << "Failed to get platform utilities!\n"; - return nullptr; - } - - const std::shared_ptr new_battery = PlatformUtilities->get_battery_status(); - if (!new_battery) - { - return nullptr; - } - - FBattery* battery = new FBattery(*new_battery); - return battery; - } -} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp deleted file mode 100644 index 735eeab..0000000 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "IPlatformUtilities.h" - -#include -#include -#include - -#include "Utilities.h" - -#include "WineUtilities.h" -#if BUILD_WINDOWS -#include "Windows/WindowsUtilities.h" -#elif BUILD_LINUX -#include "Unix/Linux/LinuxUtilities.h" -#elif BUILD_MAC -#include "Unix/Mac/MacUtilities.h" -#elif BUILD_UNIX -#include "Unix/Mac/MacUtilities.h" -#endif - -namespace HarmonyLinkLib -{ - static std::shared_ptr INSTANCE = nullptr; - - std::shared_ptr& IPlatformUtilities::GetInstance() - { - if (!INSTANCE) - { - #if BUILD_WINDOWS - INSTANCE = std::make_shared(); - #elif BUILD_LINUX - INSTANCE = std::make_shared(); - #elif BUILD_MAC - INSTANCE = std::make_shared(); - #elif BUILD_UNIX - INSTANCE = std::make_shared(); - // ... other platform checks - #else - std::wcout << "Platform is not supported.\n" - #endif - } - - return INSTANCE; - } - - bool IPlatformUtilities::is_running_under_wine() - { - return WineUtilities::is_wine_present(); - } - - bool IPlatformUtilities::is_linux() - { - #ifdef BUILD_LINUX - return true; - #else - return is_running_under_wine(); - #endif - } - - bool IPlatformUtilities::is_steam_deck() - { - const std::shared_ptr device = get_device(); - - return device && device->device == EDevice::STEAM_DECK; - } - - bool IPlatformUtilities::is_docked() - { - static constexpr uint8_t CHARGING_SCORE = 3; - static constexpr uint8_t EXTERNAL_MONITOR_SCORE = 4; - static constexpr uint8_t STEAM_DECK_RESOLUTION_SCORE = 3; - static constexpr uint8_t KEYBOARD_DETECTION_SCORE = 1; - static constexpr uint8_t MOUSE_DETECTION_SCORE = 2; - static constexpr uint8_t CONTROLLER_DETECTION_SCORE = 3; - static constexpr uint8_t FINAL_TARGET_DETECTION_SCORE = 9; - - - const std::shared_ptr device = get_device(); - - if (!device) - { - std::wcout << "Error: failed to get device.\n"; - return false; - } - - if (device->device != EDevice::STEAM_DECK) - { - std::wcout << "Error: Dock detection is currently only supported on Steam Decks.\n"; - return false; - } - - uint8_t score = 0; - - Utilities::DebugPrint("Detected: ", false); - - if (is_charging()) - { - Utilities::DebugPrint("Charging, ", false); - score += CHARGING_SCORE; - } - - if (get_is_external_monitor_connected()) - { - Utilities::DebugPrint("External monitor, ", false); - score += EXTERNAL_MONITOR_SCORE; - } - - if (get_is_steam_deck_native_resolution()) - { - Utilities::DebugPrint("Non-native resolution, ", false); - score += STEAM_DECK_RESOLUTION_SCORE; - } - - if (get_keyboard_detected()) - { - Utilities::DebugPrint("keyboard ", false); - score += KEYBOARD_DETECTION_SCORE; - } - - if (get_mouse_detected()) - { - Utilities::DebugPrint("mouse, ", false); - score += MOUSE_DETECTION_SCORE; - } - - if (get_external_controller_detected()) - { - Utilities::DebugPrint("external controller, ", false); - score += CONTROLLER_DETECTION_SCORE; - } - - Utilities::DebugPrint(fmt::format("Score: {}/{}", score, FINAL_TARGET_DETECTION_SCORE).c_str()); - - return score >= FINAL_TARGET_DETECTION_SCORE; - } - - std::shared_ptr IPlatformUtilities::get_device() - { - FDevice new_device; - - if (is_linux()) - { - new_device.platform = EPlatform::LINUX; - } - else - { - new_device.platform = EPlatform::WINDOWS; - } - - const std::shared_ptr battery_status = get_battery_status(); - - if (battery_status && !battery_status->has_battery) - { - new_device.device = EDevice::DESKTOP; - } - else - { - new_device.device = EDevice::LAPTOP; - } - - const ESteamDeck steam_deck_model = detect_steam_deck(new_device); - - if (steam_deck_model != ESteamDeck::NONE) { - new_device.device = EDevice::STEAM_DECK; - new_device.steam_deck_model = steam_deck_model; - } - return std::make_shared(new_device); - } - - // Helper function to check if the device is a Steam Deck - ESteamDeck IPlatformUtilities::detect_steam_deck(const FDevice& device) { - // Check if the device is already identified as a Steam Deck - if (device.device == EDevice::STEAM_DECK && device.steam_deck_model != ESteamDeck::NONE) { - return device.steam_deck_model; - } - - ESteamDeck steam_deck_model = ESteamDeck::NONE; - - // Retrieve and process CPU information - const std::shared_ptr cpu_info = get_cpu_info(); - if (!cpu_info) { - wprintf(L"CPU information not available.\n"); - } else { - // Convert the CPU model name to lower case once - FString cpu_model_lower = FString::to_lower(cpu_info->Model_Name); - - // Map of CPU models to their corresponding Steam Deck models - static const std::unordered_map model_map = { - {FString::to_lower("amd custom apu 0405"), ESteamDeck::LCD}, - {FString::to_lower("amd custom apu 0932"), ESteamDeck::OLED} - }; - - auto iterator = model_map.find(cpu_model_lower); - if (iterator != model_map.end()) { - steam_deck_model = iterator->second; - wprintf(L"Steam Deck detected by CPU model name: %hs.\n", cpu_model_lower.c_str()); - } - } - - // Check for Steam Deck by OS version only if no model has been detected yet - if (steam_deck_model == ESteamDeck::NONE) - { - if (const std::shared_ptr version = get_os_version()) - { - if (version->variant_id == "steamdeck" && version->name == "SteamOS") - { - // Use UNKNOWN if OS matches but CPU model doesn't fit known profiles - steam_deck_model = ESteamDeck::UNKNOWN; - wprintf(L"Steam Deck OS detected but model is unknown.\n"); - } - } - else - { - wprintf(L"OS version information not available.\n"); - } - } - - return steam_deck_model; - } - - bool IPlatformUtilities::is_connected_to_ac() - { - const std::shared_ptr battery = get_battery_status(); - return battery && battery->is_connected_to_ac; - } - - bool IPlatformUtilities::is_charging() - { - const std::shared_ptr battery = get_battery_status(); - return battery && battery->has_battery && battery->is_connected_to_ac; - } -} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h deleted file mode 100644 index e6f034f..0000000 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Enums/ESteamDeck.h" -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FDevice.h" -#include "Structs/FOSVerInfo.h" - -namespace HarmonyLinkLib -{ - class IPlatformUtilities { - public: - static std::shared_ptr& GetInstance(); - - IPlatformUtilities() = default; - IPlatformUtilities(const IPlatformUtilities& other) = default; - IPlatformUtilities(IPlatformUtilities&& other) = default; - IPlatformUtilities& operator=(const IPlatformUtilities& other) = default; - IPlatformUtilities& operator=(IPlatformUtilities&& other) = default; - virtual ~IPlatformUtilities() = default; - - // General OS-level functions - virtual bool is_running_under_wine(); - virtual bool is_linux(); - virtual bool is_steam_deck(); - virtual bool is_docked(); - - virtual std::shared_ptr get_device(); - virtual std::shared_ptr get_cpu_info() = 0; - virtual std::shared_ptr get_battery_status() = 0; - virtual std::shared_ptr get_os_version() = 0; - virtual bool get_is_external_monitor_connected() = 0; - virtual bool get_keyboard_detected() = 0; - virtual bool get_mouse_detected() = 0; - virtual bool get_external_controller_detected() = 0; - virtual bool get_is_steam_deck_native_resolution() = 0; - //virtual bool get_is_ethernet_connected() = 0; - //virtual bool get_is_external_input_detected() = 0; - - ESteamDeck detect_steam_deck(const FDevice& device); - bool is_connected_to_ac(); - bool is_charging(); - - // Add more virtual functions for other OS interactions here - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h deleted file mode 100644 index ee1f516..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Structs/FOSVerInfo.h" - -#include "Platform/Unix/UnixUtilities.h" - -namespace HarmonyLinkLib -{ - class LinuxUtilities : public UnixUtilities { - public: - // Implementation for other Linux-specific functions - std::shared_ptr get_battery_status() override; - - std::shared_ptr get_os_version() override; - - std::shared_ptr get_cpu_info() override; - - bool is_linux() override - { - return true; - } - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp deleted file mode 100644 index 0d3b777..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "UnixUtilities.h" - -namespace HarmonyLinkLib -{ - bool UnixUtilities::is_running_under_wine() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return false; - } - - std::shared_ptr UnixUtilities::get_cpu_info() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - std::shared_ptr UnixUtilities::get_battery_status() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - std::shared_ptr UnixUtilities::get_os_version() - { - std::wcout << "This feature is not supported on unix systems yet.\n"; - return nullptr; - } - - bool UnixUtilities::get_is_external_monitor_connected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_keyboard_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_mouse_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_external_controller_detected() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } - - bool UnixUtilities::get_is_steam_deck_native_resolution() - { - std::wcout << "This feature is not supported on unix-based systems yet.\n"; - return false; - } -} \ No newline at end of file diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h deleted file mode 100644 index 8a06546..0000000 --- a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Platform/IPlatformUtilities.h" -namespace HarmonyLinkLib -{ - // This is more of a "catch all" for all unix-based systems - // that don't have their own implementations. - class UnixUtilities : public IPlatformUtilities { - public: - bool is_running_under_wine() override; - - std::shared_ptr get_cpu_info() override; - std::shared_ptr get_battery_status() override; - std::shared_ptr get_os_version() override; - - bool get_is_external_monitor_connected() override; - - bool get_keyboard_detected() override; - - bool get_mouse_detected() override; - - bool get_external_controller_detected() override; - - bool get_is_steam_deck_native_resolution() override; - - // Implementation for other Unix/Linux-specific functions - }; -} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp deleted file mode 100644 index dfd7aa8..0000000 --- a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "WindowsUtilities.h" - -#include -#include - -#include -#pragma comment(lib, "XInput.lib") - -#include "Platform/WineUtilities.h" -#include - -namespace HarmonyLinkLib -{ - std::shared_ptr WindowsUtilities::get_battery_status() - { - if (is_linux()) - { - return WineUtilities::get_battery_status(); - } - FBattery result; - - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) { - result.has_battery = status.BatteryFlag != 128; // 128 indicates no battery - result.is_connected_to_ac = status.ACLineStatus == 1; - result.battery_percent = result.has_battery ? status.BatteryLifePercent : 0; - } else { - std::wcout << "Failed to get power statistics.\n"; - } - - return std::make_shared(result); - } - - std::shared_ptr WindowsUtilities::get_cpu_info() - { - if (is_linux()) - { - return WineUtilities::get_cpu_info(); - } - - return {}; - } - - std::shared_ptr WindowsUtilities::get_os_version() - { - if (is_linux()) - { - return WineUtilities::get_linux_info(); - } - - OSVERSIONINFOEX os_version_info; - ZeroMemory(&os_version_info, sizeof(OSVERSIONINFOEX)); - os_version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - if (!GetVersionEx(reinterpret_cast(&os_version_info))) { - // Handle error if needed - return nullptr; - } - - FOSVerInfo os_version; - - HKEY h_key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_READ, &h_key) == ERROR_SUCCESS) - { - DWORD dw_size; - DWORD dw_type; - char sz_product_name[256]; - dw_size = sizeof(sz_product_name); - if (RegQueryValueEx(h_key, TEXT("ProductName"), nullptr, &dw_type, reinterpret_cast(sz_product_name), &dw_size) == ERROR_SUCCESS) - { - os_version.pretty_name = sz_product_name; - } - RegCloseKey(h_key); - } - - std::stringstream version; - version << os_version_info.dwMajorVersion << "." << os_version_info.dwMinorVersion; - os_version.version_id = version.str(); - - os_version.name = "Windows"; - os_version.version = os_version_info.dwBuildNumber; // Build number as the version - - return std::make_shared(os_version); - } - - bool WindowsUtilities::get_is_external_monitor_connected() - { - // SM_CMONITORS returns the count of all display monitors. - const int monitorCount = GetSystemMetrics(SM_CMONITORS); - - // More than one monitor implies an external monitor is connected. - return monitorCount > 1; - } - - bool WindowsUtilities::get_keyboard_detected() - { - UINT n_devices; - std::vector devices; - - GetRawInputDeviceList(devices.data(), &n_devices, sizeof(RAWINPUTDEVICELIST)); - - if (n_devices == 0) - { - return false; - } - - return std::any_of(devices.begin(), devices.end(), [](const RAWINPUTDEVICELIST& device) - { - return device.dwType == RIM_TYPEKEYBOARD; - }); - } - - bool WindowsUtilities::get_mouse_detected() - { - UINT n_devices; - std::vector devices; - - GetRawInputDeviceList(devices.data(), &n_devices, sizeof(RAWINPUTDEVICELIST)); - - if (n_devices == 0) - { - return false; - } - - return std::any_of(devices.begin(), devices.end(), [](const RAWINPUTDEVICELIST& device) - { - return device.dwType == RIM_TYPEMOUSE; - }); - } - - bool WindowsUtilities::get_external_controller_detected() - { - static_assert(XUSER_MAX_COUNT <= UINT8_MAX, "XUSER_MAX_COUNT exceeds uint8_t size"); - - uint8_t connectedGamepads = 0; - - for (DWORD i = 0; i < XUSER_MAX_COUNT; ++i) { - XINPUT_STATE state; - ZeroMemory(&state, sizeof(XINPUT_STATE)); - - if (XInputGetState(i, &state) == ERROR_SUCCESS) { - connectedGamepads++; - } - } - - return connectedGamepads > 1; - } - - bool WindowsUtilities::get_is_steam_deck_native_resolution() - { - DEVMODE devMode; - devMode.dmSize = sizeof(DEVMODE); - - // Get the current display settings for the primary monitor - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode)) { - // Check if the resolution is higher than 800p (1280x800) - if (devMode.dmPelsWidth > 1280 || devMode.dmPelsHeight > 800) { - return true; - } - } - return false; - } -} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h deleted file mode 100644 index 809b204..0000000 --- a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Platform/IPlatformUtilities.h" - -namespace HarmonyLinkLib -{ - class WindowsUtilities : public IPlatformUtilities - { - public: - std::shared_ptr get_battery_status() override; - - std::shared_ptr get_cpu_info() override; - - std::shared_ptr get_os_version() override; - - bool get_is_external_monitor_connected() override; - - bool get_keyboard_detected() override; - - bool get_mouse_detected() override; - - bool get_external_controller_detected() override; - - bool get_is_steam_deck_native_resolution() override; - }; -} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.cpp b/HarmonyLinkLib/src/Platform/WineUtilities.cpp deleted file mode 100644 index efe48a3..0000000 --- a/HarmonyLinkLib/src/Platform/WineUtilities.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "WineUtilities.h" - -#include -#include -#include -#include -#include - -#ifdef BUILD_WINDOWS -#include -#endif - -namespace HarmonyLinkLib -{ - bool force_detect_wine = false; - - std::shared_ptr HarmonyLinkLib::WineUtilities::get_battery_status() - { - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FBattery result = {}; - for (int i = 0; i <= 9; ++i) { - if (std::string bat_path = append + "/sys/class/power_supply/BAT" + std::to_string(i); std::filesystem::exists(bat_path)) { - result.has_battery = true; - - std::ifstream status_file(bat_path + "/status"); - std::string status; - if (status_file.is_open() && std::getline(status_file, status)) { - if (status == "Charging" || status == "AC") { - result.is_connected_to_ac = true; - } - } - - std::ifstream capacity_file(bat_path + "/capacity"); - if (capacity_file.is_open() && std::getline(capacity_file, status)) { - result.battery_percent = static_cast(std::stoi(status)); - break; // assuming you only need data from the first battery found - } - } - } - - return std::make_shared(result); - } - - std::shared_ptr WineUtilities::get_cpu_info() - { - std::wcout << "Getting cpu info\n"; - - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FCPUInfo cpu_info; - - std::ifstream file(append + "/proc/cpuinfo"); - std::unordered_map hashmap; - - if (file) { - std::string line; - while (std::getline(file, line)) { - std::istringstream line_stream(line); - std::string key, value; - if (std::getline(line_stream, key, ':')) { - key.erase(key.find_last_not_of(" \t") + 1); // Trim trailing whitespace from key - if (std::getline(line_stream, value)) { - value.erase(0, value.find_first_not_of(" \t")); // Trim leading whitespace from value - - // Aggregate flags - if (key == "flags") { - std::istringstream flag_stream(value); - std::string flag; - while (flag_stream >> flag) { - flag.erase(flag.find_last_not_of(" \t") + 1); // Trim trailing whitespace from flag - cpu_info.Flags.insert(HarmonyLinkLib::FString(flag)); - //printf("Flag detected: %s\n", flag.c_str()); - } - } else { - hashmap[key] = value; - } - } - } - } - file.close(); - } - - // Now you can access the values using the keys: - cpu_info.VendorID = hashmap["vendor_id"]; - cpu_info.Model_Name = hashmap["model name"]; - - try { - cpu_info.Physical_Cores = std::stoi(hashmap["cpu cores"].c_str()); - } catch (const std::invalid_argument& ia) { - std::wcerr << "Invalid argument: " << ia.what() << '\n'; - } catch (const std::out_of_range& oor) { - std::wcerr << "Out of Range error: " << oor.what() << '\n'; - } - - cpu_info.Logical_Cores = (cpu_info.Flags.find("ht") != cpu_info.Flags.end()) ? cpu_info.Physical_Cores * 2 : cpu_info.Physical_Cores; - - return std::make_shared(cpu_info); - } - - std::shared_ptr WineUtilities::get_linux_info() - { - std::string append; - if (is_wine_present()) - { - append = "Z:"; - } - - FOSVerInfo os_info; - - std::ifstream file(append + "/etc/os-release"); - std::unordered_map hashmap; - - if (file) { - std::string line; - while (std::getline(file, line)) { - std::istringstream lineStream(line); - std::string key, value; - if (std::getline(lineStream, key, '=')) { - if (std::getline(lineStream, value)) { - // Remove leading and trailing whitespace - size_t firstNonSpace = value.find_first_not_of(" \t"); - size_t lastNonSpace = value.find_last_not_of(" \t"); - if (firstNonSpace != std::string::npos && lastNonSpace != std::string::npos) { - value = value.substr(firstNonSpace, lastNonSpace - firstNonSpace + 1); - } else { - value.clear(); // If value is all whitespace, make it empty - } - - // Check for double quotes and remove them - if (!value.empty() && value.front() == '"' && value.back() == '"') { - value = value.substr(1, value.length() - 2); - } - - hashmap[key] = value; - } - } - } - file.close(); - } - - // Now you can access the values using the keys: - os_info.name = hashmap["NAME"]; - os_info.id = hashmap["ID"]; - os_info.version_id = hashmap["VERSION_ID"]; - os_info.version_codename = hashmap["VERSION_CODENAME"]; - os_info.pretty_name = hashmap["PRETTY_NAME"]; - - try { - os_info.version = std::stoi(hashmap["VERSION"].c_str()); - } catch (const std::invalid_argument& ia) { - std::cerr << "Invalid argument: " << ia.what() << '\n'; - // Handle the error, perhaps by setting a default value or leaving the field unchanged - } catch (const std::out_of_range& oor) { - std::cerr << "Out of Range error: " << oor.what() << '\n'; - // Handle the error, perhaps by setting a default value or leaving the field unchanged - } - - return std::make_shared(os_info); - } - - bool WineUtilities::is_wine_present() - { - static bool isWineCached = false; // Static variable to store the cached result - static bool isWine = false; // Static variable to indicate if the caching has been done - - if (!isWineCached) - { - // Only detect wine if force_detect_wine is true or if we haven't cached the result yet -#ifdef BUILD_WINDOWS - std::wcout << "Detecting wine...\n"; - bool HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "wine_get_version") != nullptr; - - if (!HasFound) - HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "proton_get_version") != nullptr; - - wprintf(L"wine %s found\n", HasFound ? L"has been" : L"not"); - - isWine = HasFound; // Cache the result -#else - isWine = false; // In non-Windows builds, always set isWine to false -#endif - isWineCached = true; // Indicate that the result is now cached - } - - return isWine; // Return the cached result - } - - bool WineUtilities::force_detect_wine_presence() - { - force_detect_wine = true; - return is_wine_present(); - } -} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.h b/HarmonyLinkLib/src/Platform/WineUtilities.h deleted file mode 100644 index 5e5bdae..0000000 --- a/HarmonyLinkLib/src/Platform/WineUtilities.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "Structs/FBattery.h" -#include "Structs/FCPUInfo.h" -#include "Structs/FOSVerInfo.h" - -namespace HarmonyLinkLib -{ - class WineUtilities - { - public: - static std::shared_ptr get_battery_status(); - - static std::shared_ptr get_cpu_info(); - - /** - * @brief Retrieves Linux OS version information from a specified file. - * - * This function parses a file (typically a Linux OS release file) at the given location - * to extract operating system version information. It reads key-value pairs from the file, - * processes them to handle whitespace and quotes, and then stores them in an FOSVerInfo - * structure. If the file location is invalid or the file cannot be opened, it returns an - * empty FOSVerInfo structure. Errors during parsing, such as invalid format or out of range - * values, are handled with exception catching. In Windows builds where Wine is detected, - * this function can use the file location 'Z:/etc/os-release' to retrieve the underlying - * Linux system information. - * - * @param file_location The location of the file containing OS version information. - * @return A shared pointer to a structure containing the parsed OS version information. - */ - static std::shared_ptr get_linux_info(); - - /** - * @brief Detects the presence of Wine or Proton in Windows builds. - * - * This function assesses if the application is running under Wine or Proton by - * querying specific functions in the 'ntdll.dll' module. It is only active in - * Windows builds, returning false for non-Windows builds. - * - * @return bool True if Wine or Proton is detected, false otherwise. - */ - static bool is_wine_present(); - - static bool force_detect_wine_presence(); - }; -} diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h b/HarmonyLinkLib/src/Structs/Battery.c similarity index 63% rename from HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h rename to HarmonyLinkLib/src/Structs/Battery.c index 237a0c5..020a0d7 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h +++ b/HarmonyLinkLib/src/Structs/Battery.c @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include "Structs/Battery.h" -#include "Platform/Unix/UnixUtilities.h" +#include -namespace HarmonyLinkLib +void FBattery_print(const FBattery* self) { - class MacUtitities : public UnixUtilities { - public: - // Mac-specific overrides and additional functionality - }; + wprintf(L"Battery present: %ls\n", self->has_battery ? L"'Yes'" : L"'No'"); + wprintf(L"Connected to AC: %ls\n", self->is_connected_to_ac ? L"'Yes'" : L"'No'"); + wprintf(L"Battery percent: %ls\n", self->battery_percent ? L"'Yes'" : L"'No'"); } diff --git a/HarmonyLinkLib/src/Utilities.cpp b/HarmonyLinkLib/src/Utilities.cpp deleted file mode 100644 index 608437c..0000000 --- a/HarmonyLinkLib/src/Utilities.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "Utilities.h" - -#include - -#include "FString.h" - -void HarmonyLinkLib::Utilities::DebugPrint(const FString& String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << String.c_str(); - - if (AddNewline) - { - std::wcout << L"\n"; - } -#endif -} - -void HarmonyLinkLib::Utilities::DebugPrint(const char* String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << std::wstring(String, String + std::strlen(String)); - - if (AddNewline) { - std::wcout << L"\n"; - } -#endif -} - -void HarmonyLinkLib::Utilities::DebugPrint(const wchar_t* String, bool AddNewline) -{ -#ifdef DEBUG_MODE - std::wcout << String; - - if (AddNewline) { - std::wcout << L"\n"; - } -#endif -} diff --git a/HarmonyLinkLib/src/Utilities.h b/HarmonyLinkLib/src/Version.c similarity index 59% rename from HarmonyLinkLib/src/Utilities.h rename to HarmonyLinkLib/src/Version.c index d6114c8..b844b0c 100644 --- a/HarmonyLinkLib/src/Utilities.h +++ b/HarmonyLinkLib/src/Version.c @@ -12,19 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include "Version.h" -#include "HarmonyLinkLib.h" +#include -namespace HarmonyLinkLib +char* get_version_string(void) { - class FString; - - class Utilities - { - public: - static void DebugPrint(const FString& String, bool AddNewline = true); - static void DebugPrint(const char* String, bool AddNewline = true); - static void DebugPrint(const wchar_t* String, bool AddNewline = true); - }; + return HARMONYLINK_VERSION; +} + +char* get_version_build_timestamp(void) +{ + return __TIMESTAMP__; +} + +char* get_git_branch(void) +{ + return GIT_BRANCH_NAME; +} + +char* get_git_commit_timestamp(void) +{ + return GIT_COMMIT_TIMESTAMP; +} + +bool get_is_debug(void) +{ +#ifdef DEBUG_MODE + return true; +#else + return false; +#endif } diff --git a/HarmonyLinkLib/src/dllmain.c b/HarmonyLinkLib/src/dllmain.c new file mode 100644 index 0000000..e69de29 diff --git a/HarmonyLinkLib/src/dllmain.cpp b/HarmonyLinkLib/src/dllmain.cpp deleted file mode 100644 index 5e6df48..0000000 --- a/HarmonyLinkLib/src/dllmain.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include "Version.h" - -namespace HarmonyLinkLib -{ - void HarmonyLinkInit() - { - std::wcout << "HarmonyLink V" << version::ToString().c_str() << " Copyright (C) 2023 Jordon Brooks\n"; - } -} - - -#if BUILD_WINDOWS -#include - -// Standard DLL entry point -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - // Code to run when the DLL is loaded - HarmonyLinkLib::HarmonyLinkInit(); - break; - case DLL_THREAD_ATTACH: - // Code to run when a thread is created during the DLL's lifetime - case DLL_THREAD_DETACH: - // Code to run when a thread ends normally. - case DLL_PROCESS_DETACH: - // Code to run when the DLL is unloaded - default: - break; - } - return TRUE; // Successful DLL_PROCESS_ATTACH. -} -#endif - -#if BUILD_UNIX -__attribute__((constructor)) -static void onLibraryLoad() { - // Code to run when the library is loaded - HarmonyLinkLib::HarmonyLinkInit(); -} - -__attribute__((destructor)) -static void onLibraryUnload() { - // Code to run when the library is unloaded -} -#endif diff --git a/HarmonyLinkTest/CMakeLists.txt b/HarmonyLinkTest/CMakeLists.txt index 949ea4f..31dd770 100644 --- a/HarmonyLinkTest/CMakeLists.txt +++ b/HarmonyLinkTest/CMakeLists.txt @@ -15,11 +15,11 @@ cmake_minimum_required(VERSION 3.10) project(HarmonyLinkTest) # Specify the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) # Automatically add all .cpp and .h/.hpp files in the src directory -file(GLOB_RECURSE TEST_SOURCES "src/*.cpp") +file(GLOB_RECURSE TEST_SOURCES "src/*.c") file(GLOB_RECURSE TEST_HEADERS "src/*.h" "src/*.hpp") # Add executable for static library diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp b/HarmonyLinkTest/src/main.c similarity index 67% rename from HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp rename to HarmonyLinkTest/src/main.c index 001364c..245d90e 100644 --- a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp +++ b/HarmonyLinkTest/src/main.c @@ -12,9 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "MacUtilities.h" +#include +#include "HarmonyLinkLib.h" -namespace HarmonyLinkLib +int main(void) { + wprintf(L"Hello from C!\n"); -} \ No newline at end of file + if (!HarmonyLink_Init()) + { + wprintf(L"Error: Failed to initialise HarmonyLink!\n"); + return 1; + } + + wprintf(L"Successfully Initialised HarmonyLink!\n"); + + return 0; +} diff --git a/HarmonyLinkTest/src/main.cpp b/HarmonyLinkTest/src/main.cpp deleted file mode 100644 index e9eaf87..0000000 --- a/HarmonyLinkTest/src/main.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2024 Jordon Brooks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include -#include - -#include "HarmonyLinkLib.h" - -// Include necessary headers for platform-specific functionality -#ifdef BUILD_WINDOWS -#include // For _kbhit() and _getch() -#include // For system("cls") -#else -#include // For read() -#include // For termios -#include // For getchar() -#include // For F_GETFL, F_SETFL and O_NONBLOCK -#endif - -std::atomic quitFlag(false); - -// Function to clear the screen cross-platform -void clearScreen() { -#ifdef _WIN32 - system("cls"); -#else - std::cout << "\x1B[2J\x1B[H"; -#endif -} - - -// Function to check if 'q' or 'Q' is pressed in Windows -void checkForQuit() { - while (!quitFlag) { -#ifdef BUILD_WINDOWS - if (_kbhit()) { - const char c = static_cast(_getch()); - if (c == 'q' || c == 'Q') { - quitFlag = true; - break; - } - } -#else - struct termios oldt, newt; - int ch; - int oldf; - - tcgetattr(STDIN_FILENO, &oldt); - newt = oldt; - newt.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - oldf = fcntl(STDIN_FILENO, F_GETFL, 0); - fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); - - ch = getchar(); - - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); - fcntl(STDIN_FILENO, F_SETFL, oldf); - - if (ch != EOF) { - ungetc(ch, stdin); - if (ch == 'q' || ch == 'Q') { - quitFlag = true; - break; - } - } -#endif - // Checks for input every roughly 60 frames - std::this_thread::sleep_for(std::chrono::milliseconds(16)); - } -} - -int main() -{ - std::cout << "Hello, World!" << '\n'; - - std::thread inputThread(checkForQuit); - - const bool isWine = HarmonyLinkLib::get_is_wine(); - const char* test = isWine ? "is" : "isn't"; - - const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); - - const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); - - const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); - - // This loop is to test how stable & expensive these functions are - while (!quitFlag) - { - // Clear the screen - clearScreen(); - - std::wcout << "This program " << test << " running under wine.\n"; - - if (cpu_info) - { - cpu_info->print(); - } - - if (os_info) - { - os_info->print(); - } - - if (device_info) - { - wprintf(L"Is SteamDeck: %s\n", device_info->device == HarmonyLinkLib::EDevice::STEAM_DECK ? L"true" : L"false"); - } - - // we can't do this before the loop because we need updated values - if (const HarmonyLinkLib::FBattery* battery = HarmonyLinkLib::get_battery_status()) - { - battery->to_string(); - battery->free(); - } - - const bool is_docked = HarmonyLinkLib::get_is_docked(); - - const char* dock_check_string = is_docked ? "is" : "isn't"; - - wprintf(L"Device %hs docked\n", dock_check_string); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - if (inputThread.joinable()) - { - inputThread.join(); - } - - if (os_info) - { - os_info->free(); - } - - if (device_info) - { - device_info->free(); - } - - if (cpu_info) - { - cpu_info->free(); - } - - return 0; -} From 7f92fa6512505650dbb701662bae1c6822b7de98 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Wed, 22 May 2024 18:55:45 +0100 Subject: [PATCH 02/18] Add CPUInfo struct --- HarmonyLinkLib/CMakeLists.txt | 2 ++ HarmonyLinkLib/include/Structs/CPUInfo.h | 32 ++++++++++++++++++++++++ HarmonyLinkLib/src/Structs/CPUInfo.c | 16 ++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 HarmonyLinkLib/include/Structs/CPUInfo.h create mode 100644 HarmonyLinkLib/src/Structs/CPUInfo.c diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 95ca22a..176f6ea 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -57,6 +57,7 @@ set(COMMON_SOURCES "src/Version.c" "src/Structs/Battery.c" + "src/Structs/CPUInfo.c" ) # Explicitly list include files @@ -70,6 +71,7 @@ set(COMMON_INCLUDES "include/Enums/SteamDeck.h" "include/Structs/Battery.h" + "include/Structs/CPUInfo.h" ) set(WINDOWS_SOURCES diff --git a/HarmonyLinkLib/include/Structs/CPUInfo.h b/HarmonyLinkLib/include/Structs/CPUInfo.h new file mode 100644 index 0000000..ae0532a --- /dev/null +++ b/HarmonyLinkLib/include/Structs/CPUInfo.h @@ -0,0 +1,32 @@ +// 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" + +typedef struct +{ + char* VendorID; + bool Model_Name; + unsigned int Physical_Cores; + unsigned int Logical_Cores; + char[] Flags; + +} FCPUInfo; + +//HARMONYLINKLIB_API void FBattery_print(const FCPUInfo* self); + diff --git a/HarmonyLinkLib/src/Structs/CPUInfo.c b/HarmonyLinkLib/src/Structs/CPUInfo.c new file mode 100644 index 0000000..703f260 --- /dev/null +++ b/HarmonyLinkLib/src/Structs/CPUInfo.c @@ -0,0 +1,16 @@ +// 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" + From 18129ac7c25c8592a5b3a11bcac116b928efdeab Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Wed, 22 May 2024 18:56:31 +0100 Subject: [PATCH 03/18] Ignore Idea folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0839667..2e489f4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ build/** # Blacklist specific build directories linuxbuild/ build/ +.idea/ From 7dbe088577b6b78414a61d9d5878e910f2f142ce Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Wed, 22 May 2024 18:59:53 +0100 Subject: [PATCH 04/18] Forgot to add semi-colon to unsupported platform message --- HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp index 735eeab..555cc10 100644 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp +++ b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp @@ -49,7 +49,7 @@ namespace HarmonyLinkLib INSTANCE = std::make_shared(); // ... other platform checks #else - std::wcout << "Platform is not supported.\n" + std::wcout << "Platform is not supported.\n"; #endif } From 53f661ece8b43d22a08a3ed97ce37d35fb0e65f2 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Fri, 24 May 2024 21:05:34 +0100 Subject: [PATCH 05/18] Fix fmt not being included in library --- HarmonyLinkLib/CMakeLists.txt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 03440bf..eb67f49 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -92,11 +92,6 @@ set(COMMON_INCLUDES "src/Utilities.h" ) -# Adding fmt headers explicitly -set(FMT_HEADERS - "${fmt_SOURCE_DIR}/include/fmt" -) - set(WINDOWS_SOURCES "src/Platform/Windows/WindowsUtilities.cpp" ) @@ -166,9 +161,6 @@ target_include_directories(HarmonyLinkLibStatic ) target_compile_definitions(HarmonyLinkLibStatic PRIVATE HARMONYLINKLIB_STATIC) -# Include fmt headers -target_include_directories(HarmonyLinkLibStatic PRIVATE ${FMT_HEADERS}) - # Set output directories for all build types foreach(TYPE IN ITEMS DEBUG RELEASE) string(TOUPPER ${TYPE} TYPE_UPPER) @@ -182,8 +174,9 @@ foreach(TYPE IN ITEMS DEBUG RELEASE) ) endforeach() -target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt) -target_link_libraries(HarmonyLinkLibShared PRIVATE fmt) +# Link fmt to HarmonyLinkLib +target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt::fmt-header-only) +target_link_libraries(HarmonyLinkLibShared PRIVATE fmt::fmt-header-only) if (UNIX) target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) From 810cea013ea74369664f9709e0024d55e8e756f9 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Fri, 24 May 2024 21:08:11 +0100 Subject: [PATCH 06/18] Version Bump --- HarmonyLinkLib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index eb67f49..7146d8e 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -12,7 +12,7 @@ # limitations under the License. cmake_minimum_required(VERSION 3.10) -project(HarmonyLinkLib VERSION 2.1.1) +project(HarmonyLinkLib VERSION 2.1.2) include(FetchContent) From 41621b2af3483e7aad9ce31ceec5de7a3f083cc4 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Mon, 27 May 2024 01:07:19 +0100 Subject: [PATCH 07/18] Add more C stuff --- HarmonyLinkLib/include/Structs/CPUInfo.h | 42 +++++++++-- HarmonyLinkLib/src/Structs/CPUInfo.c | 88 ++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 6 deletions(-) diff --git a/HarmonyLinkLib/include/Structs/CPUInfo.h b/HarmonyLinkLib/include/Structs/CPUInfo.h index ae0532a..3620f77 100644 --- a/HarmonyLinkLib/include/Structs/CPUInfo.h +++ b/HarmonyLinkLib/include/Structs/CPUInfo.h @@ -12,21 +12,51 @@ // 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" -typedef struct -{ +typedef struct { + char** data; // Array of strings (flags) + size_t FlagsCount; // Number of flags +} FlagsInfo; + +typedef struct { char* VendorID; - bool Model_Name; + char* Model_Name; unsigned int Physical_Cores; unsigned int Logical_Cores; - char[] Flags; - + FlagsInfo flagsInfo; } FCPUInfo; -//HARMONYLINKLIB_API void FBattery_print(const FCPUInfo* self); +// Initialize FlagsInfo +void FlagsInfo_Init(FlagsInfo* flagsInfo, size_t count); +// Initialize FCPUInfo +void FCPUInfo_Init(FCPUInfo* cpuInfo, const char* vendorID, const char* modelName, unsigned int physicalCores, unsigned int logicalCores, size_t flagsCount); + +// Print FlagsInfo +HARMONYLINKLIB_API void HL_FlagsInfo_Print(const FlagsInfo* flagsInfo); + +// Print FCPUInfo +HARMONYLINKLIB_API void HL_FCPUInfo_Print(const FCPUInfo* cpuInfo); + +// Free FlagsInfo +HARMONYLINKLIB_API void HL_FlagsInfo_Free(FlagsInfo* flagsInfo); + +// Free FCPUInfo +HARMONYLINKLIB_API void FCPUInfo_Free(FCPUInfo* cpuInfo); + +// Check if a flag exists in FlagsInfo +HARMONYLINKLIB_API bool HL_FlagsInfo_Contains(const FlagsInfo* flagsInfo, const char* flag); + +// Add a flag to FlagsInfo +void FlagsInfo_AddFlag(FlagsInfo* flagsInfo, size_t index, const char* flag); + +// Remove a flag from FlagsInfo by value +void FlagsInfo_Remove(FlagsInfo* flagsInfo, const char* flag); diff --git a/HarmonyLinkLib/src/Structs/CPUInfo.c b/HarmonyLinkLib/src/Structs/CPUInfo.c index 703f260..182abe0 100644 --- a/HarmonyLinkLib/src/Structs/CPUInfo.c +++ b/HarmonyLinkLib/src/Structs/CPUInfo.c @@ -14,3 +14,91 @@ #include "Structs/CPUInfo.h" +#include +#include + +void FlagsInfo_Init(FlagsInfo *flagsInfo, size_t count) { + flagsInfo->FlagsCount = count; + flagsInfo->data = (char**)malloc(count * sizeof(char*)); + for (size_t i = 0; i < count; ++i) { + flagsInfo->data[i] = NULL; + } +} + +void FCPUInfo_Init(FCPUInfo *cpuInfo, const char *vendorID, const char *modelName, unsigned int physicalCores, + unsigned int logicalCores, size_t flagsCount) { + cpuInfo->VendorID = strdup(vendorID); + cpuInfo->Model_Name = strdup(modelName); + cpuInfo->Physical_Cores = physicalCores; + cpuInfo->Logical_Cores = logicalCores; + FlagsInfo_Init(&cpuInfo->flagsInfo, flagsCount); +} + +void FlagsInfo_AddFlag(FlagsInfo *flagsInfo, size_t index, const char *flag) { + if (index < flagsInfo->FlagsCount) { + flagsInfo->data[index] = strdup(flag); + } +} + +void HL_FlagsInfo_Print(const FlagsInfo *flagsInfo) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + if (flagsInfo->data[i] != NULL) { + wprintf(L" %s\n", flagsInfo->data[i]); + } + } +} + +void HL_FCPUInfo_Print(const FCPUInfo *cpuInfo) { + wprintf(L"VendorID: %s\n", cpuInfo->VendorID); + wprintf(L"Model Name: %s\n", cpuInfo->Model_Name); + wprintf(L"Physical Cores: %u\n", cpuInfo->Physical_Cores); + wprintf(L"Logical Cores: %u\n", cpuInfo->Logical_Cores); + wprintf(L"Flags:\n"); + HL_FlagsInfo_Print(&cpuInfo->flagsInfo); +} + +void HL_FlagsInfo_Free(FlagsInfo *flagsInfo) { + for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { + free(flagsInfo->data[i]); + } + free(flagsInfo->data); +} + +void FlagsInfo_Remove(FlagsInfo *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--; + + // Use a temporary pointer to ensure realloc success + char** temp = realloc(flagsInfo->data, flagsInfo->FlagsCount * sizeof(char*)); + if (temp != NULL) { + flagsInfo->data = temp; + } else if (flagsInfo->FlagsCount > 0) { + // realloc failed and we're not deallocating to zero, handle error + fprintf(stderr, "Realloc failed. Memory not reallocated.\n"); + exit(EXIT_FAILURE); + } + break; + } + } +} + +bool HL_FlagsInfo_Contains(const FlagsInfo *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; +} + +void HL_FCPUInfo_Free(FCPUInfo *cpuInfo) { + free(cpuInfo->VendorID); + free(cpuInfo->Model_Name); + HL_FlagsInfo_Free(&cpuInfo->flagsInfo); +} From b35dec2fdc0831054e19fd70353bbaaf0190d1ba Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Mon, 27 May 2024 02:13:58 +0100 Subject: [PATCH 08/18] added more stuff --- HarmonyLinkLib/CMakeLists.txt | 30 ++--- HarmonyLinkLib/include/Structs/Battery.h | 2 + HarmonyLinkLib/include/Structs/CPUInfo.h | 28 +---- HarmonyLinkLib/include/Structs/StringArray.h | 51 ++++++++ HarmonyLinkLib/include/Utilities.h | 18 +++ HarmonyLinkLib/src/Structs/CPUInfo.c | 98 ++++++---------- HarmonyLinkLib/src/Structs/StringArray.c | 117 +++++++++++++++++++ HarmonyLinkLib/src/Utilities.c | 27 +++++ 8 files changed, 274 insertions(+), 97 deletions(-) create mode 100644 HarmonyLinkLib/include/Structs/StringArray.h create mode 100644 HarmonyLinkLib/include/Utilities.h create mode 100644 HarmonyLinkLib/src/Structs/StringArray.c create mode 100644 HarmonyLinkLib/src/Utilities.c diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 176f6ea..b794608 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -52,26 +52,30 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Resources/Version.rc.in ${CMAKE_CURRE # Explicitly list source files set(COMMON_SOURCES - "src/dllmain.c" - "src/HarmonyLinkLib.c" - "src/Version.c" + src/dllmain.c + src/HarmonyLinkLib.c + src/Version.c + src/Utilities.c - "src/Structs/Battery.c" - "src/Structs/CPUInfo.c" + src/Structs/Battery.c + src/Structs/CPUInfo.c + src/Structs/StringArray.c ) # Explicitly list include files set(COMMON_INCLUDES - "include/Core.h" - "include/HarmonyLinkLib.h" - "include/Version.h" + include/Core.h + include/HarmonyLinkLib.h + include/Version.h + include/Utilities.h - "include/Enums/Device.h" - "include/Enums/Platform.h" - "include/Enums/SteamDeck.h" + include/Enums/Device.h + include/Enums/Platform.h + include/Enums/SteamDeck.h - "include/Structs/Battery.h" - "include/Structs/CPUInfo.h" + include/Structs/Battery.h + include/Structs/CPUInfo.h + include/Structs/StringArray.h ) set(WINDOWS_SOURCES diff --git a/HarmonyLinkLib/include/Structs/Battery.h b/HarmonyLinkLib/include/Structs/Battery.h index 0ee37b3..af566e7 100644 --- a/HarmonyLinkLib/include/Structs/Battery.h +++ b/HarmonyLinkLib/include/Structs/Battery.h @@ -25,5 +25,7 @@ typedef struct unsigned char battery_percent; } FBattery; +HARMONYLINKLIB_API FBattery* FBattery_Init(const FBattery* self); + HARMONYLINKLIB_API void FBattery_print(const FBattery* self); diff --git a/HarmonyLinkLib/include/Structs/CPUInfo.h b/HarmonyLinkLib/include/Structs/CPUInfo.h index 3620f77..f9daddb 100644 --- a/HarmonyLinkLib/include/Structs/CPUInfo.h +++ b/HarmonyLinkLib/include/Structs/CPUInfo.h @@ -20,43 +20,27 @@ #include #include "Core.h" - -typedef struct { - char** data; // Array of strings (flags) - size_t FlagsCount; // Number of flags -} FlagsInfo; +#include "Structs/StringArray.h" typedef struct { char* VendorID; char* Model_Name; unsigned int Physical_Cores; unsigned int Logical_Cores; - FlagsInfo flagsInfo; + StringArray flagsInfo; } FCPUInfo; -// Initialize FlagsInfo -void FlagsInfo_Init(FlagsInfo* flagsInfo, size_t count); - // Initialize FCPUInfo -void FCPUInfo_Init(FCPUInfo* cpuInfo, const char* vendorID, const char* modelName, unsigned int physicalCores, unsigned int logicalCores, size_t flagsCount); +FCPUInfo* FCPUInfo_Init(const char* vendorID, const char* modelName, unsigned int physicalCores, unsigned int logicalCores, size_t flagsCount); // Print FlagsInfo -HARMONYLINKLIB_API void HL_FlagsInfo_Print(const FlagsInfo* flagsInfo); +HARMONYLINKLIB_API void HL_FlagsInfo_Print(const FCPUInfo* cpuInfo); // Print FCPUInfo HARMONYLINKLIB_API void HL_FCPUInfo_Print(const FCPUInfo* cpuInfo); -// Free FlagsInfo -HARMONYLINKLIB_API void HL_FlagsInfo_Free(FlagsInfo* flagsInfo); - // Free FCPUInfo -HARMONYLINKLIB_API void FCPUInfo_Free(FCPUInfo* cpuInfo); +HARMONYLINKLIB_API void HL_FCPUInfo_Free(FCPUInfo* cpuInfo); // Check if a flag exists in FlagsInfo -HARMONYLINKLIB_API bool HL_FlagsInfo_Contains(const FlagsInfo* flagsInfo, const char* flag); - -// Add a flag to FlagsInfo -void FlagsInfo_AddFlag(FlagsInfo* flagsInfo, size_t index, const char* flag); - -// Remove a flag from FlagsInfo by value -void FlagsInfo_Remove(FlagsInfo* flagsInfo, const char* flag); +HARMONYLINKLIB_API bool HL_FlagsInfo_Contains(const FCPUInfo* cpuInfo, const char* flag); diff --git a/HarmonyLinkLib/include/Structs/StringArray.h b/HarmonyLinkLib/include/Structs/StringArray.h new file mode 100644 index 0000000..ff7b433 --- /dev/null +++ b/HarmonyLinkLib/include/Structs/StringArray.h @@ -0,0 +1,51 @@ +// 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 + +typedef struct { + 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 +HARMONYLINKLIB_API void HL_StringArray_Print(const StringArray* flagsInfo); + +// Free FlagsInfo +HARMONYLINKLIB_API void HL_StringArray_Free(StringArray* flagsInfo); + +// Check if a flag exists in FlagsInfo +HARMONYLINKLIB_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); diff --git a/HarmonyLinkLib/include/Utilities.h b/HarmonyLinkLib/include/Utilities.h new file mode 100644 index 0000000..f50ad6a --- /dev/null +++ b/HarmonyLinkLib/include/Utilities.h @@ -0,0 +1,18 @@ +// 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 + +// Utility function to convert char* to wchar_t* +wchar_t* convertToWideChar(const char* str); \ No newline at end of file diff --git a/HarmonyLinkLib/src/Structs/CPUInfo.c b/HarmonyLinkLib/src/Structs/CPUInfo.c index 182abe0..1c169e9 100644 --- a/HarmonyLinkLib/src/Structs/CPUInfo.c +++ b/HarmonyLinkLib/src/Structs/CPUInfo.c @@ -13,92 +13,66 @@ // limitations under the License. #include "Structs/CPUInfo.h" +#include "Utilities.h" #include #include -void FlagsInfo_Init(FlagsInfo *flagsInfo, size_t count) { - flagsInfo->FlagsCount = count; - flagsInfo->data = (char**)malloc(count * sizeof(char*)); - for (size_t i = 0; i < count; ++i) { - flagsInfo->data[i] = NULL; - } -} - -void FCPUInfo_Init(FCPUInfo *cpuInfo, const char *vendorID, const char *modelName, unsigned int physicalCores, +FCPUInfo* FCPUInfo_Init(const char *vendorID, const char *modelName, unsigned int physicalCores, unsigned int logicalCores, size_t flagsCount) { - cpuInfo->VendorID = strdup(vendorID); - cpuInfo->Model_Name = strdup(modelName); + FCPUInfo *cpuInfo = (FCPUInfo*)malloc(sizeof(FCPUInfo)); + + if (cpuInfo == NULL) { + fprintf(stderr, "Memory allocation failed for FCPUInfo.\n"); + exit(EXIT_FAILURE); + } + + cpuInfo->VendorID = _strdup(vendorID); + cpuInfo->Model_Name = _strdup(modelName); cpuInfo->Physical_Cores = physicalCores; cpuInfo->Logical_Cores = logicalCores; - FlagsInfo_Init(&cpuInfo->flagsInfo, flagsCount); + StringArray_Init(&cpuInfo->flagsInfo, flagsCount); + + return cpuInfo; } -void FlagsInfo_AddFlag(FlagsInfo *flagsInfo, size_t index, const char *flag) { - if (index < flagsInfo->FlagsCount) { - flagsInfo->data[index] = strdup(flag); +void HL_FlagsInfo_Print(const FCPUInfo* cpuInfo) { + if (!cpuInfo) + { + fprintf(stderr, "cpuInfo is nullptr!\n"); + return; } -} -void HL_FlagsInfo_Print(const FlagsInfo *flagsInfo) { - for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { - if (flagsInfo->data[i] != NULL) { - wprintf(L" %s\n", flagsInfo->data[i]); - } - } + HL_StringArray_Print(&cpuInfo->flagsInfo); } void HL_FCPUInfo_Print(const FCPUInfo *cpuInfo) { - wprintf(L"VendorID: %s\n", cpuInfo->VendorID); - wprintf(L"Model Name: %s\n", cpuInfo->Model_Name); + 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_FlagsInfo_Print(&cpuInfo->flagsInfo); + HL_StringArray_Print(&cpuInfo->flagsInfo); + + free(wVendorID); + free(wModelName); } -void HL_FlagsInfo_Free(FlagsInfo *flagsInfo) { - for (size_t i = 0; i < flagsInfo->FlagsCount; ++i) { - free(flagsInfo->data[i]); +bool HL_FlagsInfo_Contains(const FCPUInfo* cpuInfo, const char* flag) { + if (!cpuInfo) + { + fprintf(stderr, "cpuInfo is nullptr!\n"); + return false; } - free(flagsInfo->data); -} -void FlagsInfo_Remove(FlagsInfo *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--; - - // Use a temporary pointer to ensure realloc success - char** temp = realloc(flagsInfo->data, flagsInfo->FlagsCount * sizeof(char*)); - if (temp != NULL) { - flagsInfo->data = temp; - } else if (flagsInfo->FlagsCount > 0) { - // realloc failed and we're not deallocating to zero, handle error - fprintf(stderr, "Realloc failed. Memory not reallocated.\n"); - exit(EXIT_FAILURE); - } - break; - } - } -} - -bool HL_FlagsInfo_Contains(const FlagsInfo *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; + return HL_StringArray_Contains(&cpuInfo->flagsInfo, flag); } void HL_FCPUInfo_Free(FCPUInfo *cpuInfo) { free(cpuInfo->VendorID); free(cpuInfo->Model_Name); - HL_FlagsInfo_Free(&cpuInfo->flagsInfo); + HL_StringArray_Free(&cpuInfo->flagsInfo); } diff --git a/HarmonyLinkLib/src/Structs/StringArray.c b/HarmonyLinkLib/src/Structs/StringArray.c new file mode 100644 index 0000000..aa2187f --- /dev/null +++ b/HarmonyLinkLib/src/Structs/StringArray.c @@ -0,0 +1,117 @@ +// 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); + } + flagsInfo->data[flagsInfo->FlagsCount] = _strdup(flag); + 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/HarmonyLinkLib/src/Utilities.c b/HarmonyLinkLib/src/Utilities.c new file mode 100644 index 0000000..25d0bf7 --- /dev/null +++ b/HarmonyLinkLib/src/Utilities.c @@ -0,0 +1,27 @@ +// 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; + mbstowcs_s(&len, NULL, 0, str, 0); // Get the length of the wide string (including null terminator) + wchar_t* wstr = (wchar_t*)malloc(len * sizeof(wchar_t)); + if (wstr == NULL) { + return NULL; // Handle memory allocation failure + } + mbstowcs_s(&len, wstr, len, str, len - 1); + return wstr; +} \ No newline at end of file From 6b90c9f76a3402614c259a699ea18ac51425979e Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Mon, 27 May 2024 13:18:50 +0100 Subject: [PATCH 09/18] More work --- .gitignore | 3 +- CMakeLists.txt | 3 +- HarmonyLinkLib/src/HarmonyLinkLib.c | 28 --- HarmonyLinkLib/src/dllmain.c | 0 HarmonyLinkTest/CMakeLists.txt | 10 +- HarmonyLinkTest_CPP/CMakeLists.txt | 58 ++++++ HarmonyLinkTest_CPP/src/main.cpp | 170 ++++++++++++++++++ .../CMakeLists.txt | 33 ++-- .../Resources/Version.rc.in | 0 .../include/Core.h | 10 +- .../include/Enums/Device.h | 27 ++- LibHarmonyLink/include/Enums/Platform.h | 46 +++++ .../include/Enums/SteamDeck.h | 25 ++- .../include/HarmonyLinkLib.h | 12 +- .../include/Structs/Battery.h | 17 +- .../include/Structs/CPUInfo.h | 25 ++- LibHarmonyLink/include/Structs/Device.h | 47 +++++ LibHarmonyLink/include/Structs/OSInfo.h | 49 +++++ .../include/Structs/StringArray.h | 26 ++- .../include/Utilities.h | 12 +- .../include/Version.h | 26 ++- .../include/Version.h.in | 10 +- .../src/HarmonyLinkLib.c | 18 +- .../src/Structs/Battery.c | 17 ++ .../src/Structs/CPUInfo.c | 7 +- LibHarmonyLink/src/Structs/Device.c | 58 ++++++ LibHarmonyLink/src/Structs/OSInfo.c | 40 +++++ .../src/Structs/StringArray.c | 4 + .../src/Utilities.c | 19 +- .../src/Version.c | 19 +- 30 files changed, 710 insertions(+), 109 deletions(-) delete mode 100644 HarmonyLinkLib/src/HarmonyLinkLib.c delete mode 100644 HarmonyLinkLib/src/dllmain.c create mode 100644 HarmonyLinkTest_CPP/CMakeLists.txt create mode 100644 HarmonyLinkTest_CPP/src/main.cpp rename {HarmonyLinkLib => LibHarmonyLink}/CMakeLists.txt (83%) rename {HarmonyLinkLib => LibHarmonyLink}/Resources/Version.rc.in (100%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Core.h (77%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Enums/Device.h (65%) create mode 100644 LibHarmonyLink/include/Enums/Platform.h rename {HarmonyLinkLib => LibHarmonyLink}/include/Enums/SteamDeck.h (62%) rename {HarmonyLinkLib => LibHarmonyLink}/include/HarmonyLinkLib.h (81%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Structs/Battery.h (71%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Structs/CPUInfo.h (62%) create mode 100644 LibHarmonyLink/include/Structs/Device.h create mode 100644 LibHarmonyLink/include/Structs/OSInfo.h rename {HarmonyLinkLib => LibHarmonyLink}/include/Structs/StringArray.h (62%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Utilities.h (82%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Version.h (62%) rename {HarmonyLinkLib => LibHarmonyLink}/include/Version.h.in (69%) rename HarmonyLinkLib/include/Enums/Platform.h => LibHarmonyLink/src/HarmonyLinkLib.c (75%) rename {HarmonyLinkLib => LibHarmonyLink}/src/Structs/Battery.c (65%) rename {HarmonyLinkLib => LibHarmonyLink}/src/Structs/CPUInfo.c (94%) create mode 100644 LibHarmonyLink/src/Structs/Device.c create mode 100644 LibHarmonyLink/src/Structs/OSInfo.c rename {HarmonyLinkLib => LibHarmonyLink}/src/Structs/StringArray.c (97%) rename {HarmonyLinkLib => LibHarmonyLink}/src/Utilities.c (71%) rename {HarmonyLinkLib => LibHarmonyLink}/src/Version.c (60%) diff --git a/.gitignore b/.gitignore index 2e489f4..81e8788 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,9 @@ build/** !Images/* !.github/** -!HarmonyLinkLib/** +!LibHarmonyLink/** !HarmonyLinkTest/** +!HarmonyLinkTest_CPP/** # Blacklist specific build directories linuxbuild/ 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/src/HarmonyLinkLib.c b/HarmonyLinkLib/src/HarmonyLinkLib.c deleted file mode 100644 index 9d1f950..0000000 --- a/HarmonyLinkLib/src/HarmonyLinkLib.c +++ /dev/null @@ -1,28 +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 "Version.h" - -bool HarmonyLink_Init(void) -{ - wprintf(L"HarmonyLink V%hs Copyright (C) 2023 Jordon Brooks\n", get_version_string()); - wprintf(L"Build Timestamp: %hs\n", get_version_build_timestamp()); - wprintf(L"Git Branch: %hs\n", get_git_branch()); - wprintf(L"Git Commit Timestamp: %hs\n", get_git_commit_timestamp()); - wprintf(L"Build type: %ls\n", get_is_debug() ? L"True" : L"False"); - return 1; -} diff --git a/HarmonyLinkLib/src/dllmain.c b/HarmonyLinkLib/src/dllmain.c deleted file mode 100644 index e69de29..0000000 diff --git a/HarmonyLinkTest/CMakeLists.txt b/HarmonyLinkTest/CMakeLists.txt index 31dd770..a821500 100644 --- a/HarmonyLinkTest/CMakeLists.txt +++ b/HarmonyLinkTest/CMakeLists.txt @@ -24,13 +24,13 @@ file(GLOB_RECURSE TEST_HEADERS "src/*.h" "src/*.hpp") # 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 +54,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/HarmonyLinkTest_CPP/CMakeLists.txt b/HarmonyLinkTest_CPP/CMakeLists.txt new file mode 100644 index 0000000..9c18edd --- /dev/null +++ b/HarmonyLinkTest_CPP/CMakeLists.txt @@ -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. + +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") + +# 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_CPP/src/main.cpp b/HarmonyLinkTest_CPP/src/main.cpp new file mode 100644 index 0000000..7d9a93f --- /dev/null +++ b/HarmonyLinkTest_CPP/src/main.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2024 Jordon Brooks +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#include "HarmonyLinkLib.h" + +// Include necessary headers for platform-specific functionality +#ifdef BUILD_WINDOWS +#include // For _kbhit() and _getch() +#include // For system("cls") +#else +#include // For read() +#include // For termios +#include // For getchar() +#include // For F_GETFL, F_SETFL and O_NONBLOCK +#endif + +std::atomic quitFlag(false); + +// Function to clear the screen cross-platform +void clearScreen() { +#ifdef BUILD_WINDOWS + system("cls"); +#else + std::cout << "\x1B[2J\x1B[H"; +#endif +} + + +// Function to check if 'q' or 'Q' is pressed in Windows +void checkForQuit() { + while (!quitFlag) { +#ifdef BUILD_WINDOWS + if (_kbhit()) { + const char c = static_cast(_getch()); + if (c == 'q' || c == 'Q') { + quitFlag = true; + break; + } + } +#else + struct termios oldt, newt; + int ch; + int oldf; + + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + + ch = getchar(); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + fcntl(STDIN_FILENO, F_SETFL, oldf); + + if (ch != EOF) { + ungetc(ch, stdin); + if (ch == 'q' || ch == 'Q') { + quitFlag = true; + break; + } + } +#endif + // Checks for input every roughly 60 frames + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + } +} + +int main() +{ + std::cout << "Hello, World!" << '\n'; + + std::thread inputThread(checkForQuit); + + if (!LibHarmonyLink::HarmonyLink_Init()) + { + printf("Failed to Initialize HarmonyLink!"); + } + + printf("HarmonyLink Initialized!"); + + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + + //const bool isWine = LibHarmonyLink::get_is_wine(); + //const char* test = isWine ? "is" : "isn't"; + + //const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); + + //const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); + + //const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); + + // This loop is to test how stable & expensive these functions are + while (!quitFlag) + { + // Clear the screen + clearScreen(); + + //std::wcout << "This program " << test << " running under wine.\n"; + + //if (cpu_info) + //{ + // cpu_info->print(); + //} + + //if (os_info) + //{ + // os_info->print(); + //} + + //if (device_info) + //{ + // wprintf(L"Is SteamDeck: %s\n", device_info->device == HarmonyLinkLib::EDevice::STEAM_DECK ? L"true" : L"false"); + //} + + // we can't do this before the loop because we need updated values + //if (const HarmonyLinkLib::FBattery* battery = HarmonyLinkLib::get_battery_status()) + //{ + // battery->print(); + // battery->free(); + //} + + //const bool is_docked = HarmonyLinkLib::get_is_docked(); + + //const char* dock_check_string = is_docked ? "is" : "isn't"; + + //wprintf(L"Device %hs docked\n", dock_check_string); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + if (inputThread.joinable()) + { + inputThread.join(); + } + + //if (os_info) + //{ + // os_info->free(); + //} + + //if (device_info) + //{ + // device_info->free(); + //} + + //if (cpu_info) + //{ + // cpu_info->free(); + //} + + return 0; +} diff --git a/HarmonyLinkLib/CMakeLists.txt b/LibHarmonyLink/CMakeLists.txt similarity index 83% rename from HarmonyLinkLib/CMakeLists.txt rename to LibHarmonyLink/CMakeLists.txt index b794608..b250121 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/LibHarmonyLink/CMakeLists.txt @@ -12,7 +12,7 @@ # limitations under the License. cmake_minimum_required(VERSION 3.10) -project(HarmonyLinkLib VERSION 2.1.1) +project(LibHarmonyLink VERSION 2.1.1) # Specify the C++ standard set(CMAKE_C_STANDARD 11) @@ -42,9 +42,9 @@ configure_file(include/Version.h.in Version.generated.h) # 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 @@ -52,7 +52,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Resources/Version.rc.in ${CMAKE_CURRE # Explicitly list source files set(COMMON_SOURCES - src/dllmain.c src/HarmonyLinkLib.c src/Version.c src/Utilities.c @@ -60,6 +59,8 @@ set(COMMON_SOURCES src/Structs/Battery.c src/Structs/CPUInfo.c src/Structs/StringArray.c + src/Structs/Device.c + src/Structs/OSInfo.C ) # Explicitly list include files @@ -76,6 +77,8 @@ set(COMMON_INCLUDES include/Structs/Battery.h include/Structs/CPUInfo.h include/Structs/StringArray.h + include/Structs/Device.h + include/Structs/OSInfo.h ) set(WINDOWS_SOURCES @@ -117,40 +120,36 @@ elseif(UNIX) 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) # 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) +target_compile_definitions(LibHarmonyLinkStatic PRIVATE HARMONYLINK_STATIC) # 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() - - -if (UNIX) -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 77% rename from HarmonyLinkLib/include/Core.h rename to LibHarmonyLink/include/Core.h index 94a32d2..49ea871 100644 --- a/HarmonyLinkLib/include/Core.h +++ b/LibHarmonyLink/include/Core.h @@ -16,13 +16,13 @@ // 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 diff --git a/HarmonyLinkLib/include/Enums/Device.h b/LibHarmonyLink/include/Enums/Device.h similarity index 65% rename from HarmonyLinkLib/include/Enums/Device.h rename to LibHarmonyLink/include/Enums/Device.h index 8ee0946..66e749c 100644 --- a/HarmonyLinkLib/include/Enums/Device.h +++ b/LibHarmonyLink/include/Enums/Device.h @@ -14,18 +14,39 @@ #pragma once +#include "Core.h" + // Undefine the LINUX macro to avoid conflicts with the enum definition. #undef LINUX -typedef enum -{ +#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/HarmonyLinkLib/include/Enums/SteamDeck.h b/LibHarmonyLink/include/Enums/SteamDeck.h similarity index 62% rename from HarmonyLinkLib/include/Enums/SteamDeck.h rename to LibHarmonyLink/include/Enums/SteamDeck.h index 142504e..b6fe09e 100644 --- a/HarmonyLinkLib/include/Enums/SteamDeck.h +++ b/LibHarmonyLink/include/Enums/SteamDeck.h @@ -14,10 +14,31 @@ #pragma once -typedef enum -{ +#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/HarmonyLinkLib/include/HarmonyLinkLib.h b/LibHarmonyLink/include/HarmonyLinkLib.h similarity index 81% rename from HarmonyLinkLib/include/HarmonyLinkLib.h rename to LibHarmonyLink/include/HarmonyLinkLib.h index 9930ffd..a6a45ed 100644 --- a/HarmonyLinkLib/include/HarmonyLinkLib.h +++ b/LibHarmonyLink/include/HarmonyLinkLib.h @@ -17,4 +17,14 @@ #include #include "Core.h" -HARMONYLINKLIB_API bool HarmonyLink_Init(void); +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +HARMONYLINK_API bool HarmonyLink_Init(void); + +#ifdef __cplusplus +} +} +#endif diff --git a/HarmonyLinkLib/include/Structs/Battery.h b/LibHarmonyLink/include/Structs/Battery.h similarity index 71% rename from HarmonyLinkLib/include/Structs/Battery.h rename to LibHarmonyLink/include/Structs/Battery.h index af566e7..0fe6614 100644 --- a/HarmonyLinkLib/include/Structs/Battery.h +++ b/LibHarmonyLink/include/Structs/Battery.h @@ -18,14 +18,23 @@ #include "Core.h" -typedef struct -{ +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +typedef struct { bool has_battery; bool is_connected_to_ac; unsigned char battery_percent; } FBattery; -HARMONYLINKLIB_API FBattery* FBattery_Init(const FBattery* self); +HARMONYLINK_API FBattery* HL_FBattery_Init(bool has_battery, bool is_connected_to_ac, unsigned char battery_percent); -HARMONYLINKLIB_API void FBattery_print(const FBattery* self); +HARMONYLINK_API void HL_FBattery_print(const FBattery *self); + +#ifdef __cplusplus +} +} +#endif diff --git a/HarmonyLinkLib/include/Structs/CPUInfo.h b/LibHarmonyLink/include/Structs/CPUInfo.h similarity index 62% rename from HarmonyLinkLib/include/Structs/CPUInfo.h rename to LibHarmonyLink/include/Structs/CPUInfo.h index f9daddb..044adb9 100644 --- a/HarmonyLinkLib/include/Structs/CPUInfo.h +++ b/LibHarmonyLink/include/Structs/CPUInfo.h @@ -22,25 +22,36 @@ #include "Core.h" #include "Structs/StringArray.h" +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + typedef struct { - char* VendorID; - char* Model_Name; + 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); +FCPUInfo* FCPUInfo_Init(const char *vendorID, const char *modelName, unsigned int physicalCores, unsigned int logicalCores, + size_t flagsCount); // Print FlagsInfo -HARMONYLINKLIB_API void HL_FlagsInfo_Print(const FCPUInfo* cpuInfo); +HARMONYLINK_API void HL_FlagsInfo_Print(const FCPUInfo *cpuInfo); // Print FCPUInfo -HARMONYLINKLIB_API void HL_FCPUInfo_Print(const FCPUInfo* cpuInfo); +HARMONYLINK_API void HL_FCPUInfo_Print(const FCPUInfo *cpuInfo); // Free FCPUInfo -HARMONYLINKLIB_API void HL_FCPUInfo_Free(FCPUInfo* cpuInfo); +HARMONYLINK_API void HL_FCPUInfo_Free(FCPUInfo *cpuInfo); // Check if a flag exists in FlagsInfo -HARMONYLINKLIB_API bool HL_FlagsInfo_Contains(const FCPUInfo* cpuInfo, const char* flag); +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/HarmonyLinkLib/include/Structs/StringArray.h b/LibHarmonyLink/include/Structs/StringArray.h similarity index 62% rename from HarmonyLinkLib/include/Structs/StringArray.h rename to LibHarmonyLink/include/Structs/StringArray.h index ff7b433..1b87569 100644 --- a/HarmonyLinkLib/include/Structs/StringArray.h +++ b/LibHarmonyLink/include/Structs/StringArray.h @@ -23,29 +23,39 @@ #define DEFAULT_INITIAL_FLAGS_SIZE 4 +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + typedef struct { - char** data; // Array of strings (flags) + 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); +void StringArray_Init(StringArray *flagsInfo, size_t overrideInitialSize); // Print FlagsInfo -HARMONYLINKLIB_API void HL_StringArray_Print(const StringArray* flagsInfo); +HARMONYLINK_API void HL_StringArray_Print(const StringArray *flagsInfo); // Free FlagsInfo -HARMONYLINKLIB_API void HL_StringArray_Free(StringArray* flagsInfo); +HARMONYLINK_API void HL_StringArray_Free(StringArray *flagsInfo); // Check if a flag exists in FlagsInfo -HARMONYLINKLIB_API bool HL_StringArray_Contains(const StringArray* flagsInfo, const char* flag); +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); +void StringArray_AddFlag(StringArray *flagsInfo, const char *flag); // Remove a flag from FlagsInfo by value -void StringArray_Remove(StringArray* flagsInfo, const char* flag); +void StringArray_Remove(StringArray *flagsInfo, const char *flag); // Resize FlagsInfo array -void StringArray_Resize(StringArray* flagsInfo, size_t newSize); +void StringArray_Resize(StringArray *flagsInfo, size_t newSize); + +#ifdef __cplusplus +} +} +#endif diff --git a/HarmonyLinkLib/include/Utilities.h b/LibHarmonyLink/include/Utilities.h similarity index 82% rename from HarmonyLinkLib/include/Utilities.h rename to LibHarmonyLink/include/Utilities.h index f50ad6a..4aa6856 100644 --- a/HarmonyLinkLib/include/Utilities.h +++ b/LibHarmonyLink/include/Utilities.h @@ -14,5 +14,15 @@ #include +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + // Utility function to convert char* to wchar_t* -wchar_t* convertToWideChar(const char* str); \ No newline at end of file +wchar_t *convertToWideChar(const char *str); + +#ifdef __cplusplus +} +} +#endif \ No newline at end of file diff --git a/HarmonyLinkLib/include/Version.h b/LibHarmonyLink/include/Version.h similarity index 62% rename from HarmonyLinkLib/include/Version.h rename to LibHarmonyLink/include/Version.h index 74f6179..d238e47 100644 --- a/HarmonyLinkLib/include/Version.h +++ b/LibHarmonyLink/include/Version.h @@ -17,8 +17,24 @@ #include #include "Core.h" -HARMONYLINKLIB_API char* get_version_string(void); -HARMONYLINKLIB_API char* get_version_build_timestamp(void); -HARMONYLINKLIB_API char* get_git_branch(void); -HARMONYLINKLIB_API char* get_git_commit_timestamp(void); -HARMONYLINKLIB_API bool get_is_debug(void); +#ifdef __cplusplus +namespace LibHarmonyLink { +extern "C" { +#endif + +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/include/Enums/Platform.h b/LibHarmonyLink/src/HarmonyLinkLib.c similarity index 75% rename from HarmonyLinkLib/include/Enums/Platform.h rename to LibHarmonyLink/src/HarmonyLinkLib.c index c077d8c..ab45b0a 100644 --- a/HarmonyLinkLib/include/Enums/Platform.h +++ b/LibHarmonyLink/src/HarmonyLinkLib.c @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Jordon Brooks +// Copyright (c) 2024 Jordon Brooks // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma once +#include +#include "HarmonyLinkLib.h" -typedef enum +#include "Version.h" + +bool HarmonyLink_Init(void) { - EPlatform_UNKNOWN, - EPlatform_WINDOWS, - EPlatform_LINUX, - EPlatform_MAC, - EPlatform_UNIX, -} EPlatform; + HL_version_print(); + return 1; +} diff --git a/HarmonyLinkLib/src/Structs/Battery.c b/LibHarmonyLink/src/Structs/Battery.c similarity index 65% rename from HarmonyLinkLib/src/Structs/Battery.c rename to LibHarmonyLink/src/Structs/Battery.c index 020a0d7..dbd0bba 100644 --- a/HarmonyLinkLib/src/Structs/Battery.c +++ b/LibHarmonyLink/src/Structs/Battery.c @@ -15,6 +15,23 @@ #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"); + 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) { diff --git a/HarmonyLinkLib/src/Structs/CPUInfo.c b/LibHarmonyLink/src/Structs/CPUInfo.c similarity index 94% rename from HarmonyLinkLib/src/Structs/CPUInfo.c rename to LibHarmonyLink/src/Structs/CPUInfo.c index 1c169e9..c88e999 100644 --- a/HarmonyLinkLib/src/Structs/CPUInfo.c +++ b/LibHarmonyLink/src/Structs/CPUInfo.c @@ -26,9 +26,14 @@ FCPUInfo* FCPUInfo_Init(const char *vendorID, const char *modelName, unsigned in 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); 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..5116ba4 --- /dev/null +++ b/LibHarmonyLink/src/Structs/OSInfo.c @@ -0,0 +1,40 @@ +// 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 "Structs/OSInfo.h" + +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"); + exit(EXIT_FAILURE); + } + + OSVerInfo->name = name; + OSVerInfo->version = version; + OSVerInfo->id = id; + OSVerInfo->variant_id = version_id; + OSVerInfo->version_codename = version_codename; + OSVerInfo->pretty_name = pretty_name; + OSVerInfo->version_id = variant_id; + + return OSVerInfo; +} + +void HL_FOSVerInfo_Free(FOSVerInfo *OSVerInfo) { + +} diff --git a/HarmonyLinkLib/src/Structs/StringArray.c b/LibHarmonyLink/src/Structs/StringArray.c similarity index 97% rename from HarmonyLinkLib/src/Structs/StringArray.c rename to LibHarmonyLink/src/Structs/StringArray.c index aa2187f..5165193 100644 --- a/HarmonyLinkLib/src/Structs/StringArray.c +++ b/LibHarmonyLink/src/Structs/StringArray.c @@ -39,7 +39,11 @@ void StringArray_AddFlag(StringArray *flagsInfo, const char *flag) { 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++; } diff --git a/HarmonyLinkLib/src/Utilities.c b/LibHarmonyLink/src/Utilities.c similarity index 71% rename from HarmonyLinkLib/src/Utilities.c rename to LibHarmonyLink/src/Utilities.c index 25d0bf7..6aa8b51 100644 --- a/HarmonyLinkLib/src/Utilities.c +++ b/LibHarmonyLink/src/Utilities.c @@ -17,11 +17,28 @@ wchar_t* convertToWideChar(const char* str) { size_t len = 0; - mbstowcs_s(&len, NULL, 0, str, 0); // Get the length of the wide string (including null terminator) + +#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; } \ No newline at end of file diff --git a/HarmonyLinkLib/src/Version.c b/LibHarmonyLink/src/Version.c similarity index 60% rename from HarmonyLinkLib/src/Version.c rename to LibHarmonyLink/src/Version.c index b844b0c..fd34e33 100644 --- a/HarmonyLinkLib/src/Version.c +++ b/LibHarmonyLink/src/Version.c @@ -15,28 +15,29 @@ #include "Version.h" #include +#include -char* get_version_string(void) +char* HL_version_get_string(void) { return HARMONYLINK_VERSION; } -char* get_version_build_timestamp(void) +char* HL_version_build_timestamp(void) { return __TIMESTAMP__; } -char* get_git_branch(void) +char* HL_git_branch(void) { return GIT_BRANCH_NAME; } -char* get_git_commit_timestamp(void) +char* HL_git_commit_timestamp(void) { return GIT_COMMIT_TIMESTAMP; } -bool get_is_debug(void) +bool HL_is_debug(void) { #ifdef DEBUG_MODE return true; @@ -44,3 +45,11 @@ bool get_is_debug(void) 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"); +} From f25ca44f03cef8667052fb2f0a284fde471045e2 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Mon, 27 May 2024 19:09:17 +0100 Subject: [PATCH 10/18] Linux compile working --- .gitignore | 4 ++ Compile.bat | 68 ++++++++++++++++++++++++++++++++ Compile.sh | 73 +++++++++++++++++++++++++++++++++++ HarmonyLinkLib/CMakeLists.txt | 16 +++++++- HarmonyLinkLib/include/Core.h | 12 +++++- 5 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 Compile.bat create mode 100644 Compile.sh diff --git a/.gitignore b/.gitignore index 2e489f4..a7fdac2 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ build/** linuxbuild/ build/ .idea/ +winbuild/ + +!Compile.sh +!Compile.bat diff --git a/Compile.bat b/Compile.bat new file mode 100644 index 0000000..ccad60c --- /dev/null +++ b/Compile.bat @@ -0,0 +1,68 @@ +@echo off +setlocal enabledelayedexpansion + +REM Clear the screen +cls + +REM Define the color codes +set GREEN= +set NC= + +REM Prompt the user to choose a compiler +echo %GREEN%Select the compiler to use:%NC% +echo 1^ ) MSBuild (default) +echo 2^ ) MinGW +echo 3^ ) Ninja +set /p choice=Enter the number of your choice: + +REM Set the generator and compiler based on the user's choice +if "%choice%"=="2" ( + set "GENERATOR=MinGW Makefiles" + set "COMPILER_OPTION=-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++" +) else if "%choice%"=="3" ( + set "GENERATOR=Ninja" + set "COMPILER_OPTION=" +) else ( + set "GENERATOR=Visual Studio 17 2022" + set "COMPILER_OPTION=-A x64" + set "choice=1" +) + +echo Using generator: %GENERATOR% + +REM Prompt the user to choose a build type +echo %GREEN%Select the build type:%NC% +echo 1^ ) Release (default) +echo 2^ ) Debug +set /p build_choice=Enter the number of your choice: + +REM Set the build type based on the user's choice +if "%build_choice%"=="2" ( + set "BUILD_TYPE=Debug" +) else ( + set "BUILD_TYPE=Release" +) + +echo Build type: %BUILD_TYPE% + +REM Create the build directory if it doesn't exist +if not exist "winbuild" ( + mkdir winbuild +) + +cd winbuild + +REM Get the number of processors +for /f "tokens=2 delims==" %%a in ('wmic cpu get NumberOfLogicalProcessors /value') do set "NUM_PROCESSORS=%%a" + +REM Run CMake with the selected generator and build type +cmake -G "%GENERATOR%" %COMPILER_OPTION% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. + +REM Build the project +if "%choice%"=="1" ( + cmake --build . --config %BUILD_TYPE% -- /m:%NUM_PROCESSORS% +) else ( + cmake --build . --config %BUILD_TYPE% -- -j %NUM_PROCESSORS% +) + +cd .. diff --git a/Compile.sh b/Compile.sh new file mode 100644 index 0000000..c8d82ea --- /dev/null +++ b/Compile.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +set -e + +clear + +# Define the color codes +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +# Prompt the user to choose a compiler +echo "${GREEN}Select the compiler to use:${NC}" +echo "1) g++ (default)" +echo "2) clang++" +echo "3) clang++ 15" +echo "4) clang++ 16" +read -p "Enter the number of your choice: " choice + +# Set the compiler based on the user's choice +case $choice in + 2) + C_COMPILER=clang + CXX_COMPILER=clang++ + ;; + 3) + C_COMPILER=clang-15 + CXX_COMPILER=clang++-15 + ;; + 4) + C_COMPILER=clang-16 + CXX_COMPILER=clang++-16 + ;; + *) + C_COMPILER=gcc + CXX_COMPILER=g++ + ;; +esac + +echo "Using C compiler: $C_COMPILER" +echo "Using C++ compiler: $CXX_COMPILER" + +# Prompt the user to choose a build type +echo "${GREEN}Select the build type:${NC}" +echo "1) Release (default)" +echo "2) Debug" +read -p "Enter the number of your choice: " build_choice + +# Set the build type based on the user's choice +case $build_choice in + 2) + BUILD_TYPE=Debug + ;; + *) + BUILD_TYPE=Release + ;; +esac + +echo "Build type: $BUILD_TYPE" + +# Create the build directory if it doesn't exist +if [ ! -d "linuxbuild" ]; then + mkdir linuxbuild +fi + +cd linuxbuild + +# Run CMake with the selected compiler and build type +cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_COMPILER=$C_COMPILER -DCMAKE_CXX_COMPILER=$CXX_COMPILER .. + +# Build the project +cmake --build . --config $BUILD_TYPE --clean-first -j 15 --verbose + +cd .. diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 7146d8e..eba9442 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -120,6 +120,18 @@ set(MAC_INCLUDES "src/Platform/Unix/UnixUtilities.h" ) +# Platform-specific definitions +if(WIN32) + add_definitions(-DBUILD_WINDOWS) +elseif(UNIX) + if(APPLE) + add_definitions(-DBUILD_MACOS) + else() + add_definitions(-DBUILD_LINUX) + endif() + add_definitions(-DBUILD_UNIX) +endif() + # Platform-specific definitions if(WIN32) message(STATUS "Compiling for Windows...") @@ -140,7 +152,7 @@ elseif(UNIX) endif() # Create the shared library -add_library(HarmonyLinkLibShared SHARED ${LIB_SOURCES} ${SHARED_SOURCES}) +add_library(HarmonyLinkLibShared SHARED ${LIB_SOURCES} ${SHARED_SOURCES} ${LIB_INCLUDES}) target_include_directories(HarmonyLinkLibShared PRIVATE "${PROJECT_SOURCE_DIR}/src" @@ -151,7 +163,7 @@ target_include_directories(HarmonyLinkLibShared target_compile_definitions(HarmonyLinkLibShared PRIVATE HARMONYLINKLIB_SHARED) # Create the static library -add_library(HarmonyLinkLibStatic STATIC ${LIB_SOURCES}) +add_library(HarmonyLinkLibStatic STATIC ${LIB_SOURCES} ${LIB_INCLUDES}) target_include_directories(HarmonyLinkLibStatic PRIVATE "${PROJECT_SOURCE_DIR}/src" diff --git a/HarmonyLinkLib/include/Core.h b/HarmonyLinkLib/include/Core.h index 94a32d2..90babed 100644 --- a/HarmonyLinkLib/include/Core.h +++ b/HarmonyLinkLib/include/Core.h @@ -15,7 +15,7 @@ #pragma once // Use a preprocessor definition to switch between export and import declarations -#ifdef _WIN32 +#ifdef BUILD_WINDOWS #ifdef HARMONYLINKLIB_STATIC #define HARMONYLINKLIB_API #else @@ -26,5 +26,13 @@ #endif #endif #else - #define HARMONYLINKLIB_API + #ifdef HARMONYLINKLIB_SHARED + #ifdef __clang__ + #define HARMONYLINKLIB_API __attribute__((visibility("default"))) + #else + #define HARMONYLINKLIB_API + #endif + #else + #define HARMONYLINKLIB_API + #endif #endif From daa49af2476b0733dd4f67897958e7d621d6cb36 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Fri, 31 May 2024 23:43:22 +0100 Subject: [PATCH 11/18] Working in UE4 --- .gitignore | 1 + HarmonyLinkLib/CMakeLists.txt | 1 - HarmonyLinkLib/include/HarmonyLinkLib.h | 16 ++++--- HarmonyLinkLib/src/HarmonyLinkLib.cpp | 13 ++++-- HarmonyLinkLib/src/dllmain.cpp | 61 ------------------------- HarmonyLinkTest/src/main.cpp | 10 +++- 6 files changed, 29 insertions(+), 73 deletions(-) delete mode 100644 HarmonyLinkLib/src/dllmain.cpp diff --git a/.gitignore b/.gitignore index a7fdac2..2e552b2 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ winbuild/ !Compile.sh !Compile.bat +HarmonyLinkLib/.vscode/ diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index eba9442..e61dfb3 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -69,7 +69,6 @@ set(COMMON_SOURCES "src/Platform/IPlatformUtilities.cpp" "src/HarmonyLinkLib.cpp" "src/Version.cpp" - "src/dllmain.cpp" "src/Platform/WineUtilities.cpp" "src/Utilities.cpp" ) diff --git a/HarmonyLinkLib/include/HarmonyLinkLib.h b/HarmonyLinkLib/include/HarmonyLinkLib.h index d6575a5..0298e2d 100644 --- a/HarmonyLinkLib/include/HarmonyLinkLib.h +++ b/HarmonyLinkLib/include/HarmonyLinkLib.h @@ -44,17 +44,19 @@ class IPlatformUtilities; namespace HarmonyLinkLib { - extern "C" HARMONYLINKLIB_API bool get_is_wine(); + HARMONYLINKLIB_API bool HL_Init(); - extern "C" HARMONYLINKLIB_API bool get_is_linux(); + HARMONYLINKLIB_API bool get_is_wine(); - extern "C" HARMONYLINKLIB_API bool get_is_docked(); + HARMONYLINKLIB_API bool get_is_linux(); - extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info(); + HARMONYLINKLIB_API bool get_is_docked(); - extern "C" HARMONYLINKLIB_API FDevice* get_device_info(); + HARMONYLINKLIB_API FCPUInfo* get_cpu_info(); - extern "C" HARMONYLINKLIB_API FOSVerInfo* get_os_version(); + HARMONYLINKLIB_API FDevice* get_device_info(); + + HARMONYLINKLIB_API FOSVerInfo* get_os_version(); - extern "C" HARMONYLINKLIB_API FBattery* get_battery_status(); + HARMONYLINKLIB_API FBattery* get_battery_status(); } diff --git a/HarmonyLinkLib/src/HarmonyLinkLib.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.cpp index 91ccc2c..f57feac 100644 --- a/HarmonyLinkLib/src/HarmonyLinkLib.cpp +++ b/HarmonyLinkLib/src/HarmonyLinkLib.cpp @@ -16,10 +16,19 @@ #include #include "Platform/IPlatformUtilities.h" +#include "Version.h" namespace HarmonyLinkLib { - std::shared_ptr PlatformUtilities = IPlatformUtilities::GetInstance(); + std::shared_ptr PlatformUtilities = nullptr; + + bool HL_Init() + { + std::wcout << "HarmonyLink V" << version::ToString().c_str() << " Copyright (C) 2023 Jordon Brooks\n"; + PlatformUtilities = IPlatformUtilities::GetInstance(); + + return PlatformUtilities != nullptr; + } bool get_is_wine() { @@ -92,8 +101,6 @@ namespace HarmonyLinkLib FOSVerInfo* get_os_version() { - - if (!PlatformUtilities) { std::wcout << "Failed to get platform utilities!\n"; 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/src/main.cpp b/HarmonyLinkTest/src/main.cpp index e9eaf87..d4d2d29 100644 --- a/HarmonyLinkTest/src/main.cpp +++ b/HarmonyLinkTest/src/main.cpp @@ -85,10 +85,18 @@ void checkForQuit() { int main() { - std::cout << "Hello, World!" << '\n'; + std::cout << "Hello, World!\n"; std::thread inputThread(checkForQuit); + if (!HarmonyLinkLib::HL_Init()) + { + std::cout << "Failed to init HarmonyLinkLib\n"; + return 1; + } + + std::cout << "HarmonyLinkLib successfully initialised!\n"; + const bool isWine = HarmonyLinkLib::get_is_wine(); const char* test = isWine ? "is" : "isn't"; From 9a1e6f24b1ddf2a66e3d7a6cf3388fb9bc86e15e Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Thu, 6 Jun 2024 16:04:11 +0100 Subject: [PATCH 12/18] Fix clang compiler error --- CMakeLists.txt | 12 +++---- HarmonyLinkLib/CMakeLists.txt | 64 ++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02296e9..a394d22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,12 +44,12 @@ elseif(UNIX) endif() # Set global output directories for all build types -foreach(TYPE IN ITEMS DEBUG RELEASE) - string(TOUPPER ${TYPE} TYPE_UPPER) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}") - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}") - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}") -endforeach() +#foreach(TYPE IN ITEMS DEBUG RELEASE) +# string(TOUPPER ${TYPE} TYPE_UPPER) +# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}") +# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}") +# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}") +#endforeach() # Add the library and executable directories diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index e61dfb3..2e2ed12 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -12,7 +12,7 @@ # limitations under the License. cmake_minimum_required(VERSION 3.10) -project(HarmonyLinkLib VERSION 2.1.2) +project(HarmonyLinkLib VERSION 2.1.2 LANGUAGES CXX) include(FetchContent) @@ -150,6 +150,14 @@ 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}) + # Create the shared library add_library(HarmonyLinkLibShared SHARED ${LIB_SOURCES} ${SHARED_SOURCES} ${LIB_INCLUDES}) target_include_directories(HarmonyLinkLibShared @@ -160,6 +168,7 @@ target_include_directories(HarmonyLinkLibShared "${PROJECT_SOURCE_DIR}/include" ) target_compile_definitions(HarmonyLinkLibShared PRIVATE HARMONYLINKLIB_SHARED) +set_target_properties(HarmonyLinkLibShared PROPERTIES OUTPUT_NAME "HarmonyLinkLibShared_${COMPILER_NAME}") # Create the static library add_library(HarmonyLinkLibStatic STATIC ${LIB_SOURCES} ${LIB_INCLUDES}) @@ -171,25 +180,54 @@ target_include_directories(HarmonyLinkLibStatic "${PROJECT_SOURCE_DIR}/include" ) target_compile_definitions(HarmonyLinkLibStatic PRIVATE HARMONYLINKLIB_STATIC) +set_target_properties(HarmonyLinkLibStatic PROPERTIES OUTPUT_NAME "HarmonyLinkLibStatic_${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 - 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 - ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkLibStatic" - ) -endforeach() +#foreach(TYPE IN ITEMS DEBUG RELEASE) +# string(TOUPPER ${TYPE} TYPE_UPPER) +# set_target_properties(HarmonyLinkLibShared 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 +# ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/HarmonyLinkLibStatic" +# ) +#endforeach() # Link fmt to HarmonyLinkLib target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt::fmt-header-only) target_link_libraries(HarmonyLinkLibShared PRIVATE fmt::fmt-header-only) -if (UNIX) +# Determine the compiler and set appropriate flags for libc++ +if (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Use libc++ instead of libstdc++ with Clang + target_compile_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) + target_compile_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) + target_link_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) + target_link_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) + + # Ensure the proper include paths for libc++ + target_include_directories(HarmonyLinkLibStatic SYSTEM PRIVATE + /usr/include/c++/v1 + /usr/local/include/c++/v1 + /usr/include + ) + target_include_directories(HarmonyLinkLibShared SYSTEM PRIVATE + /usr/include/c++/v1 + /usr/local/include/c++/v1 + /usr/include + ) + + # Link against the libc++ library and the filesystem library + target_link_libraries(HarmonyLinkLibStatic PRIVATE c++ c++abi c++experimental) + target_link_libraries(HarmonyLinkLibShared PRIVATE c++ c++abi c++experimental) +elseif (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") + # Use libstdc++ with GCC + target_link_options(HarmonyLinkLibStatic PRIVATE -static-libgcc -static-libstdc++) + target_link_options(HarmonyLinkLibShared PRIVATE -static-libgcc -static-libstdc++) + + # Link against the libstdc++ filesystem library if necessary target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) endif() From 7f0fa0b90d7464378b6d0941cab930e60b2e9b3c Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Thu, 6 Jun 2024 16:04:34 +0100 Subject: [PATCH 13/18] Improved Compile.sh --- Compile.sh | 134 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 40 deletions(-) diff --git a/Compile.sh b/Compile.sh index c8d82ea..63ea1c3 100644 --- a/Compile.sh +++ b/Compile.sh @@ -1,49 +1,96 @@ -#!/bin/sh +#!/bin/bash set -e clear -# Define the color codes +# Define color codes GREEN='\033[0;32m' NC='\033[0m' # No Color +PURPLE='\033[0;35m' +GRAY='\033[1;30m' -# Prompt the user to choose a compiler -echo "${GREEN}Select the compiler to use:${NC}" -echo "1) g++ (default)" -echo "2) clang++" -echo "3) clang++ 15" -echo "4) clang++ 16" -read -p "Enter the number of your choice: " choice +# Ensure dialog is installed +if ! command -v dialog &> /dev/null +then + echo "dialog could not be found. Please install it to use this script." + exit +fi -# Set the compiler based on the user's choice -case $choice in - 2) - C_COMPILER=clang - CXX_COMPILER=clang++ - ;; - 3) - C_COMPILER=clang-15 - CXX_COMPILER=clang++-15 - ;; - 4) - C_COMPILER=clang-16 - CXX_COMPILER=clang++-16 - ;; - *) - C_COMPILER=gcc - CXX_COMPILER=g++ - ;; -esac +# Function to check if a compiler is installed +check_compiler() { + if command -v $1 &> /dev/null + then + COMPILER_OPTIONS+=("$2" "$3" "$4") + fi +} -echo "Using C compiler: $C_COMPILER" -echo "Using C++ compiler: $CXX_COMPILER" +# Array to store the menu options +COMPILER_OPTIONS=() + +# Add available compilers to the options array +check_compiler g++ "1" "g++ (default)" "on" +check_compiler clang++ "2" "clang++" "off" +check_compiler clang++-15 "3" "clang++ 15" "off" +check_compiler clang++-16 "4" "clang++ 16" "off" +check_compiler clang++-17 "5" "clang++ 17" "off" + +# Debug: print the compiler options +echo "Compiler options: ${COMPILER_OPTIONS[@]}" + +# Check if any compilers are available +if [ ${#COMPILER_OPTIONS[@]} -eq 0 ]; then + dialog --msgbox "No compilers found. Please install a compiler to use this script." 10 40 + exit +fi + +# Prompt the user to choose one or more compilers +compiler_choices=$(dialog --colors --title "\Zb\Z5Select Compiler\Zn" --checklist "\nChoose one or more compilers:" 15 60 ${#COMPILER_OPTIONS[@]} "${COMPILER_OPTIONS[@]}" 3>&1 1>&2 2>&3) + +# Process the selected compilers +C_COMPILERS=() +CXX_COMPILERS=() + +# Debug: print the compiler choices +echo "Compiler choices: $compiler_choices" + +for choice in $compiler_choices; do + case $choice in + 1) + C_COMPILERS+=("gcc") + CXX_COMPILERS+=("g++") + ;; + 2) + C_COMPILERS+=("clang") + CXX_COMPILERS+=("clang++") + ;; + 3) + C_COMPILERS+=("clang-15") + CXX_COMPILERS+=("clang++-15") + ;; + 4) + C_COMPILERS+=("clang-16") + CXX_COMPILERS+=("clang++-16") + ;; + 5) + C_COMPILERS+=("clang-17") + CXX_COMPILERS+=("clang++-17") + ;; + esac +done + +# Output the chosen compilers +msg="Chosen compilers:\n" +for i in "${!C_COMPILERS[@]}"; do + msg+="C compiler: ${C_COMPILERS[$i]}, C++ compiler: ${CXX_COMPILERS[$i]}\n" +done + +dialog --colors --msgbox "\Zb\Z5$msg\Zn" 20 60 # Prompt the user to choose a build type -echo "${GREEN}Select the build type:${NC}" -echo "1) Release (default)" -echo "2) Debug" -read -p "Enter the number of your choice: " build_choice +build_choice=$(dialog --colors --title "\Zb\Z5Select Build Type\Zn" --menu "\nChoose a build type:" 10 40 2 \ +1 "Release (default)" \ +2 "Debug" 3>&1 1>&2 2>&3) # Set the build type based on the user's choice case $build_choice in @@ -55,7 +102,10 @@ case $build_choice in ;; esac -echo "Build type: $BUILD_TYPE" +# Output the chosen build type +dialog --colors --msgbox "\Zb\Z5Build type:\Zn $BUILD_TYPE" 10 40 + +clear # Create the build directory if it doesn't exist if [ ! -d "linuxbuild" ]; then @@ -64,10 +114,14 @@ fi cd linuxbuild -# Run CMake with the selected compiler and build type -cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_COMPILER=$C_COMPILER -DCMAKE_CXX_COMPILER=$CXX_COMPILER .. - -# Build the project -cmake --build . --config $BUILD_TYPE --clean-first -j 15 --verbose +# Run CMake with the selected compilers and build type +for i in "${!C_COMPILERS[@]}"; do + cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_COMPILER=${C_COMPILERS[$i]} -DCMAKE_CXX_COMPILER=${CXX_COMPILERS[$i]} .. + # Build the project + cmake --build . --config $BUILD_TYPE -j 15 #--clean-first #--verbose +done cd .. + +# End with a success message +dialog --colors --msgbox "\Zb\Z5Build(s) completed successfully!\Zn" 10 40 From c68c039c70730e1ee1eaa7dfdbbe9df1757f951a Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Thu, 6 Jun 2024 18:15:51 +0100 Subject: [PATCH 14/18] Fixed + enabled all compiler warnings --- .gitignore | 1 + HarmonyLinkTest/CMakeLists.txt | 7 +++++ HarmonyLinkTest/src/main.c | 2 +- HarmonyLinkTest_CPP/CMakeLists.txt | 7 +++++ HarmonyLinkTest_CPP/src/main.cpp | 2 +- LibHarmonyLink/CMakeLists.txt | 21 +++++++++++-- LibHarmonyLink/include/Core.h | 2 +- LibHarmonyLink/include/HarmonyLinkLib.h | 2 +- LibHarmonyLink/include/Structs/CPUInfo.h | 6 ++-- LibHarmonyLink/include/Structs/StringArray.h | 2 +- LibHarmonyLink/include/Utilities.h | 2 +- LibHarmonyLink/src/HarmonyLinkLib.c | 2 +- LibHarmonyLink/src/Structs/Battery.c | 3 +- LibHarmonyLink/src/Structs/OSInfo.c | 31 +++++++++++++++----- LibHarmonyLink/src/Utilities.c | 2 +- LibHarmonyLink/src/Version.c | 2 ++ 16 files changed, 72 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 81e8788..390d006 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ build/** linuxbuild/ build/ .idea/ +winbuild/ diff --git a/HarmonyLinkTest/CMakeLists.txt b/HarmonyLinkTest/CMakeLists.txt index a821500..a7c0d12 100644 --- a/HarmonyLinkTest/CMakeLists.txt +++ b/HarmonyLinkTest/CMakeLists.txt @@ -22,6 +22,13 @@ set(CMAKE_C_STANDARD_REQUIRED True) 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 LibHarmonyLinkStatic) diff --git a/HarmonyLinkTest/src/main.c b/HarmonyLinkTest/src/main.c index 245d90e..4752dd4 100644 --- a/HarmonyLinkTest/src/main.c +++ b/HarmonyLinkTest/src/main.c @@ -19,7 +19,7 @@ int main(void) { wprintf(L"Hello from C!\n"); - if (!HarmonyLink_Init()) + if (!HL_Init()) { wprintf(L"Error: Failed to initialise HarmonyLink!\n"); return 1; diff --git a/HarmonyLinkTest_CPP/CMakeLists.txt b/HarmonyLinkTest_CPP/CMakeLists.txt index 9c18edd..65efc21 100644 --- a/HarmonyLinkTest_CPP/CMakeLists.txt +++ b/HarmonyLinkTest_CPP/CMakeLists.txt @@ -22,6 +22,13 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) 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) diff --git a/HarmonyLinkTest_CPP/src/main.cpp b/HarmonyLinkTest_CPP/src/main.cpp index 7d9a93f..2128219 100644 --- a/HarmonyLinkTest_CPP/src/main.cpp +++ b/HarmonyLinkTest_CPP/src/main.cpp @@ -89,7 +89,7 @@ int main() std::thread inputThread(checkForQuit); - if (!LibHarmonyLink::HarmonyLink_Init()) + if (!LibHarmonyLink::HL_Init()) { printf("Failed to Initialize HarmonyLink!"); } diff --git a/LibHarmonyLink/CMakeLists.txt b/LibHarmonyLink/CMakeLists.txt index b250121..217c38e 100644 --- a/LibHarmonyLink/CMakeLists.txt +++ b/LibHarmonyLink/CMakeLists.txt @@ -12,7 +12,7 @@ # limitations under the License. cmake_minimum_required(VERSION 3.10) -project(LibHarmonyLink VERSION 2.1.1) +project(LibHarmonyLink VERSION 2.1.1 LANGUAGES C) # Specify the C++ standard set(CMAKE_C_STANDARD 11) @@ -60,7 +60,7 @@ set(COMMON_SOURCES src/Structs/CPUInfo.c src/Structs/StringArray.c src/Structs/Device.c - src/Structs/OSInfo.C + src/Structs/OSInfo.c ) # Explicitly list include files @@ -119,6 +119,21 @@ 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(LibHarmonyLinkShared SHARED ${LIB_SOURCES} ${LIB_INCLUDES} ${SHARED_SOURCES}) target_include_directories(LibHarmonyLinkShared @@ -129,6 +144,7 @@ target_include_directories(LibHarmonyLinkShared "${PROJECT_SOURCE_DIR}/include" ) target_compile_definitions(LibHarmonyLinkShared PRIVATE HARMONYLINK_SHARED) +set_target_properties(LibHarmonyLinkShared PROPERTIES OUTPUT_NAME "LibHarmonyLink_${COMPILER_NAME}") # Create the static library add_library(LibHarmonyLinkStatic STATIC ${LIB_SOURCES} ${LIB_INCLUDES}) @@ -140,6 +156,7 @@ target_include_directories(LibHarmonyLinkStatic "${PROJECT_SOURCE_DIR}/include" ) 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) diff --git a/LibHarmonyLink/include/Core.h b/LibHarmonyLink/include/Core.h index 49ea871..f561b77 100644 --- a/LibHarmonyLink/include/Core.h +++ b/LibHarmonyLink/include/Core.h @@ -26,5 +26,5 @@ #endif #endif #else - #define HARMONYLINKLIB_API + #define HARMONYLINK_API #endif diff --git a/LibHarmonyLink/include/HarmonyLinkLib.h b/LibHarmonyLink/include/HarmonyLinkLib.h index a6a45ed..a62e00c 100644 --- a/LibHarmonyLink/include/HarmonyLinkLib.h +++ b/LibHarmonyLink/include/HarmonyLinkLib.h @@ -22,7 +22,7 @@ namespace LibHarmonyLink { extern "C" { #endif -HARMONYLINK_API bool HarmonyLink_Init(void); +HARMONYLINK_API bool HL_Init(void); #ifdef __cplusplus } diff --git a/LibHarmonyLink/include/Structs/CPUInfo.h b/LibHarmonyLink/include/Structs/CPUInfo.h index 044adb9..36d9d13 100644 --- a/LibHarmonyLink/include/Structs/CPUInfo.h +++ b/LibHarmonyLink/include/Structs/CPUInfo.h @@ -27,9 +27,9 @@ namespace LibHarmonyLink { extern "C" { #endif -typedef struct { - char *VendorID; - char *Model_Name; +typedef struct FCPUInfo { + char* VendorID; + char* Model_Name; unsigned int Physical_Cores; unsigned int Logical_Cores; StringArray flagsInfo; diff --git a/LibHarmonyLink/include/Structs/StringArray.h b/LibHarmonyLink/include/Structs/StringArray.h index 1b87569..af9beea 100644 --- a/LibHarmonyLink/include/Structs/StringArray.h +++ b/LibHarmonyLink/include/Structs/StringArray.h @@ -28,7 +28,7 @@ namespace LibHarmonyLink { extern "C" { #endif -typedef struct { +typedef struct StringArray { char **data; // Array of strings (flags) size_t FlagsCount; // Number of flags size_t AllocatedSize; // Number of allocated slots diff --git a/LibHarmonyLink/include/Utilities.h b/LibHarmonyLink/include/Utilities.h index 4aa6856..cffd96e 100644 --- a/LibHarmonyLink/include/Utilities.h +++ b/LibHarmonyLink/include/Utilities.h @@ -25,4 +25,4 @@ wchar_t *convertToWideChar(const char *str); #ifdef __cplusplus } } -#endif \ No newline at end of file +#endif diff --git a/LibHarmonyLink/src/HarmonyLinkLib.c b/LibHarmonyLink/src/HarmonyLinkLib.c index ab45b0a..ae7ae47 100644 --- a/LibHarmonyLink/src/HarmonyLinkLib.c +++ b/LibHarmonyLink/src/HarmonyLinkLib.c @@ -17,7 +17,7 @@ #include "Version.h" -bool HarmonyLink_Init(void) +bool HL_Init(void) { HL_version_print(); return 1; diff --git a/LibHarmonyLink/src/Structs/Battery.c b/LibHarmonyLink/src/Structs/Battery.c index dbd0bba..56d69a2 100644 --- a/LibHarmonyLink/src/Structs/Battery.c +++ b/LibHarmonyLink/src/Structs/Battery.c @@ -23,7 +23,8 @@ FBattery* HL_FBattery_Init(bool has_battery, bool is_connected_to_ac, unsigned c if (battery == NULL) { fprintf(stderr, "Memory allocation failed for FCPUInfo.\n"); - exit(EXIT_FAILURE); + return NULL; + //exit(EXIT_FAILURE); } battery->has_battery = has_battery; diff --git a/LibHarmonyLink/src/Structs/OSInfo.c b/LibHarmonyLink/src/Structs/OSInfo.c index 5116ba4..d3493ac 100644 --- a/LibHarmonyLink/src/Structs/OSInfo.c +++ b/LibHarmonyLink/src/Structs/OSInfo.c @@ -13,28 +13,43 @@ // 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"); - exit(EXIT_FAILURE); + return NULL; + //exit(EXIT_FAILURE); } - OSVerInfo->name = name; - OSVerInfo->version = version; + OSVerInfo->name = strdup(name); + OSVerInfo->version = strdup(version); OSVerInfo->id = id; - OSVerInfo->variant_id = version_id; - OSVerInfo->version_codename = version_codename; - OSVerInfo->pretty_name = pretty_name; - OSVerInfo->version_id = variant_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) { +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/Utilities.c b/LibHarmonyLink/src/Utilities.c index 6aa8b51..5434fee 100644 --- a/LibHarmonyLink/src/Utilities.c +++ b/LibHarmonyLink/src/Utilities.c @@ -41,4 +41,4 @@ wchar_t* convertToWideChar(const char* str) { #endif return wstr; -} \ No newline at end of file +} diff --git a/LibHarmonyLink/src/Version.c b/LibHarmonyLink/src/Version.c index fd34e33..01e0a4b 100644 --- a/LibHarmonyLink/src/Version.c +++ b/LibHarmonyLink/src/Version.c @@ -16,6 +16,8 @@ #include #include +#include +#include char* HL_version_get_string(void) { From a7a80571ea304f1fa9baeb89f5a17194593b9853 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Thu, 6 Jun 2024 19:20:29 +0100 Subject: [PATCH 15/18] Remove stdc++fs requirement by using an external library --- .gitattributes | 5 +- HarmonyLinkLib/CMakeLists.txt | 78 +++++++++++-------- HarmonyLinkLib/src/Platform/WineUtilities.cpp | 6 +- 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/.gitattributes b/.gitattributes index 970e13f..92bbb8f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -36,4 +36,7 @@ # Executables *.exe binary *.out binary -*.app binary \ No newline at end of file +*.app binary + +# Linux shell files must always be LF +*.sh text eol=lf \ No newline at end of file diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 2e2ed12..311eed3 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -28,6 +28,18 @@ FetchContent_MakeAvailable(fmt) set_target_properties(fmt PROPERTIES FOLDER External) set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +# Fetch ghc library +FetchContent_Declare( + ghc_filesystem + GIT_REPOSITORY https://github.com/gulrak/filesystem.git + GIT_TAG v1.5.14 # Specify the desired version of ghc +) + +FetchContent_MakeAvailable(ghc_filesystem) + +set_target_properties(ghc_filesystem PROPERTIES FOLDER External) +set_target_properties(ghc_filesystem PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + # Find the current Git branch and the last commit timestamp find_package(Git QUIET) if(GIT_FOUND) @@ -199,35 +211,39 @@ set_target_properties(HarmonyLinkLibStatic PROPERTIES OUTPUT_NAME "HarmonyLinkLi target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt::fmt-header-only) target_link_libraries(HarmonyLinkLibShared PRIVATE fmt::fmt-header-only) +# Link ghc to HarmonyLinkLib +target_link_libraries(HarmonyLinkLibStatic PRIVATE ghc_filesystem) +target_link_libraries(HarmonyLinkLibShared PRIVATE ghc_filesystem) + # Determine the compiler and set appropriate flags for libc++ -if (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") - # Use libc++ instead of libstdc++ with Clang - target_compile_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) - target_compile_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) - target_link_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) - target_link_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) - - # Ensure the proper include paths for libc++ - target_include_directories(HarmonyLinkLibStatic SYSTEM PRIVATE - /usr/include/c++/v1 - /usr/local/include/c++/v1 - /usr/include - ) - target_include_directories(HarmonyLinkLibShared SYSTEM PRIVATE - /usr/include/c++/v1 - /usr/local/include/c++/v1 - /usr/include - ) - - # Link against the libc++ library and the filesystem library - target_link_libraries(HarmonyLinkLibStatic PRIVATE c++ c++abi c++experimental) - target_link_libraries(HarmonyLinkLibShared PRIVATE c++ c++abi c++experimental) -elseif (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") - # Use libstdc++ with GCC - target_link_options(HarmonyLinkLibStatic PRIVATE -static-libgcc -static-libstdc++) - target_link_options(HarmonyLinkLibShared PRIVATE -static-libgcc -static-libstdc++) - - # Link against the libstdc++ filesystem library if necessary - target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) - target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) -endif() +#if (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") +# # Use libc++ instead of libstdc++ with Clang +# target_compile_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) +# target_compile_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) +# target_link_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) +# target_link_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) +# +# # Ensure the proper include paths for libc++ +# target_include_directories(HarmonyLinkLibStatic SYSTEM PRIVATE +# /usr/include/c++/v1 +# /usr/local/include/c++/v1 +# /usr/include +# ) +# target_include_directories(HarmonyLinkLibShared SYSTEM PRIVATE +# /usr/include/c++/v1 +# /usr/local/include/c++/v1 +# /usr/include +# ) +# +# # Link against the libc++ library and the filesystem library +# target_link_libraries(HarmonyLinkLibStatic PRIVATE c++ c++abi c++experimental) +# target_link_libraries(HarmonyLinkLibShared PRIVATE c++ c++abi c++experimental) +#elseif (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") +# # Use libstdc++ with GCC +# target_link_options(HarmonyLinkLibStatic PRIVATE -static-libgcc -static-libstdc++) +# target_link_options(HarmonyLinkLibShared PRIVATE -static-libgcc -static-libstdc++) +# +# # Link against the libstdc++ filesystem library if necessary +# target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) +# target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) +#endif() diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.cpp b/HarmonyLinkLib/src/Platform/WineUtilities.cpp index efe48a3..fca7352 100644 --- a/HarmonyLinkLib/src/Platform/WineUtilities.cpp +++ b/HarmonyLinkLib/src/Platform/WineUtilities.cpp @@ -18,12 +18,14 @@ #include #include #include -#include +#include #ifdef BUILD_WINDOWS #include #endif +namespace fs = ghc::filesystem; + namespace HarmonyLinkLib { bool force_detect_wine = false; @@ -38,7 +40,7 @@ namespace HarmonyLinkLib 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)) { + if (std::string bat_path = append + "/sys/class/power_supply/BAT" + std::to_string(i); fs::exists(bat_path)) { result.has_battery = true; std::ifstream status_file(bat_path + "/status"); From 416fdb3bdbd5addd6880e62e06daa9fa046c0b0e Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Thu, 6 Jun 2024 20:06:09 +0100 Subject: [PATCH 16/18] UE4 Linux successful compile --- HarmonyLinkLib/CMakeLists.txt | 50 +++++++++++++---------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index 311eed3..de087b6 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -216,34 +216,22 @@ target_link_libraries(HarmonyLinkLibStatic PRIVATE ghc_filesystem) target_link_libraries(HarmonyLinkLibShared PRIVATE ghc_filesystem) # Determine the compiler and set appropriate flags for libc++ -#if (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") -# # Use libc++ instead of libstdc++ with Clang -# target_compile_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) -# target_compile_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) -# target_link_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) -# target_link_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) -# -# # Ensure the proper include paths for libc++ -# target_include_directories(HarmonyLinkLibStatic SYSTEM PRIVATE -# /usr/include/c++/v1 -# /usr/local/include/c++/v1 -# /usr/include -# ) -# target_include_directories(HarmonyLinkLibShared SYSTEM PRIVATE -# /usr/include/c++/v1 -# /usr/local/include/c++/v1 -# /usr/include -# ) -# -# # Link against the libc++ library and the filesystem library -# target_link_libraries(HarmonyLinkLibStatic PRIVATE c++ c++abi c++experimental) -# target_link_libraries(HarmonyLinkLibShared PRIVATE c++ c++abi c++experimental) -#elseif (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") -# # Use libstdc++ with GCC -# target_link_options(HarmonyLinkLibStatic PRIVATE -static-libgcc -static-libstdc++) -# target_link_options(HarmonyLinkLibShared PRIVATE -static-libgcc -static-libstdc++) -# -# # Link against the libstdc++ filesystem library if necessary -# target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) -# target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) -#endif() +if (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Use libc++ instead of libstdc++ with Clang + target_compile_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) + target_compile_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) + target_link_options(HarmonyLinkLibStatic PRIVATE -stdlib=libc++) + target_link_options(HarmonyLinkLibShared PRIVATE -stdlib=libc++) + + # Link against the libc++ library and the filesystem library + target_link_libraries(HarmonyLinkLibStatic PRIVATE c++ c++abi c++experimental) + target_link_libraries(HarmonyLinkLibShared PRIVATE c++ c++abi c++experimental) +elseif (UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") + # Use libstdc++ with GCC + target_link_options(HarmonyLinkLibStatic PRIVATE -static-libgcc -static-libstdc++) + target_link_options(HarmonyLinkLibShared PRIVATE -static-libgcc -static-libstdc++) + + # Link against the libstdc++ filesystem library if necessary + #target_link_libraries(HarmonyLinkLibStatic PRIVATE stdc++fs) + #target_link_libraries(HarmonyLinkLibShared PRIVATE stdc++fs) +endif() From 6669a6a102e408f13be41a07519391838ba65bd3 Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Sun, 14 Jul 2024 16:42:34 +0100 Subject: [PATCH 17/18] Working wine & Linux detection --- HarmonyLinkTest/src/main.c | 8 +- HarmonyLinkTest_CPP/src/main.cpp | 31 ++++--- LibHarmonyLink/CMakeLists.txt | 6 +- LibHarmonyLink/include/LibHarmonyLink.h | 90 +++++++++++++++++++ .../include/{HarmonyLinkLib.h => Wine.h} | 2 +- LibHarmonyLink/src/HarmonyLinkLib.c | 24 ----- LibHarmonyLink/src/LibHarmonyLink.c | 84 +++++++++++++++++ LibHarmonyLink/src/Wine.c | 41 +++++++++ 8 files changed, 246 insertions(+), 40 deletions(-) create mode 100644 LibHarmonyLink/include/LibHarmonyLink.h rename LibHarmonyLink/include/{HarmonyLinkLib.h => Wine.h} (95%) delete mode 100644 LibHarmonyLink/src/HarmonyLinkLib.c create mode 100644 LibHarmonyLink/src/LibHarmonyLink.c create mode 100644 LibHarmonyLink/src/Wine.c diff --git a/HarmonyLinkTest/src/main.c b/HarmonyLinkTest/src/main.c index 4752dd4..8481c73 100644 --- a/HarmonyLinkTest/src/main.c +++ b/HarmonyLinkTest/src/main.c @@ -13,7 +13,7 @@ // limitations under the License. #include -#include "HarmonyLinkLib.h" +#include "LibHarmonyLink.h" int main(void) { @@ -26,6 +26,12 @@ int main(void) } wprintf(L"Successfully Initialised HarmonyLink!\n"); + + 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/src/main.cpp b/HarmonyLinkTest_CPP/src/main.cpp index 2128219..7680ffd 100644 --- a/HarmonyLinkTest_CPP/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,6 +32,8 @@ std::atomic quitFlag(false); +std::atomic HasError(false); + // Function to clear the screen cross-platform void clearScreen() { #ifdef BUILD_WINDOWS @@ -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,19 +89,25 @@ int main() { std::cout << "Hello, World!" << '\n'; - std::thread inputThread(checkForQuit); - if (!LibHarmonyLink::HL_Init()) { - printf("Failed to Initialize HarmonyLink!"); + printf("Failed to Initialize HarmonyLink!\n"); + + HasError = true; + return 1; } - printf("HarmonyLink Initialized!"); + printf("HarmonyLink Initialized!\n"); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + std::thread inputThread(checkForQuit); - //const bool isWine = LibHarmonyLink::get_is_wine(); - //const char* test = isWine ? "is" : "isn't"; + 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"; + + printf("This program %s running under wine.\n", test); //const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); @@ -107,14 +115,13 @@ int main() //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(); diff --git a/LibHarmonyLink/CMakeLists.txt b/LibHarmonyLink/CMakeLists.txt index 217c38e..fd1c097 100644 --- a/LibHarmonyLink/CMakeLists.txt +++ b/LibHarmonyLink/CMakeLists.txt @@ -52,9 +52,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Resources/Version.rc.in ${CMAKE_CURRE # Explicitly list source files set(COMMON_SOURCES - src/HarmonyLinkLib.c + src/LibHarmonyLink.c src/Version.c src/Utilities.c + src/Wine.c src/Structs/Battery.c src/Structs/CPUInfo.c @@ -66,9 +67,10 @@ set(COMMON_SOURCES # Explicitly list include files set(COMMON_INCLUDES include/Core.h - include/HarmonyLinkLib.h + include/LibHarmonyLink.h include/Version.h include/Utilities.h + include/Wine.h include/Enums/Device.h include/Enums/Platform.h 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/LibHarmonyLink/include/HarmonyLinkLib.h b/LibHarmonyLink/include/Wine.h similarity index 95% rename from LibHarmonyLink/include/HarmonyLinkLib.h rename to LibHarmonyLink/include/Wine.h index a62e00c..9614ee4 100644 --- a/LibHarmonyLink/include/HarmonyLinkLib.h +++ b/LibHarmonyLink/include/Wine.h @@ -22,7 +22,7 @@ namespace LibHarmonyLink { extern "C" { #endif -HARMONYLINK_API bool HL_Init(void); +bool Detect_Wine(void); #ifdef __cplusplus } diff --git a/LibHarmonyLink/src/HarmonyLinkLib.c b/LibHarmonyLink/src/HarmonyLinkLib.c deleted file mode 100644 index ae7ae47..0000000 --- a/LibHarmonyLink/src/HarmonyLinkLib.c +++ /dev/null @@ -1,24 +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 "HarmonyLinkLib.h" - -#include "Version.h" - -bool HL_Init(void) -{ - HL_version_print(); - return 1; -} 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/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 From cb84f3dff845286163f73d6baf566fd128076b59 Mon Sep 17 00:00:00 2001 From: jordon Date: Sun, 4 May 2025 14:28:55 +0100 Subject: [PATCH 18/18] Updated links --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 81a55f2..f8a5b5e 100644 --- a/README.md +++ b/README.md @@ -61,22 +61,22 @@ As you can see, Even though it's running on Proton, we can still detect the unde Integrate HarmonyLink 2.0 into your game project with ease: -1. Download the latest version of HarmonyLink 2.0 from the [releases page](https://github.com/Jordonbc/HarmonyLink/releases/latest). +1. Download the latest version of HarmonyLink 2.0 from the [releases page](https://git.bbgames.dev/jordon/HarmonyLink/releases/latest). 2. Add the HarmonyLink DLL to your project according to your development environment's specifications. 3. Utilize the provided API to access device-specific metrics and enhance your game's performance on handheld devices. -Refer to the [integration documentation](https://github.com/Jordonbc/HarmonyLink/wiki/Integration-Guide) for detailed instructions. +Refer to the [integration documentation](https://git.bbgames.dev/jordon/HarmonyLink/wiki) for detailed instructions. ### Unreal Engine 5 Plugin For developers leveraging Unreal Engine 5.3 or newer*, HarmonyLink 2.0 is readily accessible as a plugin: -1. Clone or download the HarmonyLink UE5 Plugin from the [Unreal Engine Plugin repository](https://github.com/Jordonbc/HarmonyLinkUE). +1. Clone or download the HarmonyLink UE5 Plugin from the [Unreal Engine Plugin repository](https://git.bbgames.dev/jordon/HarmonyLinkUE). 2. Place the HarmonyLink plugin folder into the `Plugins` directory of your Unreal Engine 5 project. 3. Enable the HarmonyLink plugin from the Edit > Plugins menu within Unreal Engine 5. 4. Access HarmonyLink functionalities via Blueprints or C++ within your project. -For a step-by-step guide, visit the [Unreal Engine 5 Plugin instructions](https://github.com/Jordonbc/HarmonyLinkUE/wiki/Integration-Guide) on our wiki. +For a step-by-step guide, visit the [Unreal Engine 5 Plugin instructions](https://git.bbgames.dev/jordon/HarmonyLinkUE/wiki) on our wiki. *With potential backward compatibility, not verified. @@ -91,7 +91,7 @@ If you prefer to build HarmonyLink 2.0 from the source code, follow these steps: 5. Compile the code by running `cmake --build build --config Release`. 6. The built DLL will be located in the `build/bin/HarmonyLinkLib` directory. -For additional building options and troubleshooting, refer to the [building from source documentation](https://github.com/Jordonbc/HarmonyLink/wiki/Building-From-Source). +For additional building options and troubleshooting, refer to the [building from source documentation](https://git.bbgames.dev/jordon/HarmonyLink/wiki). ## How It Works