From 62a92e5bf650634fdda91cf7da2133e891a4ca99 Mon Sep 17 00:00:00 2001 From: a Date: Fri, 10 Nov 2023 17:25:36 +0200 Subject: [PATCH] (RIN forum) added new release 4 by ce20fdf2 from https://cs.rin.ru/forum/viewtopic.php?p=2933673#p2933673 --- dll/settings.h | 4 + dll/settings_parser.cpp | 11 +- dll/steam_user_stats.h | 16 ++ dll/steam_utils.h | 4 +- .../overlay_appearance.EXAMPLE.txt | 3 +- .../steam_deck.EXAMPLE.txt | 1 + overlay_experimental/steam_overlay.cpp | 145 +++++++++++++++++- overlay_experimental/steam_overlay.h | 5 + 8 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 files_example/steam_settings.EXAMPLE/steam_deck.EXAMPLE.txt diff --git a/dll/settings.h b/dll/settings.h index c3df1e3c..1f7a6602 100644 --- a/dll/settings.h +++ b/dll/settings.h @@ -100,6 +100,7 @@ struct Group_Clans { struct Overlay_Appearance { float font_size = 16.0; + float icon_size = 64.0; }; class Settings { @@ -217,6 +218,9 @@ public: //steamhttp external download support bool http_online = false; + + //steam deck flag + bool steam_deck = false; }; #endif diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 6c0906ae..6d6e7673 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -105,6 +105,10 @@ static void load_overlay_appearance(std::string appearance_filepath, Settings *s float nfont_size = std::stoull(value, NULL, 0); settings_client->overlay_appearance.font_size = nfont_size; settings_server->overlay_appearance.font_size = nfont_size; + } else if (name.compare("Icon_Size") == 0) { + float nicon_size = std::stoull(value, NULL, 0); + settings_client->overlay_appearance.icon_size = nicon_size; + settings_server->overlay_appearance.icon_size = nicon_size; } PRINT_DEBUG("Overlay appearance %s %s\n", name.c_str(), value.c_str()); } catch (...) {} @@ -253,7 +257,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s bool local_save = false; { - char array[33] = {}; + char array[256] = {}; if (Local_Storage::get_file_data(program_path + "local_save.txt", array, sizeof(array) - 1) != -1) { save_path = program_path + Settings::sanitize(array); local_save = true; @@ -366,6 +370,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s } bool steam_offline_mode = false; + bool steam_deck_mode = false; bool steamhttp_online_mode = false; bool disable_networking = false; bool disable_overlay = false; @@ -386,6 +391,8 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s PRINT_DEBUG("steam settings path %s\n", p.c_str()); if (p == "offline.txt") { steam_offline_mode = true; + } else if (p == "steam_deck.txt") { + steam_deck_mode = true; } else if (p == "http_online.txt") { steamhttp_online_mode = true; } else if (p == "disable_networking.txt") { @@ -466,6 +473,8 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s settings_server->warn_local_save = local_save; settings_client->supported_languages = supported_languages; settings_server->supported_languages = supported_languages; + settings_client->steam_deck = steam_deck_mode; + settings_server->steam_deck = steam_deck_mode; settings_client->http_online = steamhttp_online_mode; settings_server->http_online = steamhttp_online_mode; diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index 5eef49ca..5f348c4d 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -597,6 +597,22 @@ int GetAchievementIcon( const char *pchName ) return 0; } +std::string get_achievement_icon_name( const char *pchName, bool pbAchieved ) +{ + if (pchName == nullptr) return ""; + std::lock_guard lock(global_mutex); + + try { + auto it = defined_achievements_find(pchName); + if (it != defined_achievements.end()) { + if (pbAchieved) return it.value()["icon"].get(); + else return it.value()["icon_gray"].get(); + } + } catch (...) {} + + return ""; +} + // Get general attributes for an achievement. Accepts the following keys: // - "name" and "desc" for retrieving the localized achievement name and description (returned in UTF8) diff --git a/dll/steam_utils.h b/dll/steam_utils.h index d229cd33..81e468c7 100644 --- a/dll/steam_utils.h +++ b/dll/steam_utils.h @@ -417,8 +417,8 @@ ESteamIPv6ConnectivityState GetIPv6ConnectivityState( ESteamIPv6ConnectivityProt // returns true if currently running on the Steam Deck device bool IsSteamRunningOnSteamDeck() { - PRINT_DEBUG("%s\n", __FUNCTION__); - return false; + PRINT_DEBUG("%s %i\n", __FUNCTION__, (int)settings->steam_deck); + return settings->steam_deck; } // Opens a floating keyboard over the game content and sends OS keyboard keys directly to the game. diff --git a/files_example/steam_settings.EXAMPLE/overlay_appearance.EXAMPLE.txt b/files_example/steam_settings.EXAMPLE/overlay_appearance.EXAMPLE.txt index fb8fbbfe..811c98ce 100644 --- a/files_example/steam_settings.EXAMPLE/overlay_appearance.EXAMPLE.txt +++ b/files_example/steam_settings.EXAMPLE/overlay_appearance.EXAMPLE.txt @@ -1 +1,2 @@ -Font_Size 16.0 \ No newline at end of file +Font_Size 16.0 +Icon_Size 64.0 \ No newline at end of file diff --git a/files_example/steam_settings.EXAMPLE/steam_deck.EXAMPLE.txt b/files_example/steam_settings.EXAMPLE/steam_deck.EXAMPLE.txt new file mode 100644 index 00000000..c06f8dd0 --- /dev/null +++ b/files_example/steam_settings.EXAMPLE/steam_deck.EXAMPLE.txt @@ -0,0 +1 @@ +Rename this to: steam_deck.txt to pretend steam is running on a steam deck. diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 672fbcd0..21ff3b40 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -101,6 +101,10 @@ int find_free_notification_id(std::vector const& notifications) #endif #include "notification.h" +char *notif_achievement_wav_custom; +char *notif_invite_wav_custom; +bool notif_achievement_wav_custom_inuse = false; +bool notif_invite_wav_custom_inuse = false; void Steam_Overlay::steam_overlay_run_every_runcb(void* object) { @@ -330,7 +334,24 @@ void Steam_Overlay::NotifyUser(friend_window_state& friend_state) { friend_state.window_state |= window_state_need_attention; #ifdef __WINDOWS__ - PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY); + if (notif_invite_wav_custom_inuse) { + PlaySoundA((LPCSTR)notif_invite_wav_custom, NULL, SND_ASYNC | SND_MEMORY); + } else { + PlaySoundA((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY); + } +#endif + } +} + +void Steam_Overlay::NotifyUserAchievement() +{ + if (settings->disable_overlay_achievement_notification) return; + if (!show_overlay) + { +#ifdef __WINDOWS__ + if (notif_achievement_wav_custom_inuse) { + PlaySoundA((LPCSTR)notif_achievement_wav_custom, NULL, SND_ASYNC | SND_MEMORY); + } #endif } } @@ -427,10 +448,21 @@ void Steam_Overlay::AddAchievementNotification(nlohmann::json const& ach) Notification notif; notif.id = id; notif.type = notification_type_achievement; + // Load achievement image + std::string file_path = Local_Storage::get_game_settings_path() + ach["icon"].get(); + unsigned long long file_size = file_size_(file_path); + if (file_size) { + std::string img = Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size); + if (img.length() > 0) { + if (_renderer) notif.icon = _renderer->CreateImageResource((void*)img.c_str(), settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size); + } + } + notif.message = ach["displayName"].get() + "\n" + ach["description"].get(); notif.start_time = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); notifications.emplace_back(notif); + NotifyUserAchievement(); have_notifications = true; } else @@ -690,7 +722,24 @@ void Steam_Overlay::BuildNotifications(int width, int height) switch (it->type) { case notification_type_achievement: - ImGui::TextWrapped("%s", it->message.c_str()); + { + if (!it->icon.expired()) { + ImGui::BeginTable("imgui_table", 2); + ImGui::TableSetupColumn("imgui_table_image", ImGuiTableColumnFlags_WidthFixed, settings->overlay_appearance.icon_size); + ImGui::TableSetupColumn("imgui_table_text"); + ImGui::TableNextRow(ImGuiTableRowFlags_None, settings->overlay_appearance.icon_size); + + ImGui::TableSetColumnIndex(0); + ImGui::Image((ImU64)*it->icon.lock().get(), ImVec2(settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size)); + + ImGui::TableSetColumnIndex(1); + ImGui::TextWrapped("%s", it->message.c_str()); + + ImGui::EndTable(); + } else { + ImGui::TextWrapped("%s", it->message.c_str()); + } + } break; case notification_type_invite: { @@ -826,6 +875,51 @@ void Steam_Overlay::CreateFonts() reset_LastError(); } +void Steam_Overlay::LoadAudio() +{ + std::string file_path; + std::string file_name; + unsigned long long file_size; + + for (int i = 0; i < 2; i++) { + if (i == 0) file_name = "overlay_achievement_notification.wav"; + if (i == 1) file_name = "overlay_friend_notification.wav"; + + file_path = Local_Storage::get_game_settings_path() + file_name; + file_size = file_size_(file_path); + if (!file_size) { + if (settings->local_save.length() > 0) { + file_path = settings->local_save + "/settings/" + file_name; + } else { + file_path = Local_Storage::get_user_appdata_path() + "/settings/" + file_name; + } + file_size = file_size_(file_path); + } + if (file_size) { + std::ifstream myfile; + myfile.open(utf8_decode(file_path), std::ios::binary | std::ios::in); + if (myfile.is_open()) { + myfile.seekg (0, myfile.end); + int length = myfile.tellg(); + myfile.seekg (0, myfile.beg); + + if (i == 0) { + notif_achievement_wav_custom = new char [length]; + myfile.read (notif_achievement_wav_custom, length); + notif_achievement_wav_custom_inuse = true; + } + if (i == 1) { + notif_invite_wav_custom = new char [length]; + myfile.read (notif_invite_wav_custom, length); + notif_invite_wav_custom_inuse = true; + } + + myfile.close(); + } + } + } +} + // Try to make this function as short as possible or it might affect game's fps. void Steam_Overlay::OverlayProc() { @@ -854,7 +948,15 @@ void Steam_Overlay::OverlayProc() bool show = true; - if (ImGui::Begin(translationSteamOverlay[current_language], &show, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus)) + char tmp[TRANSLATION_BUFFER_SIZE]; + snprintf(tmp, sizeof(tmp), translationRenderer[current_language], (_renderer == nullptr ? "Unknown" : _renderer->GetLibraryName().c_str())); + std::string windowTitle; + windowTitle.append(translationSteamOverlay[current_language]); + windowTitle.append(" ("); + windowTitle.append(tmp); + windowTitle.append(")"); + + if (ImGui::Begin(windowTitle.c_str(), &show, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus)) { ImGui::LabelText("##label", translationUserPlaying[current_language], settings->get_local_name(), @@ -862,8 +964,6 @@ void Steam_Overlay::OverlayProc() settings->get_local_game_id().AppID()); ImGui::SameLine(); - ImGui::LabelText("##label", translationRenderer[current_language], (_renderer == nullptr ? "Unknown" : _renderer->GetLibraryName().c_str())); - ImGui::Spacing(); if (ImGui::Button(translationShowAchievements[current_language])) { show_achievements = true; @@ -913,8 +1013,34 @@ void Steam_Overlay::OverlayProc() bool achieved = x.achieved; bool hidden = x.hidden && !achieved; + if (x.icon.expired()) { + std::string file_path = Local_Storage::get_game_settings_path() + x.icon_name; + unsigned long long file_size = file_size_(file_path); + if (file_size) { + std::string img = Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size); + if (img.length() > 0) { + if (_renderer) x.icon = _renderer->CreateImageResource((void*)img.c_str(), settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size); + } + } + } + ImGui::Separator(); - ImGui::Text("%s", x.title.c_str()); + + if (!x.icon.expired()) { + ImGui::BeginTable(x.title.c_str(), 2); + ImGui::TableSetupColumn("imgui_table_image", ImGuiTableColumnFlags_WidthFixed, settings->overlay_appearance.icon_size); + ImGui::TableSetupColumn("imgui_table_text"); + ImGui::TableNextRow(ImGuiTableRowFlags_None, settings->overlay_appearance.icon_size); + + ImGui::TableSetColumnIndex(0); + ImGui::Image((ImU64)*x.icon.lock().get(), ImVec2(settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size)); + + ImGui::TableSetColumnIndex(1); + ImGui::Text("%s", x.title.c_str()); + } else { + ImGui::Text("%s", x.title.c_str()); + } + if (hidden) { ImGui::Text(translationHiddenAchievement[current_language]); } else { @@ -930,6 +1056,9 @@ void Steam_Overlay::OverlayProc() } else { ImGui::TextColored(ImVec4(255, 0, 0, 255), translationNotAchieved[current_language]); } + + if (!x.icon.expired()) ImGui::EndTable(); + ImGui::Separator(); } ImGui::EndChild(); @@ -1084,6 +1213,9 @@ void Steam_Overlay::RunCallbacks() ach.unlock_time = 0; } + if (achieved) ach.icon_name = steamUserStats->get_achievement_icon_name(ach.name.c_str(), true); + else ach.icon_name = steamUserStats->get_achievement_icon_name(ach.name.c_str(), false); + achievements.push_back(ach); } @@ -1096,6 +1228,7 @@ void Steam_Overlay::RunCallbacks() _renderer = future_renderer.get(); PRINT_DEBUG("got renderer %p\n", _renderer); CreateFonts(); + LoadAudio(); } } diff --git a/overlay_experimental/steam_overlay.h b/overlay_experimental/steam_overlay.h index 50f25fda..d2fbae61 100644 --- a/overlay_experimental/steam_overlay.h +++ b/overlay_experimental/steam_overlay.h @@ -68,6 +68,7 @@ struct Notification std::chrono::seconds start_time; std::string message; std::pair* frd; + std::weak_ptr icon; }; struct Overlay_Achievement @@ -75,9 +76,11 @@ struct Overlay_Achievement std::string name; std::string title; std::string description; + std::string icon_name; bool hidden; bool achieved; uint32 unlock_time; + std::weak_ptr icon; }; #ifdef EMU_OVERLAY @@ -142,6 +145,7 @@ class Steam_Overlay bool IHaveLobby(); void NotifyUser(friend_window_state& friend_state); + void NotifyUserAchievement(); // Right click on friend void BuildContextMenu(Friend const& frd, friend_window_state &state); @@ -167,6 +171,7 @@ public: void HookReady(bool ready); void CreateFonts(); + void LoadAudio(); void OverlayProc(); void OpenOverlayInvite(CSteamID lobbyId);