mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-23 19:25:35 +08:00
manage overlay cursor input/clipping and internal frame processing in a better way
This commit is contained in:
parent
1518075b17
commit
4d2e14be3f
@ -144,6 +144,11 @@ class Steam_Overlay
|
|||||||
bool overlay_state_changed;
|
bool overlay_state_changed;
|
||||||
|
|
||||||
std::atomic<bool> i_have_lobby;
|
std::atomic<bool> i_have_lobby;
|
||||||
|
|
||||||
|
// changed each time a notification is posted or overlay is shown/hidden
|
||||||
|
std::atomic_uint32_t renderer_frame_processing_requests = 0;
|
||||||
|
// changed only when overlay is shown/hidden, true means overlay is shown
|
||||||
|
std::atomic_bool obscure_cursor_requests = false;
|
||||||
|
|
||||||
constexpr static const int renderer_detector_polling_ms = 100;
|
constexpr static const int renderer_detector_polling_ms = 100;
|
||||||
std::future<InGameOverlay::RendererHook_t *> future_renderer{};
|
std::future<InGameOverlay::RendererHook_t *> future_renderer{};
|
||||||
@ -187,7 +192,8 @@ class Steam_Overlay
|
|||||||
void load_audio();
|
void load_audio();
|
||||||
|
|
||||||
void overlay_state_hook(bool ready);
|
void overlay_state_hook(bool ready);
|
||||||
void allow_renderer_frame_processing(bool state);
|
void allow_renderer_frame_processing(bool state, bool cleaning_up_overlay = false);
|
||||||
|
void obscure_cursor_input(bool state);
|
||||||
|
|
||||||
void overlay_proc();
|
void overlay_proc();
|
||||||
|
|
||||||
|
@ -418,24 +418,41 @@ bool Steam_Overlay::open_overlay_hook(bool toggle)
|
|||||||
return show_overlay;
|
return show_overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Steam_Overlay::allow_renderer_frame_processing(bool state)
|
void Steam_Overlay::allow_renderer_frame_processing(bool state, bool cleaning_up_overlay)
|
||||||
{
|
{
|
||||||
// this is very important internally it calls the necessary fuctions
|
// this is very important internally it calls the necessary fuctions
|
||||||
// to properly update ImGui window size on the next overlay_proc() call
|
// to properly update ImGui window size on the next overlay_proc() call
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
// clip the cursor
|
auto new_val = ++renderer_frame_processing_requests;
|
||||||
_renderer->HideAppInputs(true);
|
if (new_val == 1) { // only take an action on first request
|
||||||
// allow internal frmae processing
|
// allow internal frmae processing
|
||||||
_renderer->HideOverlayInputs(false);
|
_renderer->HideOverlayInputs(false);
|
||||||
PRINT_DEBUG("Steam_Overlay::allow_renderer_frame_processing enabled frame processing\n");
|
PRINT_DEBUG("Steam_Overlay::allow_renderer_frame_processing enabled frame processing (count=%u)\n", new_val);
|
||||||
} else if (notifications.empty() && !show_overlay) {
|
}
|
||||||
// don't clip the cursor
|
|
||||||
_renderer->HideAppInputs(false);
|
|
||||||
// only stop internal frame processing when our state flag == false, and we don't have notifications
|
|
||||||
_renderer->HideOverlayInputs(true);
|
|
||||||
PRINT_DEBUG("Steam_Overlay::allow_renderer_frame_processing disabled frame processing\n");
|
|
||||||
} else {
|
} else {
|
||||||
PRINT_DEBUG("Steam_Overlay::allow_renderer_frame_processing will not disable frame processing, notifications count=%zu, show overlay=%i\n", notifications.size(), (int)show_overlay);
|
if (renderer_frame_processing_requests > 0) {
|
||||||
|
auto new_val = --renderer_frame_processing_requests;
|
||||||
|
if (!new_val || cleaning_up_overlay) { // only take an action when the requests reach 0 or by force
|
||||||
|
_renderer->HideOverlayInputs(true);
|
||||||
|
PRINT_DEBUG("Steam_Overlay::allow_renderer_frame_processing disabled frame processing (count=%u, force=%i)\n", new_val, (int)cleaning_up_overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Steam_Overlay::obscure_cursor_input(bool state) {
|
||||||
|
bool opposite_request = !state;
|
||||||
|
if (obscure_cursor_requests.compare_exchange_weak(opposite_request, state)) { // if we have the opposite state
|
||||||
|
if (state) {
|
||||||
|
// clip the cursor
|
||||||
|
_renderer->HideAppInputs(true);
|
||||||
|
PRINT_DEBUG("Steam_Overlay::obscure_cursor_input obscured app input\n");
|
||||||
|
} else {
|
||||||
|
// restore the old cursor
|
||||||
|
_renderer->HideAppInputs(false);
|
||||||
|
PRINT_DEBUG("Steam_Overlay::obscure_cursor_input restored app input\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,7 +540,7 @@ int find_free_notification_id(std::vector<Notification> const& notifications)
|
|||||||
|
|
||||||
bool Steam_Overlay::submit_notification(notification_type type, const std::string &msg, std::pair<const Friend, friend_window_state> *frd, const std::weak_ptr<uint64_t> &icon)
|
bool Steam_Overlay::submit_notification(notification_type type, const std::string &msg, std::pair<const Friend, friend_window_state> *frd, const std::weak_ptr<uint64_t> &icon)
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Steam_Overlay::submit_notification %i '%s'\n", (int)type, msg.c_str());
|
PRINT_DEBUG("Steam_Overlay::submit_notification %i\n", (int)type);
|
||||||
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
||||||
if (!Ready()) return false;
|
if (!Ready()) return false;
|
||||||
|
|
||||||
@ -542,8 +559,6 @@ bool Steam_Overlay::submit_notification(notification_type type, const std::strin
|
|||||||
notif.icon = icon;
|
notif.icon = icon;
|
||||||
|
|
||||||
notifications.emplace_back(notif);
|
notifications.emplace_back(notif);
|
||||||
|
|
||||||
PRINT_DEBUG("Steam_Overlay::submit_notification enabling frame processing to show notification\n");
|
|
||||||
Steam_Overlay::allow_renderer_frame_processing(true);
|
Steam_Overlay::allow_renderer_frame_processing(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -906,8 +921,13 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// erase all notifications whose visible time exceeded the max
|
// erase all notifications whose visible time exceeded the max
|
||||||
notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [&now](Notification &item) {
|
notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [this, &now](Notification &item) {
|
||||||
return (now - item.start_time) > Notification::show_time;
|
if ((now - item.start_time) > Notification::show_time) {
|
||||||
|
PRINT_DEBUG("Steam_Overlay::build_notifications will disable frame processing after removing a notification\n");
|
||||||
|
allow_renderer_frame_processing(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}), notifications.end());
|
}), notifications.end());
|
||||||
|
|
||||||
if (!friend_actions_temp.empty()) {
|
if (!friend_actions_temp.empty()) {
|
||||||
@ -978,13 +998,6 @@ void Steam_Overlay::overlay_proc()
|
|||||||
ImGui::PushFont(font_notif);
|
ImGui::PushFont(font_notif);
|
||||||
build_notifications(io.DisplaySize.x, io.DisplaySize.y);
|
build_notifications(io.DisplaySize.x, io.DisplaySize.y);
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
|
|
||||||
// after showing all notifications, and if we won't show the overlay
|
|
||||||
// then disable frame rendering
|
|
||||||
if (notifications.empty() && !show_overlay) {
|
|
||||||
PRINT_DEBUG("Steam_Overlay::overlay_proc disabled frame processing (no request to show overlay and 0 notifications)\n");
|
|
||||||
Steam_Overlay::allow_renderer_frame_processing(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************** exit early if we shouldn't show the overlay
|
// ******************** exit early if we shouldn't show the overlay
|
||||||
@ -1321,8 +1334,16 @@ void Steam_Overlay::UnSetupOverlay()
|
|||||||
if (setup_overlay_called.compare_exchange_weak(already_called, false)) {
|
if (setup_overlay_called.compare_exchange_weak(already_called, false)) {
|
||||||
is_ready = false;
|
is_ready = false;
|
||||||
|
|
||||||
// stop internal frame processing
|
// stop internal frame processing & restore cursor
|
||||||
if (_renderer) _renderer->HideOverlayInputs(true);
|
if (_renderer) {
|
||||||
|
allow_renderer_frame_processing(false, true);
|
||||||
|
obscure_cursor_input(false);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// this hacky solution just sets it to an empty function
|
||||||
|
_renderer->OverlayHookReady = [](InGameOverlay::OverlayHookState state) {};
|
||||||
|
}
|
||||||
|
|
||||||
// allow the future_renderer thread to exit if needed
|
// allow the future_renderer thread to exit if needed
|
||||||
// std::this_thread::sleep_for(std::chrono::milliseconds((int)(renderer_detector_polling_ms * 1.3f)));
|
// std::this_thread::sleep_for(std::chrono::milliseconds((int)(renderer_detector_polling_ms * 1.3f)));
|
||||||
@ -1333,12 +1354,13 @@ void Steam_Overlay::UnSetupOverlay()
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (_renderer) {
|
if (_renderer) {
|
||||||
|
PRINT_DEBUG("Steam_Overlay::UnSetupOverlay will free any images resources\n");
|
||||||
for (auto &ach : achievements) {
|
for (auto &ach : achievements) {
|
||||||
if (!ach.icon.expired()) _renderer->ReleaseImageResource(ach.icon);
|
if (!ach.icon.expired()) _renderer->ReleaseImageResource(ach.icon);
|
||||||
if (!ach.icon_gray.expired()) _renderer->ReleaseImageResource(ach.icon_gray);
|
if (!ach.icon_gray.expired()) _renderer->ReleaseImageResource(ach.icon_gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer = nullptr;
|
_renderer = nullptr;
|
||||||
PRINT_DEBUG("Steam_Overlay::UnSetupOverlay freed all images\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1425,6 +1447,7 @@ void Steam_Overlay::ShowOverlay(bool state)
|
|||||||
io.MouseDrawCursor = state;
|
io.MouseDrawCursor = state;
|
||||||
|
|
||||||
Steam_Overlay::allow_renderer_frame_processing(state);
|
Steam_Overlay::allow_renderer_frame_processing(state);
|
||||||
|
Steam_Overlay::obscure_cursor_input(state);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user