use event system for pause events, pause game when browser tab is hidden on wasm build

This commit is contained in:
ohsqueezy 2023-12-12 12:58:14 -05:00
parent db7e41e470
commit 0767f1f926
2 changed files with 54 additions and 17 deletions

View File

@ -174,6 +174,14 @@ Cakefoot::Cakefoot()
/* Switch volume on */
button.at("volume").press();
#if defined(EMSCRIPTEN)
/* Pause the game when the browser tab is hidden */
if (emscripten_set_visibilitychange_callback(nullptr, false, &respond_to_visibility_change) < 0)
{
sb::Log::log("Failed to enable browser visibility change automatic pause feature", sb::Log::WARN);
}
#endif
}
void Cakefoot::load_audio()
@ -408,22 +416,7 @@ void Cakefoot::set_up_buttons()
pause_plane.texture(pause_texture);
button.at("pause") = sb::Pad<>{pause_plane, configuration()("button", "pause translation"), configuration()("button", "pause scale"), 1.0f};
button.at("pause").on_state_change([&](bool state){
unpaused_timer.off();
run_timer.off();
/* Transition between main theme and menu theme */
if (audio.at("main").playing())
{
audio.at("main").pause();
}
if (audio.at("menu").paused())
{
audio.at("menu").resume();
}
else if (audio.at("menu").fading() || !audio.at("menu").playing())
{
audio.at("menu").play();
}
sb::Delegate::post("pause", false);
});
/* Set up volume button */
@ -831,7 +824,6 @@ void Cakefoot::set_up_hud()
format_clock(configuration()("progress", "quest best")));
label.at("quest best").refresh();
}
}
void Cakefoot::load_vbo()
@ -1773,6 +1765,26 @@ void Cakefoot::respond(SDL_Event& event)
}
}
else if (sb::Delegate::compare(event, "pause") && level_index > 0 && static_cast<std::size_t>(level_index) <= configuration()("levels").size() - 2)
{
unpaused_timer.off();
run_timer.off();
/* Transition between main theme and menu theme */
if (audio.at("main").playing())
{
audio.at("main").pause();
}
if (audio.at("menu").paused())
{
audio.at("menu").resume();
}
else if (audio.at("menu").fading() || !audio.at("menu").playing())
{
audio.at("menu").play();
}
}
else if (sb::Delegate::compare(event, "reconfig"))
{
load_curves();
@ -2430,6 +2442,17 @@ void Cakefoot::update(float timestamp)
sb::Log::gl_errors("at end of update");
}
#if defined(EMSCRIPTEN)
EM_BOOL respond_to_visibility_change(int event_type, const EmscriptenVisibilityChangeEvent* visibility_change_event, void* user_data)
{
if (visibility_change_event->hidden)
{
sb::Delegate::post("pause", false);
}
return true;
}
#endif
int main()
{
Cakefoot game = Cakefoot();

View File

@ -491,6 +491,20 @@ public:
};
#if defined(EMSCRIPTEN)
/*!
* This event handler should be registered with emscripten_set_visibilitychange_callback so it will be called automatically when the
* browser tab is hidden. A pause event will be posted through sb::Delegate::post(const std::string&, bool) when the browser tab is
* hidden.
*
* @param event_type Emscripten's ID for the visibilitychange event
* @param visibility_change_event Emscripten's event object
* @param user_data Emscripten's API allows wser data to be passed, but this is treated as null
* @return True to indicate that the event was consumed by the handler
*/
EM_BOOL respond_to_visibility_change(int event_type, const EmscriptenVisibilityChangeEvent* visibility_change_event, void* user_data);
#endif
/*!
* Create a Cakewalk instance and launch its mainloop.
*