--- a/Game/src/game.c +++ b/Game/src/game.c @@ -68,6 +68,36 @@ #include #include #include + +#ifdef __EMSCRIPTEN__ +/* Optional motion input belongs only to the live player's view, never a menu. + * Called by the existing SDL event/frame pump; only transitions cross into JS. */ +void dukeBrowserUpdateInputState(void) +{ + static int previous = -1; + int active = 0; + if (myconnectindex >= 0 && myconnectindex < MAXPLAYERS) + { + const struct player_struct *player = &ps[myconnectindex]; + active = player->gm == MODE_GAME && ready2send && + ud.recstat != 2 && !ud.pause_on && !ud.show_help && + !ud.overhead_on && !CONSOLE_IsActive() && + !player->dead_flag && player->cheat_phase <= 0 && player->newowner == -1 && + player->i >= 0 && player->i < MAXSPRITES && sprite[player->i].extra > 0; + } + if (active == previous) return; + previous = active; + EM_ASM({ + var active = !!$0; + Module['dukeGameplayActive'] = active; + if (typeof Module['dukeInputState'] === 'function') { + try { Module['dukeInputState'](active); } catch (error) { + console.error('Duke input-state callback failed', error); + } + } + }, active); +} +#endif #define MINITEXT_BLUE 0 @@ -2404,6 +2434,7 @@ if (exiting || (toTitle && numplayers > 1)) return; exiting = 1; ready2send = 0; + dukeBrowserUpdateInputState(); gamequit = 0; KB_FlushKeyboardQueue(); dukeTournamentStop(); --- a/Engine/src/display.c +++ b/Engine/src/display.c @@ -39,6 +39,10 @@ #include "icon.h" #include "draw.h" #include "cache.h" + +#ifdef __EMSCRIPTEN__ +extern void dukeBrowserUpdateInputState(void); +#endif /* @@ -472,6 +476,10 @@ { SDL_Event event; +#ifdef __EMSCRIPTEN__ + dukeBrowserUpdateInputState(); +#endif + while(SDL_PollEvent(&event)) root_sdl_event_filter(&event); } /* handle_events */