Skip to content

feat: expose controller port device API for EmulatorJS#38

Open
chrisallenlane wants to merge 1 commit intoEmulatorJS:v1.22.2from
chrisallenlane:feat/controller-port-device
Open

feat: expose controller port device API for EmulatorJS#38
chrisallenlane wants to merge 1 commit intoEmulatorJS:v1.22.2from
chrisallenlane:feat/controller-port-device

Conversation

@chrisallenlane
Copy link
Copy Markdown

Body

Hi, all.

Over the weekend I embedded EmulatorJS in a project, and realized that lightgun support was not implemented. This is one of two PRs that implements it. (You can see it working now in the linked project - I've applied these patches there already.)

I am a software engineer, but I am not a C programmer, so please take a close look at this one. That said, the I've robustly tested the changes (meaning: I've beaten Battleclash and Metal Combat: Falcon's Revenge several times today, lol), and I've encountered no issues.

I hope this is helpful. I'm happy to answer any questions.

Summary

This adds two new WASM-exported functions and lightgun input handling to enable EmulatorJS to support controller port device switching at runtime -- most notably, lightgun peripherals like the SNES Super Scope.

Currently, EmulatorJS has no way to change a port's device type (e.g. from Joypad to Super Scope). The core reports available device types via RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, and core_set_controller_port_device() exists internally, but neither is exposed to JavaScript. This means lightgun games are unplayable across all systems.

Changes

runloop.c -- Two new functions inside #ifdef EMULATORJS:

  • ejs_get_controller_port_info() -- Serializes the controller info already stored in sys_info->ports (reported by the core via SET_CONTROLLER_INFO) into a parseable port:deviceId:description\n string. Follows the same pattern as get_core_options().

  • ejs_set_controller_port_device(port, device) -- Thin wrapper around core_set_controller_port_device().

input/drivers/emulatorjs_input.c -- Added RETRO_DEVICE_LIGHTGUN case to rwebinput_input_state():

  • Mouse position mapped to LIGHTGUN_SCREEN_X/Y via existing viewport translation
  • Mouse buttons mapped to lightgun buttons:
    • Left click: Trigger
    • Right click: AUX_A (Cursor)
    • Middle click: AUX_B (Turbo)
    • Button 4: Start (Pause)
    • Button 5: Select
  • Advertised lightgun capability in rwebinput_get_capabilities()

Makefile.emulatorjs -- Added both new functions to EXPORTED_FUNCTIONS.

Testing

Tested with snes9x core running SNES Super Scope games (Battle Clash, Metal Combat: Falcon's Revenge, Super Scope 6). Crosshair tracks mouse, fire/cursor/turbo buttons work correctly, device type persists across settings changes.

Related issues

Companion PR

The EmulatorJS JavaScript UI changes that consume these new exports will be submitted as a separate PR to EmulatorJS/EmulatorJS.

Add two new WASM-exported functions to allow EmulatorJS to query
available controller device types per port and change them at runtime:

- ejs_get_controller_port_info(): serializes the controller info
  reported by cores via RETRO_ENVIRONMENT_SET_CONTROLLER_INFO into
  a string that JavaScript can parse.

- ejs_set_controller_port_device(port, device): thin wrapper around
  core_set_controller_port_device() to allow changing a port's device
  type (e.g. switching from Joypad to Super Scope) from JavaScript.

Also adds RETRO_DEVICE_LIGHTGUN handling to the EmulatorJS input
driver, mapping mouse position to lightgun screen coordinates and
mouse buttons to lightgun buttons (trigger, cursor, turbo, start,
select).

This enables lightgun support for SNES Super Scope, Justifier,
NES Zapper, PSX GunCon, and other lightgun peripherals across all
supported cores.

Closes EmulatorJS/EmulatorJS#677
Related: EmulatorJS/EmulatorJS#272, EmulatorJS/EmulatorJS#816,
EmulatorJS/EmulatorJS#1117

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@BinBashBanana
Copy link
Copy Markdown

This looks good to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants