Commit Graph

125 Commits

Author SHA1 Message Date
Shane McGovern 7e2307f58c Use spare CPU cores to remove in-game hitches on low-power devices (#2872)
* Use spare CPU cores to remove in-game hitches on low-power devices

Per-frame game logic and drawing are cheap; the remaining stalls on
low-power handhelds are one-off main-thread hitches from chip SFX/cry
synthesis, RED++ atlas recolouring, image decodes and the require shim.
Move those onto background threads, each with a synchronous fallback so
behaviour is identical when threads are unavailable (POKEPORT_NO_THREAD=1,
no love.thread, worker failure).

Also adds an F3 frame-time overlay and POKEPORT_GAME_PROF headless
profiling to measure these costs.

* Address code review: shared WorkerLane, F3 gating, decode/epoch fixes

- Extract src/core/WorkerLane.lua (worker lifecycle, prioritised lanes,
  per-lane epochs, bounded LRU) and rebuild the SFX and atlas/decode
  prefetchers on it
- Keep decoded sprite sheets in every colour mode (the OBJ palette bake
  re-reads them), skip oversized decodes, and let palette changes drop
  only atlas bakes
- Only bump the SFX render epoch when the channel mix actually changes
- F3 overlay toggle no longer steals the key from rebinding screens or
  player bindings; profilers stop only when a quit really proceeds
- Require fast path: test hook instead of a hot-path counter
- Shared tests/drivers/perf_util.lua; drivers restore their patches

* WorkerLane: no budget leak on duplicate sends, keep priority on requeue

- Lane:pump only counts a job against the in-flight budget once per key
- requeueInflight puts entries back at the head of their own queue, so
  background hints no longer overtake front requests after a bump
- shutdown() keeps a fatally failed worker off
- Hiding the F3 overlay logs one summary line instead of a full block

* F3 overlay: last-120-frame stats, font-sized box, scale on large screens

* Prefetch: skip useless hints, no main-thread fallback, mix check vs worker config

- Don't queue decodes for sprite sheets whose Image and OBJ bake are cached
- Atlas hint is dropped (sync bake at build time) when the worker can't
  decode the tileset itself, instead of decoding on the main thread
- SFX epoch bump compares the live mix with what the worker was last
  configured with, replacing the load-time snapshot

* Sprite decode skip: raw-path cache check, never under RED++

* Gen 2 battles prefetch both parties' cries; sprite skip keyed by raw path

* Prefetch: skip cached tilesets outside RED++, log hint failures once

* Profiler: bench survives F3 hide, frame total excludes vsync; safer SFX pump, ordered requeue, tileset skip respects pending variants

* Profiler counts GPU stalls in present; water void-fill keeps tileset hint; README + test coverage

* Profiler vsync cap: measured cadence via RefreshRate, no per-frame allocation

* Use upstream's chip-worker prewarm for SFX/cries; drop our separate SFX worker

Our extra coverage (Gen 1 common SFX + party cries, both parties' battle
cries, lead move sounds, hit and battle SFX, Gen 2 bench cries) now goes
through ChipAudio.prewarmSfx/prewarmCry and a new Sound.prewarmMove.

* Skip decode hints for composed assets; share move cache key; drop dead demoteAll

* Drop dev-only profiling extras: POKEPORT_JITP hook and perf drivers

* README: name the worker threads POKEPORT_JIT leaves alone

* Profiler: count the pre-present vblank wait as present, log on NX quit

- time PresentSync.waitBeforePresent as "present" (the X11 GLX vblank wait
  lands there), so it is excluded like the wait inside present
- NX quit now emits the PROF summary / overlay line too
- love.quit's scripted check reads FrameProfiler.benchRequested, so
  POKEPORT_GAME_PROF=0 no longer counts as a bench run
- prefetchAtlas skips composed tileset sheets (Assets.isComposed)
- hit sounds defined once in EffectRegistry.HIT_SOUNDS, shared with the
  battle prewarm (each hit still gets its own copy)
- drop redundant obpPaths, dead FrameProfiler.visible and the unused
  Lane:bump requeue mode; restore applyOptions' doc comment
2026-10-12 08:38:45 +01:00
bryanthaboi f8cb71cc00 CLOSES #2862, CLOSES #2863, CLOSES #2864, CLOSES #2865, CLOSES #2866, CLOSES #2867, CLOSES #2868, CLOSES #2871 2026-10-11 18:20:24 -04:00
bryanthaboi e81362907a CLOSES #2843, CLOSES #2844, CLOSES #2845, CLOSES #2846 2026-10-10 14:06:59 -04:00
bryanthaboi c819846a3d CLOSES #2759, CLOSES #2761, CLOSES #2762, CLOSES #2763, CLOSES #2764, CLOSES #2765, CLOSES #2766, CLOSES #2767
CLOSES #2759, CLOSES #2761, CLOSES #2762, CLOSES #2763, CLOSES #2764, CLOSES #2765, CLOSES #2766, CLOSES #2767
2026-10-08 10:20:26 -04:00
bryanthaboi 5742782ea5 go go go 2026-10-07 17:29:53 -04:00
bryanthaboi 0d0662cb04 launcher video 2026-10-07 17:11:53 -04:00
Autoresearch f5235858e9 Android: prevent audio focus freeze and add audio mode option (fixes #2742)
- On Android, allow game audio to mix with external audio by default instead of demanding exclusive audio focus and freezing when focus changes.
- Add an 'AUDIO MODE' option across Gen 1, Gen 2, and Gen 3 options menus and Launcher Settings:
  - BOTH: Game BGM and SFX mix with external media.
  - EXT ONLY: In-game BGM is muted while SFX remains active, mixing with external media.
  - GAME ONLY: Requests exclusive audio focus (AUDIOFOCUS_GAIN), pausing background media.
- Guard Gen 3 waitse/waitfanfare audio script waits with timeouts and Audio._suspended checks so script execution never blocks indefinitely when audio is paused or interrupted.
- Expose setAudioMixWithSystem / love.audio.setMixWithSystem via JNI / C++ to dynamically toggle Android audio focus behavior based on user setting.
- Add unit test suite in tests/engine/audio_focus_mode_test.lua.
2026-10-07 20:16:18 +01:00
bryanthaboi fcdaecd496 CLOSES #2726, CLOSES #2727, CLOSES #2729, CLOSES #2730, CLOSES #2731, CLOSES #2733, CLOSES #2734, CLOSES #2735, CLOSES #2736, CLOSES #2737, CLOSES #2740 2026-10-07 06:04:57 -04:00
bryanthaboi 74694e452a Merge pull request #2716 from Nexhas28/feat/sdl-controller-support 2026-10-06 19:56:51 -04:00
bryanthaboi 4ecf6f371f launcher pauncher 2026-10-06 17:26:40 -04:00
Shane McGovern 1a53525722 feat(input): full SDL controller support and analog rebinds in Options
- Add normalizePad() and aliases in GamepadMap for triggers and sticks
- Automatically load custom mappings from SDL_GAMECONTROLLERCONFIG and gamecontrollerdb.txt
- Add support for left and right analog sticks, triggers (L2/R2), stick clicks (LS/RS), and extra SDL buttons (Guide, Touchpad, Paddles)
- Route analog stick axis thresholds into discrete directional press/release events for seamless in-game and menu navigation
- Support rebinding buttons, thumbstick directions, triggers, and stick clicks in the CONTROLS menu (BindingsMenu) with clear abbreviated labels (LS-UP, RS-DN, L2, R2, etc.)
- Integrate stick axis event dispatch across Gen1, Gen2, and Gen3 game loops
- Add comprehensive test suite in tests/engine/sdl_controller_support_test.lua covering all axes, buttons, holds, rebinding, and multi-generation routing
2026-10-06 16:56:38 +01:00
bryanthaboi 927f3ecc6c fixes to id sync and also box 2026-10-06 11:00:16 -04:00
bryanthaboi 6774889505 Add Pokemon Ruby and Sapphire
Ruby and Sapphire 1.0/1.1/1.2 import, play, save, convert and link. Gen 3 shaders, braille, weather and reflection parity, link room players, RS custom carts and launcher support, Gen 3 link fixes for Emerald and FireRed/LeafGreen.
2026-10-05 05:07:42 -04:00
bryanthaboi 20ab97abf8 save editor 2026-10-01 21:31:40 -04:00
Shane McGovern 795276935c Performance pass: cut per-frame allocations and draw calls, fix frame-rate and batch bugs
- Shared render: cache Font encode/width, skip unchanged palette/ShaderFX
  uniform sends, reuse quads and scratch tables, cheaper sprite palettes
- Mods: fast path for loaded requires, memoized sandbox verdicts, fewer
  Hooks:call allocations, drop emptied hook chains
- Audio: bulk PCM writes, cry/SFX prewarm on the worker, sliced sync
  fallback, cached Gen 3 SE sources
- Gen 1: per-frame SGB battle palettes, hoisted overworld FX, cached menus
- Gen 2: numeric attr grid, indexed anim cells, entity culling, memoized
  cache keys, palette shader set once per tile run
- Gen 3: reuse native tile batches, per-cell metatile rebuilds, partial
  FRLG tile anim uploads, near-view ghost ticking, packed FRLG font atlas
- Fixes: emergency quit timer, Gen 3 batch regression and stale sprite
  index, trainer card texture leak, missing pic re-reads, anim tint cache,
  Crystal ghost grass overdraw, refresh-rate dependent counters, pad swap
2026-09-30 14:53:18 +00:00
bryanthaboi afc5e30d80 perhaps a windows fix 2026-09-29 20:01:49 -04:00
bryanthaboi 3d58e7bfe3 allow preses through video, and reimport while playing 2026-09-28 11:07:11 -04:00
bryanthaboi 690f0cd9a1 TOUCHDOWN 2026-09-27 16:07:31 -04:00
Shane McGovern 8c4acf669d feat: make crash reports readable and attributable 2026-09-26 22:35:10 +01:00
bryanthaboi b1216ad68a splash screen 2026-09-25 10:40:32 -04:00
bryanthaboi f8c95b8e8a CLOSES #2347, CLOSES #2384, CLOSES #2456, CLOSES #2460, CLOSES #2461, CLOSES #2468, CLOSES #2470, CLOSES #2471, CLOSES #2472, CLOSES #2473 2026-09-25 07:11:46 -04:00
bryanthaboi 9335be1bbd online update 2026-09-24 05:17:32 -04:00
bryanthaboi dee935a4ea CLOSES #2430 2026-09-23 11:58:32 -04:00
bryanthaboi 23617f43b4 CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
2026-09-22 16:27:28 -04:00
bryanthaboi 8356fdd8e1 othe rbig changes 2026-09-22 11:44:50 -04:00
bryanthaboi 84d0ea8616 audio update and return to launcher 2026-09-17 09:42:08 -04:00
1jamie 06dd4ffba8 game3: add fanfare/emote parity, pause & main menu exit flows, and bump fr cache 2026-09-15 15:41:51 -05:00
1jamie 52ad498b8b feat(game3): self-contained ROM-derived FireRed extraction & cache contract alignment
- Align CacheContract firered overrides with pure ROM extraction
- Fix door animation extraction tile sizes, palettes, and strides
- Update storage chrome, pokedex, summary, and battle chrome extractors
- Ensure 100% self-contained ROM extraction without external dependencies
2026-09-09 14:14:40 -05:00
1jamie 3cce66d497 Implement Android image export functionality and enhance save data management. Added exportImageToGallery method for saving images to the public Pictures directory on Android. Updated Printer and SaveData modules to support this feature, ensuring proper slot resolution and user feedback. Improved touch handling in the launcher to prevent unintended actions after exiting games. 2026-09-03 13:17:59 -05:00
bryanthaboi 4b2aa483bb perhaps fixing fps issue 2026-09-02 10:02:32 -04:00
1jamie 19b2b688a8 fixed present sync so android/uwp dont get treated like desktop windows, android is bufferqueue backpressure and xbox uwp is angle under the console compositor; leaving vsync on while we soft-cap was stopping the swapchain from ever locking clean. now they get their own nests, DISPLAY by default so the probe can actually engage, and fail-closed silences the driver so framecap can pace alone. 2026-08-31 16:41:42 -05:00
bryanthaboi 998cb03d4c CLOSES #1947, CLOSES #1987, CLOSES #1989, CLOSES #1994, CLOSES #1996, CLOSES #1998, CLOSES #2010, CLOSES #2011, CLOSES #2012, CLOSES #2013, CLOSES #2014, CLOSES #2015, CLOSES #2017, CLOSES #2018, CLOSES #2019, CLOSES #2020, CLOSES #2021, CLOSES #2022 2026-08-31 12:05:42 -04:00
bryanthaboi d18aab2086 Merge pull request #2008 from 1Jamie/low-power-fps-fix 2026-08-30 21:39:13 -04:00
1jamie 7984fe296c Implement idle render governor and update vsync handling for handheld builds
- Introduced the `POKEPORT_IDLE_AFTER` and `POKEPORT_IDLE_FPS` environment variables to manage presentation rates on static screens, allowing game logic and audio to maintain full speed.
- Updated the vsync handling to keep it enabled across all platforms, including KMSDRM handhelds, to leverage PresentSync for improved cadence and pacing.
- Enhanced FrameCap logic to ensure proper handling of performance caps in handheld environments, preventing unnecessary software pacing when hardware capabilities are sufficient.
- Adjusted documentation to reflect these changes and their impact on power efficiency and performance.
2026-08-30 19:47:23 -05:00
laaledesiempre a4bbcc10ab fix(core): cut per-frame allocation churn and GC pressure on the main loop
On weak single-core handhelds (RK3326/RG351MP) the main thread sits at
100% CPU, so every millisecond of jitter drops a frame: constant
stuttering while walking even at PERFORMANCE LOW with all mods off,
while average CPU usage stays unchanged.  Three sources of per-frame
garbage and pause on the hot path:

- Game:step / Game:logicSpeed passed inline closures to ModRuntime.call,
  allocating a fresh function 60 times per second.  Hoist both to
  module-level locals; behavior is identical.
- Game:update advanced the incremental collector every rendered frame.
  Space it to every 4th frame: the explicit frees the comment refers
  to still do the heavy lifting, collection stays incremental, and the
  stepping itself stops competing with the 16.6ms frame budget.
- checkEmergencyQuit called love.joystick.getJoysticks() (a fresh
  table) twice per frame to guard a 5-second hold combo.  Cache the
  joystick list and refresh it once per second; a 1s hotplug delay is
  irrelevant against a 5s hold.

Tested on an RG351MP (RK3326, dArkOS, v0.2.41): eliminates the
constant walking stutter with all mods off, and with 11 mods
re-enabled.  Average CPU is unchanged (the cost was variance, not
load), which matches the diagnosis.
2026-08-30 20:56:51 -03:00
bryanthaboi ccd3abb3b3 Merge pull request #1984 from bryanthaboi/feat/uri-launch-args 2026-08-30 14:04:38 -04:00
Adrian Castro 00a2486555 feat: add URI launch options and unified platform builds 2026-08-30 18:45:42 +02:00
1jamie 07071e334c Refine VSync detection and FixedStep logic for improved frame pacing
- Updated PresentSync to accurately measure present() block time, ensuring that the probe does not misclassify sync status due to FrameCap sleep artifacts.
- Enhanced FixedStep to implement a hard ceiling on catch-up debt, preventing input starvation during high-speed scenarios.
- Adjusted logic in Game and Game2 to utilize the new catchupLimit function for setting maxAccum, ensuring consistent behavior across speed multipliers.
- Improved test coverage for PresentProbe and PresentSync to validate the new logic and edge cases.
2026-08-30 11:29:43 -05:00
1jamie f82f565cae Fix to vsync measuring and detection and fixes fixestep so it snaps wallclock dt before applying speed
the display sync stuff i added was probing whether vsync was actually working, but it was measuring the wrong thing. during the probe we software-cap at 60 for safety, and the probe was looking at the gap between frames... which includes the sleep 😅 .....  so it always looked like sync was fine even when the driver was ignoring it. on something like the ally x on windows thats a real problem. vsync says on, probe says gated, we lift the cap and snap logic to the panel hz, then youre basically uncapped. at 2–4x that turns into hitching, dropped frames, dropped input, that weird half second freeze. speed swapping wasnt desyncing the driver, it was just making the bad path hurt more.
the solution is just we time present() itself now, not the gap after it, this way the warmup sleep cant fake a pass. if sync is unclear or broken we just stay on a capped 60 and dont snap logic. Also fixed fixedstep so it snaps wall clock dt before applying speed, so in general the 2-4x speed swaps dont screw the pacing math anymore
2026-08-30 11:12:19 -05:00
1jamie 2f6c5527f6 Add PresentSync integration for improved VSync handling
- Introduced PresentSync module to manage display synchronization.
- Updated love.run() to handle display changes and resizing events with PresentSync.
- Enhanced FrameCap logic to accommodate PresentSync requirements.
- Modified VSync to report effective states and handle driver quirks.
- Updated options menus to reflect PresentSync availability and restrictions.
- Added tests to validate PresentSync functionality and its interaction with VSync settings.

should address issue #1910 and issue #1958
2026-08-29 19:43:25 -05:00
bryanthaboi 36ad59bdbb CLOSES #1590, CLOSES #1592, CLOSES #1625, CLOSES #1657, CLOSES #1698, CLOSES #1699, CLOSES #1700, CLOSES #1843, CLOSES #1875, CLOSES #1898, CLOSES #1902, CLOSES #1905, CLOSES #1906, CLOSES #1907, CLOSES #1908, CLOSES #1909, CLOSES #1912, CLOSES #1915, CLOSES #1917, CLOSES #1919, CLOSES #1920, CLOSES #1921, CLOSES #1922, CLOSES #1923, CLOSES #1924, CLOSES #1925, CLOSES #1926, CLOSES #1927 2026-08-29 06:59:38 -04:00
bryanthaboi 680db777a3 big online energy 2026-08-28 10:14:44 -04:00
Shane McGovern dce0dd32db fix(ci): pass all engine invariant and headless test suites 2026-08-26 13:42:44 +01:00
Shane McGovern 88e24f2c0c feat(core): add global Start+Select 5s emergency force-quit watchdog 2026-08-26 13:26:14 +01:00
1jamie 28dc9b9bb0 fix(mobile): in-process launcher return for Android and iOS
Stop joining ChipAudio on every EXIT GAME, always rebuild the Gen1 Game
module on Play-again, and treat iOS like Android for return-to-launcher so
release/mobile LOVE restarts no longer wipe Game.load or crash on quit.
2026-08-25 11:25:08 -05:00
bryanthaboi ab61d08fe9 Merge pull request #1786 from 1Jamie/more-android-lc
fix(android): keep Gen1 Game.load after in-process EXIT GAME
2026-08-25 08:10:21 -04:00
bryanthaboi 1850b50ee6 CLOSES #941, CLOSES #1081, CLOSES #1349, CLOSES #1602, CLOSES #1618, CLOSES #1624, CLOSES #1630, CLOSES #1633, CLOSES #1661, CLOSES #1669, CLOSES #1676, CLOSES #1731, CLOSES #1739, CLOSES #1740, CLOSES #1742, CLOSES #1744, CLOSES #1753, CLOSES #1757, CLOSES #1758, CLOSES #1760, CLOSES #1761, CLOSES #1762, CLOSES #1763, CLOSES #1765, CLOSES #1770, CLOSES #1777, CLOSES #1781, CLOSES #1783, CLOSES #1784, CLOSES #1785, CLOSES #1787, CLOSES #1788, CLOSES #1789, CLOSES #1790, CLOSES #1792, CLOSES #1797, CLOSES #1803 2026-08-25 07:55:52 -04:00
1jamie d76d173b60 fix(android): keep Gen1 Game.load after in-process EXIT GAME
Stop fanning out arbitrary field:release() during Game/Game2 reset — shared
modules use :release as a handle API, and that teardown left the Gen1
singleton unbootable (Game:load nil) on Play-again. Harden bootGame and
endGameSession to rebuild the module if load is missing.
2026-08-24 14:33:43 -05:00
bryanthaboi cd4ef14f13 Merge branch 'dev' into spidercar2 2026-08-24 08:48:24 -04:00
bryanthaboi 8c6c360ce0 Merge pull request #1715 from caorthann-celt/dev
Enable UWP HTTP requests and Skin Studio controller support
2026-08-24 08:30:09 -04:00