From 2b7858f9b7aaed9a5b12ffde80a2d0ffb1574a10 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 3 Apr 2026 12:57:01 -0700
Subject: [PATCH] Updated touch control visibility rules
Show the touch controls when starting on a mobile device without a controller plugged in.
Show the touch controls out if touch input is provided.
Fade the touch controls out if there has been no touch input for 10 seconds.
---
game/game.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++-------
game/game.h | 12 +++++-
2 files changed, 101 insertions(+), 15 deletions(-)
diff --git a/game/game.cpp b/game/game.cpp
index f4392fde..1fc314e6 100644
--- a/game/game.cpp
+++ b/game/game.cpp
@@ -196,6 +196,16 @@ GamePanelDelegate::OnShow()
{
int i;
+ SDL_AddEventWatch(EventWatch, this);
+
+ m_lastTouch = SDL_GetTicks();
+
+ if ((IsPhone() || IsTablet()) && GetNumGamepads() == 0) {
+ ShowTouchControls();
+ } else {
+ HideTouchControls();
+ }
+
UpdateZoom();
SetSteamTimelineMode(STEAM_TIMELINE_PLAYING);
@@ -261,6 +271,79 @@ GamePanelDelegate::OnHide()
delete gSprites[gNumSprites-1];
sound->HaltSound();
+
+ SDL_RemoveEventWatch(EventWatch, this);
+}
+
+bool SDLCALL
+GamePanelDelegate::EventWatch(void *userdata, SDL_Event *event)
+{
+ GamePanelDelegate *delegate = static_cast<GamePanelDelegate*>(userdata);
+ delegate->ObserveEvent(event);
+ return true;
+}
+
+void
+GamePanelDelegate::ObserveEvent(const SDL_Event *event)
+{
+ if (event->type == SDL_EVENT_FINGER_DOWN) {
+ ShowTouchControls();
+ } else if (event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ||
+ event->type == SDL_EVENT_WINDOW_SAFE_AREA_CHANGED) {
+ UpdateZoom();
+ }
+}
+
+void
+GamePanelDelegate::ShowTouchControls()
+{
+ if (!m_touchControls) {
+ return;
+ }
+
+ m_lastTouch = SDL_GetTicks();
+
+ if (!m_touchControls->IsShown()) {
+ m_touchFading = false;
+ m_touchControls->SetAlpha(128);
+ m_touchControls->Show();
+ }
+}
+
+void
+GamePanelDelegate::HideTouchControls()
+{
+ if (!m_touchControls) {
+ return;
+ }
+
+ m_touchControls->Hide();
+}
+
+void
+GamePanelDelegate::HandleTouchFading()
+{
+ if (!m_touchControls || !m_touchControls->IsShown()) {
+ return;
+ }
+
+ if (m_touchFading) {
+ const int max = 16;
+ int v = max - m_fadeStep;
+ Uint8 value = (Uint8)(128 * v / max);
+
+ m_touchControls->SetAlpha(value);
+ ++m_fadeStep;
+ if (m_fadeStep > max) {
+ HideTouchControls();
+ }
+ } else {
+ const Uint64 TOUCH_FADE_TIMEOUT = 10 * 1000;
+ if ((SDL_GetTicks() - m_lastTouch) >= TOUCH_FADE_TIMEOUT) {
+ m_touchFading = true;
+ m_fadeStep = 1;
+ }
+ }
}
void
@@ -269,6 +352,13 @@ GamePanelDelegate::OnTick()
int i, j;
SYNC_RESULT syncResult;
+ if (m_state == STATE_PLAYING) {
+ HandleTouchFading();
+ } else {
+ // Don't time out touch while the bonus is showing
+ m_lastTouch = SDL_GetTicks();
+ }
+
switch (m_state) {
case STATE_SHOW_BONUS:
ShowBonus();
@@ -524,20 +614,6 @@ GamePanelDelegate::OnDraw(DRAWLEVEL drawLevel)
StopZoomedDrawing();
}
-bool
-GamePanelDelegate::HandleEvent(const SDL_Event &event)
-{
- if (event.type == SDL_EVENT_FINGER_DOWN) {
- if (m_touchControls) {
- m_touchControls->Show();
- }
- } else if (event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ||
- event.type == SDL_EVENT_WINDOW_SAFE_AREA_CHANGED) {
- UpdateZoom();
- }
- return false;
-}
-
bool
GamePanelDelegate::OnAction(UIBaseElement *sender, const char *action)
{
diff --git a/game/game.h b/game/game.h
index 29004910..eebc70db 100644
--- a/game/game.h
+++ b/game/game.h
@@ -37,10 +37,16 @@ class GamePanelDelegate : public UIPanelDelegate
virtual void OnHide();
virtual void OnTick();
virtual void OnDraw(DRAWLEVEL drawLevel);
- virtual bool HandleEvent(const SDL_Event &event);
virtual bool OnAction(UIBaseElement *sender, const char *action);
+ void ObserveEvent(const SDL_Event *event);
+
protected:
+ static bool SDLCALL EventWatch(void *userdata, SDL_Event *event);
+
+ void ShowTouchControls();
+ void HideTouchControls();
+ void HandleTouchFading();
void UpdateZoom();
void StartZoomUI(const SDL_Rect &rect);
void StopZoomUI();
@@ -109,6 +115,10 @@ class GamePanelDelegate : public UIPanelDelegate
SDL_Texture *m_texture = nullptr;
SDL_Rect m_savedClip;
+
+ Uint64 m_lastTouch;
+ bool m_touchFading;
+ int m_fadeStep;
};
/* ----------------------------------------------------------------- */