for the overlay:
* reduce code duplication * avoid bypassing local_storage when loading sounds * avoid alloating sound buffers via new-delete, use std::vector * clear/reset all global objects on destroy
This commit is contained in:
parent
048b9a94cd
commit
9fe55f2e81
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
* **[breaking]** introduced a new config file `enable_experimental_overlay.EXAMPLE.txt`, this deprecates the config file `disable_overlay.txt`
|
* **[breaking]** introduced a new config file `enable_experimental_overlay.txt`, which deprecates the config file `disable_overlay.txt`
|
||||||
in many occasions this feature was a source of crashes, so it's better to make it an opt-in option.
|
in many occasions this feature was a source of crashes, so it's better to make it an opt-in option.
|
||||||
otherwise, the `experimental` and `Cold Client` builds of the emu will crash on startup by default for some apps/games
|
otherwise, the `experimental` and `Cold Client` builds of the emu will crash by default on startup for some apps/games
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ int Local_Storage::store_data_settings(std::string file, const char *data, unsig
|
|||||||
|
|
||||||
int Local_Storage::get_file_data(const std::string &full_path, char *data, unsigned int max_length, unsigned int offset)
|
int Local_Storage::get_file_data(const std::string &full_path, char *data, unsigned int max_length, unsigned int offset)
|
||||||
{
|
{
|
||||||
std::ifstream myfile;
|
std::ifstream myfile{};
|
||||||
myfile.open(utf8_decode(full_path), std::ios::binary | std::ios::in);
|
myfile.open(utf8_decode(full_path), std::ios::binary | std::ios::in);
|
||||||
if (!myfile.is_open()) return -1;
|
if (!myfile.is_open()) return -1;
|
||||||
|
|
||||||
|
@ -215,8 +215,7 @@ class Steam_Overlay
|
|||||||
|
|
||||||
bool open_overlay_hook(bool toggle);
|
bool open_overlay_hook(bool toggle);
|
||||||
|
|
||||||
bool try_load_ach_icon(Overlay_Achievement &ach);
|
bool try_load_ach_icon(Overlay_Achievement &ach, bool achieved);
|
||||||
bool try_load_ach_gray_icon(Overlay_Achievement &ach);
|
|
||||||
|
|
||||||
void overlay_render_proc();
|
void overlay_render_proc();
|
||||||
void render_main_window();
|
void render_main_window();
|
||||||
|
@ -72,8 +72,10 @@ static ImFont *font_notif{};
|
|||||||
static std::recursive_mutex overlay_mutex{};
|
static std::recursive_mutex overlay_mutex{};
|
||||||
static std::atomic<bool> setup_overlay_called = false;
|
static std::atomic<bool> setup_overlay_called = false;
|
||||||
|
|
||||||
static char *notif_achievement_wav_custom{};
|
static std::map<std::string, std::vector<char>> wav_files{
|
||||||
static char *notif_invite_wav_custom{};
|
{ "overlay_achievement_notification.wav", std::vector<char>{} },
|
||||||
|
{ "overlay_friend_notification.wav", std::vector<char>{} },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ListBoxHeader() is deprecated and inlined inside <imgui.h>
|
// ListBoxHeader() is deprecated and inlined inside <imgui.h>
|
||||||
@ -229,9 +231,7 @@ void Steam_Overlay::renderer_hook_init_thread()
|
|||||||
// note: make sure to load all relevant strings before creating the font(s), otherwise some glyphs ranges will be missing
|
// note: make sure to load all relevant strings before creating the font(s), otherwise some glyphs ranges will be missing
|
||||||
void Steam_Overlay::create_fonts()
|
void Steam_Overlay::create_fonts()
|
||||||
{
|
{
|
||||||
static std::atomic<bool> create_fonts_called = false;
|
PRINT_DEBUG_ENTRY();
|
||||||
bool not_created_yet = false;
|
|
||||||
if (!create_fonts_called.compare_exchange_weak(not_created_yet, true)) return;
|
|
||||||
|
|
||||||
// disable rounding the texture height to the next power of two
|
// disable rounding the texture height to the next power of two
|
||||||
// see this: https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#4-font-atlas-texture-fails-to-upload-to-gpu
|
// see this: https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#4-font-atlas-texture-fails-to-upload-to-gpu
|
||||||
@ -317,39 +317,24 @@ void Steam_Overlay::create_fonts()
|
|||||||
|
|
||||||
void Steam_Overlay::load_audio()
|
void Steam_Overlay::load_audio()
|
||||||
{
|
{
|
||||||
std::string file_path{};
|
PRINT_DEBUG_ENTRY();
|
||||||
std::string file_name{};
|
|
||||||
unsigned long long file_size;
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (auto &kv : wav_files) {
|
||||||
if (i == 0) file_name = "overlay_achievement_notification.wav";
|
std::string file_path{};
|
||||||
if (i == 1) file_name = "overlay_friend_notification.wav";
|
unsigned int file_size{};
|
||||||
|
|
||||||
file_path = Local_Storage::get_game_settings_path() + file_name;
|
// try local location first, then try global location
|
||||||
file_size = file_size_(file_path);
|
for (const auto &settings_path : { Local_Storage::get_game_settings_path(), local_storage->get_global_settings_path() }) {
|
||||||
if (!file_size) {
|
file_path = settings_path + kv.first;
|
||||||
file_path = local_storage->get_global_settings_path() + file_name;
|
|
||||||
file_size = file_size_(file_path);
|
file_size = file_size_(file_path);
|
||||||
|
if (file_size) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_size) {
|
if (file_size) {
|
||||||
std::ifstream myfile;
|
kv.second.assign(file_size, 0);
|
||||||
myfile.open(utf8_decode(file_path), std::ios::binary | std::ios::in);
|
Local_Storage::get_file_data(file_path, (char *)&kv.second[0], file_size);
|
||||||
if (myfile.is_open()) {
|
} else {
|
||||||
myfile.seekg (0, myfile.end);
|
kv.second.clear();
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (i == 1) {
|
|
||||||
notif_invite_wav_custom = new char [length];
|
|
||||||
myfile.read (notif_invite_wav_custom, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
myfile.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,7 +394,7 @@ void Steam_Overlay::initial_load_achievements_icons()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try_load_ach_icon(ach);
|
try_load_ach_icon(ach, true);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
||||||
@ -419,7 +404,7 @@ void Steam_Overlay::initial_load_achievements_icons()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try_load_ach_gray_icon(ach);
|
try_load_ach_icon(ach, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
||||||
@ -535,8 +520,9 @@ void Steam_Overlay::notify_sound_user_invite(friend_window_state& friend_state)
|
|||||||
if (!(friend_state.window_state & window_state_show) || !show_overlay) {
|
if (!(friend_state.window_state & window_state_show) || !show_overlay) {
|
||||||
friend_state.window_state |= window_state_need_attention;
|
friend_state.window_state |= window_state_need_attention;
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
if (notif_invite_wav_custom) {
|
auto wav_data = wav_files.find("overlay_friend_notification.wav");
|
||||||
PlaySoundA((LPCSTR)notif_invite_wav_custom, NULL, SND_ASYNC | SND_MEMORY);
|
if (wav_files.end() != wav_data && wav_data->second.size()) {
|
||||||
|
PlaySoundA((LPCSTR)&wav_data->second[0], NULL, SND_ASYNC | SND_MEMORY);
|
||||||
} else {
|
} else {
|
||||||
PlaySoundA((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
PlaySoundA((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
||||||
}
|
}
|
||||||
@ -550,8 +536,9 @@ void Steam_Overlay::notify_sound_user_achievement()
|
|||||||
|
|
||||||
if (!show_overlay) {
|
if (!show_overlay) {
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
if (notif_achievement_wav_custom) {
|
auto wav_data = wav_files.find("overlay_achievement_notification.wav");
|
||||||
PlaySoundA((LPCSTR)notif_achievement_wav_custom, NULL, SND_ASYNC | SND_MEMORY);
|
if (wav_files.end() != wav_data && wav_data->second.size()) {
|
||||||
|
PlaySoundA((LPCSTR)&wav_data->second[0], NULL, SND_ASYNC | SND_MEMORY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -560,8 +547,9 @@ void Steam_Overlay::notify_sound_user_achievement()
|
|||||||
void Steam_Overlay::notify_sound_auto_accept_friend_invite()
|
void Steam_Overlay::notify_sound_auto_accept_friend_invite()
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
if (notif_invite_wav_custom) {
|
auto wav_data = wav_files.find("overlay_friend_notification.wav");
|
||||||
PlaySoundA((LPCSTR)notif_invite_wav_custom, NULL, SND_ASYNC | SND_MEMORY);
|
if (wav_files.end() != wav_data && wav_data->second.size()) {
|
||||||
|
PlaySoundA((LPCSTR)&wav_data->second[0], NULL, SND_ASYNC | SND_MEMORY);
|
||||||
} else {
|
} else {
|
||||||
PlaySoundA((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
PlaySoundA((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
||||||
}
|
}
|
||||||
@ -1093,60 +1081,38 @@ void Steam_Overlay::invite_friend(uint64 friend_id, class Steam_Friends* steamFr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Steam_Overlay::try_load_ach_icon(Overlay_Achievement &ach)
|
bool Steam_Overlay::try_load_ach_icon(Overlay_Achievement &ach, bool achieved)
|
||||||
{
|
{
|
||||||
if (!_renderer) return false;
|
if (!_renderer) return false;
|
||||||
if (!ach.icon.expired()) return true;
|
|
||||||
|
|
||||||
if (ach.icon_load_trials && ach.icon_name.size()) {
|
std::weak_ptr<uint64_t> &icon_rsrc = achieved ? ach.icon : ach.icon_gray;
|
||||||
--ach.icon_load_trials;
|
const std::string &icon_name = achieved ? ach.icon_name : ach.icon_gray_name;
|
||||||
std::string file_path = std::move(Local_Storage::get_game_settings_path() + ach.icon_name);
|
uint8_t &load_trials = achieved ? ach.icon_load_trials : ach.icon_gray_load_trials;
|
||||||
unsigned long long file_size = file_size_(file_path);
|
|
||||||
|
if (!icon_rsrc.expired()) return true;
|
||||||
|
|
||||||
|
if (load_trials && icon_name.size()) {
|
||||||
|
--load_trials;
|
||||||
|
std::string file_path(Local_Storage::get_game_settings_path() + icon_name);
|
||||||
|
unsigned int file_size = file_size_(file_path);
|
||||||
if (!file_size) {
|
if (!file_size) {
|
||||||
file_path = std::move(Local_Storage::get_game_settings_path() + Steam_Overlay::ACH_FALLBACK_DIR + "/" + ach.icon_name);
|
file_path = Local_Storage::get_game_settings_path() + Steam_Overlay::ACH_FALLBACK_DIR + "/" + icon_name;
|
||||||
file_size = file_size_(file_path);
|
file_size = file_size_(file_path);
|
||||||
}
|
}
|
||||||
if (file_size) {
|
if (file_size) {
|
||||||
std::string img = Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size);
|
std::string img = Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size);
|
||||||
if (img.length() > 0) {
|
if (img.length() > 0) {
|
||||||
ach.icon = _renderer->CreateImageResource(
|
icon_rsrc = _renderer->CreateImageResource(
|
||||||
(void*)img.c_str(),
|
(void*)img.c_str(),
|
||||||
settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size);
|
settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size);
|
||||||
if (!ach.icon.expired()) ach.icon_load_trials = Overlay_Achievement::ICON_LOAD_MAX_TRIALS;
|
|
||||||
PRINT_DEBUG("'%s' (result=%i)", ach.name.c_str(), (int)!ach.icon.expired());
|
if (!icon_rsrc.expired()) load_trials = Overlay_Achievement::ICON_LOAD_MAX_TRIALS;
|
||||||
|
PRINT_DEBUG("'%s' (result=%i)", ach.name.c_str(), (int)!icon_rsrc.expired());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !ach.icon.expired();
|
return !icon_rsrc.expired();
|
||||||
}
|
|
||||||
|
|
||||||
bool Steam_Overlay::try_load_ach_gray_icon(Overlay_Achievement &ach)
|
|
||||||
{
|
|
||||||
if (!_renderer) return false;
|
|
||||||
if (!ach.icon_gray.expired()) return true;
|
|
||||||
|
|
||||||
if (ach.icon_gray_load_trials && ach.icon_gray_name.size()) {
|
|
||||||
--ach.icon_gray_load_trials;
|
|
||||||
std::string file_path = std::move(Local_Storage::get_game_settings_path() + ach.icon_gray_name);
|
|
||||||
unsigned long long file_size = file_size_(file_path);
|
|
||||||
if (!file_size) {
|
|
||||||
file_path = std::move(Local_Storage::get_game_settings_path() + Steam_Overlay::ACH_FALLBACK_DIR + "/" + ach.icon_gray_name);
|
|
||||||
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) {
|
|
||||||
ach.icon_gray = _renderer->CreateImageResource(
|
|
||||||
(void*)img.c_str(),
|
|
||||||
settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size);
|
|
||||||
if (!ach.icon_gray.expired()) ach.icon_gray_load_trials = Overlay_Achievement::ICON_LOAD_MAX_TRIALS;
|
|
||||||
PRINT_DEBUG("'%s' (result=%i)", ach.name.c_str(), (int)!ach.icon_gray.expired());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return !ach.icon_gray.expired();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to make this function as short as possible or it might affect game's fps.
|
// Try to make this function as short as possible or it might affect game's fps.
|
||||||
@ -1326,8 +1292,8 @@ void Steam_Overlay::render_main_window()
|
|||||||
bool achieved = x.achieved;
|
bool achieved = x.achieved;
|
||||||
bool hidden = x.hidden && !achieved;
|
bool hidden = x.hidden && !achieved;
|
||||||
|
|
||||||
try_load_ach_icon(x);
|
try_load_ach_icon(x, true);
|
||||||
try_load_ach_gray_icon(x);
|
try_load_ach_icon(x, false);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
@ -1672,13 +1638,13 @@ void Steam_Overlay::UnSetupOverlay()
|
|||||||
|
|
||||||
// stop internal frame processing & restore cursor
|
// stop internal frame processing & restore cursor
|
||||||
if (_renderer) {
|
if (_renderer) {
|
||||||
allow_renderer_frame_processing(false, true);
|
|
||||||
obscure_game_input(false);
|
|
||||||
|
|
||||||
// for some reason this gets triggered after the overlay instance has been destroyed
|
// for some reason this gets triggered after the overlay instance has been destroyed
|
||||||
// I assume because the game de-initializes DX later after closing Steam APIs
|
// I assume because the game de-initializes DX later after closing Steam APIs
|
||||||
// this hacky solution just sets it to an empty function
|
// this hacky solution just sets it to an empty function
|
||||||
_renderer->OverlayHookReady = [](InGameOverlay::OverlayHookState state) {};
|
_renderer->OverlayHookReady = [](InGameOverlay::OverlayHookState state){};
|
||||||
|
|
||||||
|
allow_renderer_frame_processing(false, true);
|
||||||
|
obscure_game_input(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow the future_renderer thread to exit if needed
|
// allow the future_renderer thread to exit if needed
|
||||||
@ -1690,7 +1656,7 @@ void Steam_Overlay::UnSetupOverlay()
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (_renderer) {
|
if (_renderer) {
|
||||||
PRINT_DEBUG("will free any images resources");
|
PRINT_DEBUG("free-ing any images resources");
|
||||||
for (auto &ach : achievements) {
|
for (auto &ach : achievements) {
|
||||||
if (!ach.icon.expired()) {
|
if (!ach.icon.expired()) {
|
||||||
_renderer->ReleaseImageResource(ach.icon);
|
_renderer->ReleaseImageResource(ach.icon);
|
||||||
@ -1706,14 +1672,13 @@ void Steam_Overlay::UnSetupOverlay()
|
|||||||
_renderer = nullptr;
|
_renderer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notif_achievement_wav_custom) {
|
// cleanup everything
|
||||||
delete[] notif_achievement_wav_custom;
|
fonts_atlas.Clear();
|
||||||
notif_achievement_wav_custom = nullptr;
|
memset(&fonts_atlas, 0, sizeof(fonts_atlas));
|
||||||
}
|
font_default = nullptr;
|
||||||
|
font_notif = nullptr;
|
||||||
if (notif_invite_wav_custom) {
|
for (auto &kv : wav_files) {
|
||||||
delete[] notif_invite_wav_custom;
|
kv.second.clear();
|
||||||
notif_invite_wav_custom = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1908,7 +1873,7 @@ void Steam_Overlay::AddAchievementNotification(nlohmann::json const& ach)
|
|||||||
|
|
||||||
if (!settings->disable_overlay_achievement_notification) {
|
if (!settings->disable_overlay_achievement_notification) {
|
||||||
for (auto found_ach : found_achs) {
|
for (auto found_ach : found_achs) {
|
||||||
try_load_ach_icon(*found_ach);
|
try_load_ach_icon(*found_ach, true);
|
||||||
submit_notification(
|
submit_notification(
|
||||||
notification_type_achievement,
|
notification_type_achievement,
|
||||||
ach.value("displayName", std::string()) + "\n" + ach.value("description", std::string()),
|
ach.value("displayName", std::string()) + "\n" + ach.value("description", std::string()),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user