Keep screen on during gameplay + ESP32 bridge design notes

GameScreen: add FLAG_KEEP_SCREEN_ON while a game is active. Keeps the
system out of the deeper sleep states that aggravate OTG selective-suspend
on Samsung, where the 8BitDo adapter otherwise drops every 60-120 seconds.
Cleared on dispose so other screens are unaffected.

docs: drop a design sketch for a DIY Joy-Con bridge built on an original
ESP32 or Raspberry Pi Pico W. Covers the two architectures (fully
wireless via BT Classic host + BLE peripheral, or wired hybrid via
BT Classic host + USB-CDC serial), the Joy-Con init subcommand
requirement, a proposed wire protocol for the serial path, and the
changes we'd make app-side to consume it. Also captures the dongle
rabbit hole we went through so future-us doesn't repeat the same
experiments.

Notes that Bluepad32 already implements BT Classic HID host with
first-class Joy-Con support on original ESP32 and Pico W, which
shrinks the firmware side considerably. Also warns explicitly against
ESP32-S3 for this project — despite being the obvious "newer, better"
ESP32, it is BLE-only and cannot pair with Joy-Cons (BR/EDR-only).
This commit is contained in:
2026-04-11 19:35:31 -04:00
parent 31f7bd8904
commit 2e1c80b7c2
2 changed files with 369 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
package com.lazy.emulate.ui.screens.game
import android.app.Activity
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Handler
@@ -7,6 +8,7 @@ import android.os.Looper
import android.view.PixelCopy
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.WindowManager
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -109,6 +111,17 @@ fun GameScreen(
ControllerLayout.defaultForConsole(game.consoleType)
}
// Keep the screen on while a game is on-screen. This also keeps the system out of the
// deeper sleep / power-saving states that aggravate USB OTG selective-suspend on
// Samsung devices, where the adapter drops every ~60-120 seconds otherwise.
DisposableEffect(Unit) {
val window = (context as? Activity)?.window
window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
onDispose {
window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
DisposableEffect(game.id) {
val loaded = EmulationEngine.startGame(context, game.consoleType, game.romPath)
if (loaded != null) {