controllers.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // controllers.h -- the emulated-USB-controller abstraction.
  2. //
  3. // Each USB personality (Steam puck, Xbox/XInput, Switch HORIPAD, Switch Pro, PS5 DualSense, DS4 gyro) is an
  4. // IController living in its own mode_*.cpp. Exactly ONE is active per boot, selected by g_usbMode. Methods:
  5. // begin() -- called once from setup(): set the USB VID/PID/strings and register this mode's
  6. // interface(s). Shared USB lifecycle (detach, clear/keep CDC, serial suffix, WebUSB,
  7. // attach) stays in setup(); begin() only adds what's specific to this controller.
  8. // onReport45() -- called from rf_link.cpp each time a controller input report 0x45 is decoded. PUSH-style
  9. // modes (Xbox, puck/lizard) build + send their host report here. STREAM-style modes ignore
  10. // it and emit at a fixed cadence from task(); they read the decoded g_in directly.
  11. // task() -- called every loop(): streaming emit, handshake/subcommand draining, mode-specific upkeep.
  12. // isPuck() -- true for Steam/Lizard (keep the boot CDC composite; different USB lifecycle in setup()).
  13. //
  14. // To add a new controller: implement IController in a new mode_*.cpp, give it a singleton, and wire it into
  15. // controllerFor() in controllers.cpp.
  16. #pragma once
  17. #include <stdint.h>
  18. class IController {
  19. public:
  20. virtual ~IController()
  21. {
  22. }
  23. virtual void begin() = 0;
  24. virtual void onReport45(const uint8_t *rep, bool fresh,
  25. uint8_t bodyTlen)
  26. {
  27. (void)rep;
  28. (void)fresh;
  29. (void)bodyTlen;
  30. }
  31. // Other controller->host input reports decoded from the F1 reply (NOT 0x45): power/battery status report
  32. // 0x43, status event 0x44. The real puck forwards these to Steam verbatim -- that's how Steam reads battery.
  33. // rid = report id, data/n = body after the id. Default no-op (clean modes don't expose these reports).
  34. virtual void onAuxReport(uint8_t rid, const uint8_t *data, uint8_t n)
  35. {
  36. (void)rid;
  37. (void)data;
  38. (void)n;
  39. }
  40. virtual void task()
  41. {
  42. }
  43. // a wake gesture fired while suspended; queue any post-resume input the host needs to actually wake
  44. virtual void wakeEvent()
  45. {
  46. }
  47. virtual bool isPuck() const
  48. {
  49. return false;
  50. }
  51. };
  52. // The singleton for a given mode (nullptr if the mode is unknown). Defined in controllers.cpp.
  53. IController *controllerFor(uint8_t mode);
  54. // The active controller for this boot (set in setup()). rf_link/loop dispatch through it.
  55. extern IController *g_active;