diff --git a/doomsday/engine/data/cphelp.txt b/doomsday/engine/data/cphelp.txt index 8ce14eca07..b98fba8572 100644 --- a/doomsday/engine/data/cphelp.txt +++ b/doomsday/engine/data/cphelp.txt @@ -957,6 +957,9 @@ desc = Maximum limit for the frame rate (default: 200). [input-toggle-sharp] desc = 1=Process toggle events only on sharp ticks for backwards compatible behavior. +[input-conflict-zerocontrol] +desc = 1=If a control is influenced by two or more conflicting input device states, the control position gets zeroed. + [input-key-delay1] desc = The number of milliseconds to wait before first key repeat. diff --git a/doomsday/engine/portable/include/b_device.h b/doomsday/engine/portable/include/b_device.h index 3a6e1f1490..add04781df 100644 --- a/doomsday/engine/portable/include/b_device.h +++ b/doomsday/engine/portable/include/b_device.h @@ -34,7 +34,8 @@ typedef enum cbdevtype_e { CBD_TOGGLE, CBD_AXIS, - CBD_ANGLE + CBD_ANGLE, + NUM_CBD_TYPES } cbdevtype_t; // Flags for control-device bindings. diff --git a/doomsday/engine/portable/src/b_device.c b/doomsday/engine/portable/src/b_device.c index d9b6c03d6f..509d5cc9aa 100644 --- a/doomsday/engine/portable/src/b_device.c +++ b/doomsday/engine/portable/src/b_device.c @@ -55,6 +55,7 @@ float stageThreshold = 6.f/35; float stageFactor = .5f; +byte zeroControlUponConflict = true; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -288,6 +289,8 @@ void B_EvaluateDeviceBindingList(int localNum, dbinding_t* listRoot, float* pos, float deviceOffset; uint deviceTime; uint nowTime = Sys_GetRealTime(); + boolean conflicted[NUM_CBD_TYPES] = { false, false, false }; + boolean appliedState[NUM_CBD_TYPES] = { false, false, false }; *pos = 0; *relativeOffset = 0; @@ -397,6 +400,26 @@ void B_EvaluateDeviceBindingList(int localNum, dbinding_t* listRoot, float* pos, *pos += devicePos; *relativeOffset += deviceOffset; + + // Is this state contributing to the outcome? + if(!FEQUAL(devicePos, 0.f)) + { + if(appliedState[cb->type]) + { + // Another binding already influenced this; we have a conflict. + conflicted[cb->type] = true; + } + + // We've found one effective binding that influences this control. + appliedState[cb->type] = true; + } + } + + if(zeroControlUponConflict) + { + for(i = 0; i < NUM_CBD_TYPES; ++i) + if(conflicted[i]) + *pos = 0; } // Clamp appropriately. diff --git a/doomsday/engine/portable/src/b_main.c b/doomsday/engine/portable/src/b_main.c index 65a4ac1c96..f553175cc8 100644 --- a/doomsday/engine/portable/src/b_main.c +++ b/doomsday/engine/portable/src/b_main.c @@ -154,6 +154,10 @@ static const keyname_t keyNames[] = { void B_Register(void) { + extern byte zeroControlUponConflict; + + C_VAR_BYTE("input-conflict-zerocontrol", &zeroControlUponConflict, 0, 0, 1); + #define PROTECTED_FLAGS (CMDF_NO_DEDICATED|CMDF_DED|CMDF_CLIENT) C_CMD_FLAGS("bindevent", "ss", BindEventToCommand, PROTECTED_FLAGS);