//===========================================================================// // File: l4joy.h // // Project: MUNGA Brick: generic joystick reader // // Contents: DirectInput 8 sticks, HOTAS throttles and pedals // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once //######################################################################## // // L4JOY - the generic-joystick reader. // // PadRIO reads XInput, which covers Xbox-class pads and nothing else. // This layer adds every OTHER game device Windows knows - flight sticks, // HOTAS throttles, twist grips, rudder pedals, wheels - through // DirectInput 8, the standard generic-HID game API. It exposes up to // joyMaxDevices attached devices as normalized state blocks; the PadRIO // poll maps them onto the pod's control channels through the joydev / // joyaxis / joybutton / joyhat rows of bindings.txt (L4PADBINDINGS.h), // the same binding machinery the pad and keyboard already use. // // XInput-class devices are EXCLUDED here, or they would double-feed // through both APIs and every input would count twice. A DirectInput // device whose VID/PID also appears in a RawInput device path containing // the "IG_" marker is an XInput device - the documented detection that // does not drag in WMI. // // This is distinct from the legacy L4DINPUT.cpp DIJoystick, the 1995-era // single-device `Joystick` engine interface reachable only through the // old L4CONTROLS=DIJOYSTICK profile. That path is untouched. // // RP412JOYCONFIG=1 runs the interactive setup wizard at boot: it asks // the player to move each control, works out which device and axis moved // and which way, and writes the joystick section of bindings.txt. // RP412JOYLOG=1 logs device attach/detach. // // Ported from BT411, whose glass cockpit needed the same thing. // //######################################################################## enum { joyMaxDevices = 4, joyAxisCount = 8, // X Y Z RX RY RZ SL0 SL1 (DIJOYSTATE2 order) joyButtonCount = 32, // buttons exposed to bindings (DI carries 128) joyHatCount = 4 }; struct RPJoyDeviceState { int attached; float axis[joyAxisCount]; // normalized -1..1, raw: deadzones // are the binding layer's business unsigned buttons; // bit n = button n held int hat[joyHatCount]; // POV in centidegrees, -1 = centered char name[64]; // product name ("T.16000M", ...) }; // // Lifecycle. Init is lazy-safe (Poll calls it) and returns the attached // non-XInput device count. Re-enumeration for hot-plug happens inside // Poll on a ~3 s cadence whenever nothing is attached. // int RPJoyInit(void); void RPJoyShutdown(void); void RPJoyPoll(void); int RPJoyDeviceCount(void); const RPJoyDeviceState *RPJoyDevice(int index); // NULL out of range/detached // // Case-insensitive product-name substring match to a device index, -1 for // no match. This is what a named joydev slot resolves through. // int RPJoyFindDevice(const char *name_substring); // // The RP412JOYCONFIG capture wizard (console UI; called from RPL4.CPP // before the front end). Returns 0 if it wrote a config, non-zero on // abort or no device. // int RPJoyConfigWizard(void);