You are never asked what you own. Two controls cannot simply be watched, so they are asked for differently. Yaw is asked for twice, right then left, and which axis answers is the measurement. The same axis both times is one control covering both directions - a twist grip, a rudder bar, pedals the driver has already mixed - and binds to the signed Pedals axis. Two different axes are two real pedals, one per foot, which is what the pod had, so they bind to the pod's own LeftPedal/RightPedal pair and the game does the mixing: both at once then does what both at once did in the pod. The throttle is zeroed first. A lever sits wherever it was last left, possibly hard against the stop that reads +1, so watching it move says nothing about which end means power. Close it, press SPACE, then open it, and the direction it travels from a known idle is the direction that means throttle. CONTROLS.md, the handbook and the packaged README say all of this, and joyconfig.bat's own header no longer promises "rudder-pedal setup" when racing pedals work too.
206 lines
6.0 KiB
C
206 lines
6.0 KiB
C
//===========================================================================//
|
|
// File: l4padbindings.h //
|
|
// Project: MUNGA Brick: PadRIO binding profiles //
|
|
// Contents: The rebindable input profile (vRIO bindings format) //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
|
|
// PROPRIETARY AND CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#pragma once
|
|
|
|
#include "..\munga\style.h"
|
|
|
|
//########################################################################
|
|
// The bindings file (vRIO's format, shared grammar):
|
|
//
|
|
// key <name> button <addr> [toggle]
|
|
// key <name> axis <axis> deflect <n> | rate <n>
|
|
// pad <button> button <addr> [toggle]
|
|
// padaxis <src> axis <axis> [invert] [deadzone <d>] [rate <n>]
|
|
// joydev <slot> [product-name substring...]
|
|
// joyaxis <src> axis <axis> [invert] [lever] [deadzone <d>] [rate <n>]
|
|
// joybutton <n> button <addr> [toggle]
|
|
// joyhat <n> <up|down|left|right> button <addr>
|
|
//
|
|
// <addr> is a RIO input address: lamp buttons 0x00-0x47, internal
|
|
// keypad 0x50-0x5F, external keypad 0x60-0x6F. Loaded from
|
|
// bindings.txt beside the exe; written there (self-documenting, with
|
|
// the full default profile) on first run. Bad lines are logged and
|
|
// skipped, good lines always win.
|
|
//
|
|
// The joy* rows drive generic DirectInput devices - flight sticks,
|
|
// HOTAS throttles, twist grips, rudder pedals (L4JOY.h). They attach to
|
|
// the most recent joydev slot, or slot 0 if no joydev came first. A slot
|
|
// naming a product substring binds THAT device; a bare slot binds the
|
|
// Nth attached non-XInput device. Source names follow the DirectInput
|
|
// layout - X Y Z RX RY RZ SL0 SL1 - where a twist grip is usually RZ
|
|
// and a HOTAS throttle usually Z or SL0. RP412JOYCONFIG=1 writes these
|
|
// rows for you by asking the player to move each control.
|
|
//
|
|
// 'lever' says the source is a one-way control that rests at one end of
|
|
// its travel rather than in the middle - a floor pedal, a throttle
|
|
// slider. DirectInput reports it as a full -1..1 axis all the same, so
|
|
// without the keyword half the travel sits below zero and the first
|
|
// half of the press does nothing. It maps that travel onto 0..1, and
|
|
// the deadzone then measures from the released end instead of centre.
|
|
//########################################################################
|
|
|
|
enum PadBindRioAxis
|
|
{
|
|
BindAxisThrottle = 0,
|
|
BindAxisLeftPedal,
|
|
BindAxisRightPedal,
|
|
BindAxisJoystickY,
|
|
BindAxisJoystickX,
|
|
//
|
|
// A signed composite, not a channel the pod has: positive presses
|
|
// the right pedal, negative the left. One physical control - a
|
|
// rudder bar, a twist grip, a stick axis - works the pedal pair the
|
|
// way a foot never could, one or the other and never both. It
|
|
// decomposes into the real pair when the poll applies it.
|
|
//
|
|
BindAxisPedals,
|
|
BindAxisCount
|
|
};
|
|
|
|
enum PadBindKeyMode
|
|
{
|
|
BindKeyDeflect = 0, // hold at value while down, spring back
|
|
BindKeyRate // walk by value/second while down, position holds
|
|
};
|
|
|
|
enum PadBindPadAxis
|
|
{
|
|
BindPadLeftStickX = 0,
|
|
BindPadLeftStickY,
|
|
BindPadRightStickX,
|
|
BindPadRightStickY,
|
|
BindPadLeftTrigger,
|
|
BindPadRightTrigger,
|
|
BindPadAxisCount
|
|
};
|
|
|
|
struct PadKeyButtonBinding
|
|
{
|
|
int virtualKey;
|
|
int address; // 0x00-0x47 button, 0x50-0x6F keypad
|
|
Logical toggle;
|
|
// runtime edge/latch state
|
|
Logical wasDown;
|
|
Logical latched;
|
|
};
|
|
|
|
struct PadKeyAxisBinding
|
|
{
|
|
int virtualKey;
|
|
int axis; // PadBindRioAxis
|
|
int mode; // PadBindKeyMode
|
|
Scalar value;
|
|
};
|
|
|
|
struct PadPadButtonBinding
|
|
{
|
|
unsigned short padMask; // XINPUT_GAMEPAD_*
|
|
int address;
|
|
Logical toggle;
|
|
Logical wasDown;
|
|
Logical latched;
|
|
};
|
|
|
|
struct PadPadAxisBinding
|
|
{
|
|
int source; // PadBindPadAxis
|
|
int axis; // PadBindRioAxis
|
|
Logical invert;
|
|
Scalar deadzone; // normalized 0..1
|
|
Scalar rate; // 0 = direct position, >0 = speed integrate
|
|
};
|
|
|
|
//
|
|
// Generic joystick (DirectInput - L4JOY.h). device is a joydev SLOT,
|
|
// resolved to a live device at poll time by the slot's name substring or
|
|
// by its ordinal, so unplugging and replugging does not rewrite the file.
|
|
//
|
|
enum { BindJoyDeviceSlots = 4 };
|
|
|
|
enum PadBindJoyAxis
|
|
{
|
|
BindJoyAxisX = 0,
|
|
BindJoyAxisY,
|
|
BindJoyAxisZ,
|
|
BindJoyAxisRX,
|
|
BindJoyAxisRY,
|
|
BindJoyAxisRZ,
|
|
BindJoyAxisSL0,
|
|
BindJoyAxisSL1,
|
|
BindJoyAxisCount
|
|
};
|
|
|
|
struct PadJoyAxisBinding
|
|
{
|
|
int device; // joydev slot
|
|
int source; // PadBindJoyAxis
|
|
int axis; // PadBindRioAxis
|
|
Logical invert;
|
|
Logical lever; // rests at one end: -1..1 travel means 0..1
|
|
Scalar deadzone; // normalized 0..1
|
|
Scalar rate; // 0 = direct position, >0 = speed integrate
|
|
};
|
|
|
|
struct PadJoyButtonBinding
|
|
{
|
|
int device; // joydev slot
|
|
int button; // 0-31
|
|
int address;
|
|
Logical toggle;
|
|
Logical wasDown;
|
|
Logical latched;
|
|
};
|
|
|
|
struct PadJoyHatBinding
|
|
{
|
|
int device; // joydev slot
|
|
int hat; // 0-3
|
|
int direction; // 0 up, 1 right, 2 down, 3 left
|
|
int address;
|
|
};
|
|
|
|
struct PadBindingProfile
|
|
{
|
|
enum
|
|
{
|
|
maxKeyButtons = 128,
|
|
maxKeyAxes = 32,
|
|
maxPadButtons = 32,
|
|
maxPadAxes = 16,
|
|
maxJoyAxes = 24,
|
|
maxJoyButtons = 48,
|
|
maxJoyHats = 16
|
|
};
|
|
|
|
PadKeyButtonBinding keyButtons[maxKeyButtons];
|
|
int keyButtonCount;
|
|
PadKeyAxisBinding keyAxes[maxKeyAxes];
|
|
int keyAxisCount;
|
|
PadPadButtonBinding padButtons[maxPadButtons];
|
|
int padButtonCount;
|
|
PadPadAxisBinding padAxes[maxPadAxes];
|
|
int padAxisCount;
|
|
|
|
PadJoyAxisBinding joyAxes[maxJoyAxes];
|
|
int joyAxisCount;
|
|
PadJoyButtonBinding joyButtons[maxJoyButtons];
|
|
int joyButtonCount;
|
|
PadJoyHatBinding joyHats[maxJoyHats];
|
|
int joyHatCount;
|
|
// "" = take the slot's ordinal attached device
|
|
char joyDeviceMatch[BindJoyDeviceSlots][64];
|
|
};
|
|
|
|
// Load bindings.txt from the working directory into the profile,
|
|
// writing the default profile file first when absent. Errors go to
|
|
// the debug log with line numbers.
|
|
void
|
|
PadBindings_Load(PadBindingProfile *profile);
|