Compare commits

..

No commits in common. "Dev" and "V2.1" have entirely different histories.
Dev ... V2.1

16 changed files with 124 additions and 351 deletions

5
.gitattributes vendored
View file

@ -36,7 +36,4 @@
# Executables
*.exe binary
*.out binary
*.app binary
# Linux shell files must always be LF
*.sh text eol=lf
*.app binary

View file

@ -24,7 +24,7 @@ jobs:
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
os: [ubuntu-latest, windows-latest] # macos-latest
os: [ubuntu-latest, windows-latest, macos-latest]
build_type: [Release]
c_compiler: [gcc, clang, cl]
cpp_compiler: [g++, clang++, cl]
@ -38,9 +38,9 @@ jobs:
- os: ubuntu-latest
c_compiler: clang
cpp_compiler: clang++
#- os: macos-latest
# c_compiler: clang
# cpp_compiler: clang++
- os: macos-latest
c_compiler: clang
cpp_compiler: clang++
exclude:
- os: windows-latest
c_compiler: gcc
@ -50,14 +50,14 @@ jobs:
c_compiler: cl
- os: ubuntu-latest
cpp_compiler: cl
#- os: macos-latest
# c_compiler: gcc
#- os: macos-latest
# cpp_compiler: g++
#- os: macos-latest
# c_compiler: cl
#- os: macos-latest
# cpp_compiler: cl
- os: macos-latest
c_compiler: gcc
- os: macos-latest
cpp_compiler: g++
- os: macos-latest
c_compiler: cl
- os: macos-latest
cpp_compiler: cl
steps:
- uses: actions/checkout@v4
with:

6
.gitignore vendored
View file

@ -21,9 +21,3 @@ build/**
# Blacklist specific build directories
linuxbuild/
build/
.idea/
winbuild/
!Compile.sh
!Compile.bat
HarmonyLinkLib/.vscode/

View file

@ -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

View file

@ -1,68 +0,0 @@
@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 ..

View file

@ -1,127 +0,0 @@
#!/bin/bash
set -e
clear
# Define color codes
GREEN='\033[0;32m'
NC='\033[0m' # No Color
PURPLE='\033[0;35m'
GRAY='\033[1;30m'
# 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
# Function to check if a compiler is installed
check_compiler() {
if command -v $1 &> /dev/null
then
COMPILER_OPTIONS+=("$2" "$3" "$4")
fi
}
# 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
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
2)
BUILD_TYPE=Debug
;;
*)
BUILD_TYPE=Release
;;
esac
# 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
mkdir linuxbuild
fi
cd linuxbuild
# 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

View file

@ -12,11 +12,10 @@
# limitations under the License.
cmake_minimum_required(VERSION 3.10)
project(HarmonyLinkLib VERSION 2.1.2 LANGUAGES CXX)
project(HarmonyLinkLib VERSION 2.1.0)
include(FetchContent)
# Fetch fmt library
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
@ -24,22 +23,15 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(fmt)
if(NOT fmt_POPULATED)
FetchContent_Populate(fmt)
# Add fmt but exclude it from the ALL target, reducing IDE clutter
add_subdirectory(${fmt_SOURCE_DIR} ${fmt_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
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)
@ -81,6 +73,7 @@ set(COMMON_SOURCES
"src/Platform/IPlatformUtilities.cpp"
"src/HarmonyLinkLib.cpp"
"src/Version.cpp"
"src/dllmain.cpp"
"src/Platform/WineUtilities.cpp"
"src/Utilities.cpp"
)
@ -131,18 +124,6 @@ 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...")
@ -162,16 +143,8 @@ 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})
add_library(HarmonyLinkLibShared SHARED ${LIB_SOURCES} ${SHARED_SOURCES})
target_include_directories(HarmonyLinkLibShared
PRIVATE
"${PROJECT_SOURCE_DIR}/src"
@ -180,10 +153,9 @@ 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})
add_library(HarmonyLinkLibStatic STATIC ${LIB_SOURCES})
target_include_directories(HarmonyLinkLibStatic
PRIVATE
"${PROJECT_SOURCE_DIR}/src"
@ -192,46 +164,20 @@ 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)
# 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++)
# 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()
# Link fmt library to both shared and static libraries
target_link_libraries(HarmonyLinkLibShared PRIVATE fmt::fmt)
target_link_libraries(HarmonyLinkLibStatic PRIVATE fmt::fmt)

View file

@ -15,7 +15,7 @@
#pragma once
// Use a preprocessor definition to switch between export and import declarations
#ifdef BUILD_WINDOWS
#ifdef _WIN32
#ifdef HARMONYLINKLIB_STATIC
#define HARMONYLINKLIB_API
#else
@ -26,13 +26,5 @@
#endif
#endif
#else
#ifdef HARMONYLINKLIB_SHARED
#ifdef __clang__
#define HARMONYLINKLIB_API __attribute__((visibility("default")))
#else
#define HARMONYLINKLIB_API
#endif
#else
#define HARMONYLINKLIB_API
#endif
#define HARMONYLINKLIB_API
#endif

View file

@ -14,9 +14,6 @@
#pragma once
// Undefine the LINUX macro to avoid conflicts with the enum definition.
#undef LINUX
#include <cstdint>
// Enum class for representing different types of devices

View file

@ -44,19 +44,17 @@ class IPlatformUtilities;
namespace HarmonyLinkLib
{
HARMONYLINKLIB_API bool HL_Init();
extern "C" HARMONYLINKLIB_API bool get_is_wine();
HARMONYLINKLIB_API bool get_is_wine();
extern "C" HARMONYLINKLIB_API bool get_is_linux();
HARMONYLINKLIB_API bool get_is_linux();
extern "C" HARMONYLINKLIB_API bool get_is_docked();
HARMONYLINKLIB_API bool get_is_docked();
extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info();
HARMONYLINKLIB_API FCPUInfo* get_cpu_info();
extern "C" HARMONYLINKLIB_API FDevice* get_device_info();
HARMONYLINKLIB_API FDevice* get_device_info();
HARMONYLINKLIB_API FOSVerInfo* get_os_version();
extern "C" HARMONYLINKLIB_API FOSVerInfo* get_os_version();
HARMONYLINKLIB_API FBattery* get_battery_status();
extern "C" HARMONYLINKLIB_API FBattery* get_battery_status();
}

View file

@ -16,19 +16,10 @@
#include <iostream>
#include "Platform/IPlatformUtilities.h"
#include "Version.h"
namespace HarmonyLinkLib
{
std::shared_ptr<IPlatformUtilities> 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;
}
std::shared_ptr<IPlatformUtilities> PlatformUtilities = IPlatformUtilities::GetInstance();
bool get_is_wine()
{
@ -101,6 +92,8 @@ namespace HarmonyLinkLib
FOSVerInfo* get_os_version()
{
if (!PlatformUtilities)
{
std::wcout << "Failed to get platform utilities!\n";

View file

@ -49,7 +49,7 @@ namespace HarmonyLinkLib
INSTANCE = std::make_shared<UnixUtilities>();
// ... other platform checks
#else
std::wcout << "Platform is not supported.\n";
std::wcout << "Platform is not supported.\n"
#endif
}

View file

@ -18,14 +18,12 @@
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <ghc/filesystem.hpp>
#include <filesystem>
#ifdef BUILD_WINDOWS
#include <windows.h>
#endif
namespace fs = ghc::filesystem;
namespace HarmonyLinkLib
{
bool force_detect_wine = false;
@ -40,7 +38,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); fs::exists(bat_path)) {
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");

View file

@ -0,0 +1,61 @@
// Copyright (c) 2024 Jordon Brooks
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
#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 <windows.h>
// 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

View file

@ -85,18 +85,10 @@ 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";

View file

@ -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://git.bbgames.dev/jordon/HarmonyLink/releases/latest).
1. Download the latest version of HarmonyLink 2.0 from the [releases page](https://github.com/Jordonbc/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://git.bbgames.dev/jordon/HarmonyLink/wiki) for detailed instructions.
Refer to the [integration documentation](https://github.com/Jordonbc/HarmonyLink/wiki/Integration-Guide) 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://git.bbgames.dev/jordon/HarmonyLinkUE).
1. Clone or download the HarmonyLink UE5 Plugin from the [Unreal Engine Plugin repository](https://github.com/Jordonbc/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://git.bbgames.dev/jordon/HarmonyLinkUE/wiki) on our wiki.
For a step-by-step guide, visit the [Unreal Engine 5 Plugin instructions](https://github.com/Jordonbc/HarmonyLinkUE/wiki/Integration-Guide) 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://git.bbgames.dev/jordon/HarmonyLink/wiki).
For additional building options and troubleshooting, refer to the [building from source documentation](https://github.com/Jordonbc/HarmonyLink/wiki/Building-From-Source).
## How It Works