diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt index af70787..a0dbaad 100644 --- a/HarmonyLinkLib/CMakeLists.txt +++ b/HarmonyLinkLib/CMakeLists.txt @@ -66,6 +66,7 @@ set(COMMON_INCLUDES "include/Enums/EDevice.h" "include/Enums/EPlatform.h" + "include/Enums/ESteamDeck.h" "include/FString.h" "include/HarmonyLinkLib.h" diff --git a/HarmonyLinkLib/include/Enums/EDevice.h b/HarmonyLinkLib/include/Enums/EDevice.h index 31f9bfe..f49c7ec 100644 --- a/HarmonyLinkLib/include/Enums/EDevice.h +++ b/HarmonyLinkLib/include/Enums/EDevice.h @@ -21,6 +21,7 @@ namespace HarmonyLinkLib { enum class EDevice : uint8_t { + UNKNOWN, DESKTOP, LAPTOP, HANDHELD, diff --git a/HarmonyLinkLib/include/Enums/EPlatform.h b/HarmonyLinkLib/include/Enums/EPlatform.h index 66697ee..ffa2be7 100644 --- a/HarmonyLinkLib/include/Enums/EPlatform.h +++ b/HarmonyLinkLib/include/Enums/EPlatform.h @@ -21,6 +21,7 @@ namespace HarmonyLinkLib { enum class EPlatform : uint8_t { + UNKNOWN, WINDOWS, LINUX, MAC, diff --git a/HarmonyLinkLib/include/Enums/ESteamDeck.h b/HarmonyLinkLib/include/Enums/ESteamDeck.h new file mode 100644 index 0000000..9fbad64 --- /dev/null +++ b/HarmonyLinkLib/include/Enums/ESteamDeck.h @@ -0,0 +1,29 @@ +// Copyright (c) 2024 Jordon Brooks +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +// Enum class for representing different types of devices +namespace HarmonyLinkLib +{ + enum class ESteamDeck : uint8_t + { + NONE, // Device is not a steam deck + UNKNOWN, // Device is a steam deck but model cannot be determined + LCD, + OLED, + }; +} diff --git a/HarmonyLinkLib/include/Structs/FDevice.h b/HarmonyLinkLib/include/Structs/FDevice.h index 50a1a5c..b574d6a 100644 --- a/HarmonyLinkLib/include/Structs/FDevice.h +++ b/HarmonyLinkLib/include/Structs/FDevice.h @@ -18,13 +18,15 @@ #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; - EDevice device; + EPlatform platform = EPlatform::UNKNOWN; + EDevice device = EDevice::UNKNOWN; + ESteamDeck steam_deck_model = ESteamDeck::NONE; }; } diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp index 2f5d6fc..735eeab 100644 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp +++ b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include "Utilities.h" #include "WineUtilities.h" @@ -169,51 +171,64 @@ namespace HarmonyLinkLib new_device.device = EDevice::LAPTOP; } - if (is_steam_deck_detected(new_device)) { + 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 - bool IPlatformUtilities::is_steam_deck_detected(const FDevice& device) { - + 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) { - return true; + if (device.device == EDevice::STEAM_DECK && device.steam_deck_model != ESteamDeck::NONE) { + return device.steam_deck_model; } - // Check for Steam Deck by OS version - if (const std::shared_ptr version = get_os_version()) { - if (version->variant_id == "steamdeck" && version->name == "SteamOS") { - return true; - } + 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 { - wprintf(L"OS version information not available.\n"); - } - - // Set of known Steam Deck CPU model names - const std::set steam_deck_models = { - "amd custom apu 0405" // LCD Steam Deck - "amd custom apu 0932", // OLED Steam Deck - }; - - // Check for Steam Deck by CPU model name - if (const std::shared_ptr cpu_info = get_cpu_info()) { - const FString cpu_model_lower = FString::to_lower(cpu_info->Model_Name); - for (const auto& model : steam_deck_models) { - if (cpu_model_lower == FString::to_lower(model.c_str())) { - wprintf(L"Steam Deck detected by CPU model name.\n"); - return true; + // 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"CPU information not available.\n"); + else + { + wprintf(L"OS version information not available.\n"); + } } - wprintf(L"Device is not a Steam Deck.\n"); - - return false; + return steam_deck_model; } bool IPlatformUtilities::is_connected_to_ac() diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h index 420edef..e6f034f 100644 --- a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h +++ b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h @@ -14,6 +14,7 @@ #pragma once +#include "Enums/ESteamDeck.h" #include "Structs/FBattery.h" #include "Structs/FCPUInfo.h" #include "Structs/FDevice.h" @@ -50,7 +51,7 @@ namespace HarmonyLinkLib //virtual bool get_is_ethernet_connected() = 0; //virtual bool get_is_external_input_detected() = 0; - bool is_steam_deck_detected(const FDevice& device); + ESteamDeck detect_steam_deck(const FDevice& device); bool is_connected_to_ac(); bool is_charging();