Просмотр исходного кода

input: binding multiple key/axis to the same controller action

undefined
Benlitz Sam Hocevar <sam@hocevar.net> 11 лет назад
Родитель
Сommit
339f05db73
3 измененных файлов: 166 добавлений и 74 удалений
  1. +125
    -44
      src/input/controller.cpp
  2. +40
    -29
      src/input/controller.h
  3. +1
    -1
      src/input/input.h

+ 125
- 44
src/input/controller.cpp Просмотреть файл

@@ -22,26 +22,43 @@ namespace lol

void KeyBinding::Bind(const char* device_name, const char* key_name)
{
ClearBinding();
const InputDevice* device = InputDevice::Get(device_name);

m_device = InputDevice::Get(device_name);
if (!m_device)
if (!device)
{
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
return;
}

m_keyindex = m_device->GetKeyIndex(key_name);

if (m_keyindex < 0)
int keyindex = device->GetKeyIndex(key_name);
if (keyindex < 0)
{
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name, key_name);
return;
}

m_keybindings.Push(device, keyindex);
}

bool KeyBinding::Unbind(const char* device_name, const char* key_name)
{
for (int i = 0; i < m_keybindings.Count(); ++i)
{
if (m_keybindings[i].m1->GetName() == device_name)
{
if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(key_name))
{
m_keybindings.Remove(i);
return true;
}
}
}
return false;
}

void KeyBinding::ClearBinding()
void KeyBinding::ClearBindings()
{
m_keyindex = -1;
m_keybindings.Empty();
}

///////////////////////////////////////////////////////////////////////////////
@@ -49,89 +66,153 @@ void KeyBinding::ClearBinding()

void AxisBinding::Bind(const char* device_name, const char* axis_name)
{
ClearBinding();

m_device = InputDevice::Get(device_name);
if (!m_device)
const InputDevice* device = InputDevice::Get(device_name);
if (!device)
{
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
return;
}

m_axisindex = m_device->GetAxisIndex(axis_name);

if (m_axisindex < 0)
int axisindex = device->GetAxisIndex(axis_name);
if (axisindex < 0)
{
Log::Warn("Trying to bind controller to axis %s.%s which doesn't exist", device_name, axis_name);
return;
}

m_axisbindings.Push(device, axisindex);
}

void AxisBinding::BindKey(const char* device_name, const char* key_name)
{
ClearBinding();

m_device = InputDevice::Get(device_name);
if (!m_device)
const InputDevice* device = InputDevice::Get(device_name);
if (!device)
{
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
return;
}

m_maxkeyindex = m_device->GetKeyIndex(key_name);

if (m_maxkeyindex < 0)
int keyindex = device->GetKeyIndex(key_name);
if (keyindex < 0)
{
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name, key_name);
return;
}

m_keybindings.Push(device, -1, keyindex);
}

void AxisBinding::BindKeys(const char* device_name, const char* min_key_name, const char* max_key_name)
{
ClearBinding();
m_device = InputDevice::Get(device_name);
if (!m_device)
const InputDevice* device = InputDevice::Get(device_name);
if (!device)
{
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
return;
}

m_minkeyindex = m_device->GetKeyIndex(min_key_name);
m_maxkeyindex = m_device->GetKeyIndex(max_key_name);

if (m_minkeyindex < 0)
int minkeyindex = device->GetKeyIndex(min_key_name);
if (minkeyindex < 0)
{
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name, min_key_name);
ClearBinding();
return;
}

if (m_maxkeyindex < 0)
int maxkeyindex = device->GetKeyIndex(max_key_name);
if (maxkeyindex < 0)
{
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name, max_key_name);
ClearBinding();
return;
}

m_keybindings.Push(device, minkeyindex, maxkeyindex);
}

void AxisBinding::ClearBinding()
bool AxisBinding::Unbind(const char* device_name, const char* axis_name)
{
m_axisindex = -1;
m_minkeyindex = -1;
m_maxkeyindex = -1;
for (int i = 0; i < m_keybindings.Count(); ++i)
{
if (m_axisbindings[i].m1->GetName() == device_name)
{
if (m_axisbindings[i].m2 == m_axisbindings[i].m1->GetAxisIndex(axis_name))
{
m_axisbindings.Remove(i);
return true;
}
}
}
return false;
}

bool AxisBinding::UnbindKey(const char* device_name, const char* key_name)
{
for (int i = 0; i < m_keybindings.Count(); ++i)
{
if (m_keybindings[i].m1->GetName() == device_name)
{
if (m_keybindings[i].m2 == -1 && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(key_name))
{
m_keybindings.Remove(i);
return true;
}
}
}
return false;
}

bool AxisBinding::UnbindKeys(const char* device_name, const char* min_key_name, const char* max_key_name)
{
for (int i = 0; i < m_keybindings.Count(); ++i)
{
if (m_keybindings[i].m1->GetName() == device_name)
{
if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(min_key_name)
&& m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(max_key_name))
{
m_keybindings.Remove(i);
return true;
}
}
}
return false;

}

void AxisBinding::ClearBindings()
{
m_axisbindings.Empty();
m_keybindings.Empty();
}

float AxisBinding::RetrieveCurrentValue()
{
if (m_axisindex != -1)
float max_positive = 0.0f;
float max_negative = 0.0f;

for (int i = 0; i < m_axisbindings.Count(); ++i)
{
return m_device->GetAxis(m_axisindex);
float value = m_axisbindings[i].m1->GetAxis(m_axisbindings[i].m2);
if (value > max_positive)
max_positive = value;
if (value < max_negative)
max_negative = value;
}

float value = 0.0f;
if (m_minkeyindex != -1)
value += m_device->GetKey(m_minkeyindex) ? -1.0f : 0.0f;
if (m_maxkeyindex != -1)
value += m_device->GetKey(m_maxkeyindex) ? 1.0f : 0.0f;
for (int i = 0; i < m_keybindings.Count(); ++i)
{
float value = 0.0f;
m_keybindings[i].m1->GetKey(m_keybindings[i].m2);
value += m_keybindings[i].m1->GetKey(m_keybindings[i].m3) ? 1.0f : 0.0f;
if (m_keybindings[i].m2 != -1)
value += m_keybindings[i].m1->GetKey(m_keybindings[i].m2) ? -1.0f : 0.0f;

if (value > max_positive)
max_positive = value;
if (value < max_negative)
max_negative = value;
}

return value;
return max_negative + max_positive;
}

///////////////////////////////////////////////////////////////////////////////


+ 40
- 29
src/input/controller.h Просмотреть файл

@@ -20,35 +20,45 @@ class KeyBinding
{
public:
KeyBinding()
: m_device(nullptr),
m_keyindex(-1),
m_current(false),
: m_current(false),
m_previous(false)
{}

/** Indicate wheither the key is currently down */
/** Indicates wheither the key is currently down */
bool IsDown() const { return m_current; }
/** Indicate wheither the key is currently up */
/** Indicates wheither the key is currently up */
bool IsUp() const { return !m_current; }
/** Indicate wheither the key has just been pressed */
/** Indicates wheither the key has just been pressed */
bool IsPressed() const { return m_current && !m_previous; }
/** Indicate wheither the key has just been released */
/** Indicates wheither the key has just been released */
bool IsReleased() const { return !m_current && m_previous; }

/** Bind a physical device and key */
void Bind(const char* device_name, const char* key_name);
/** Unbind a previously bound physical device and key. Returns true if the binding was existing. */
bool Unbind(const char* device_name, const char* key_name);
/** Clear current binding */
void ClearBinding();

/** Indicate wheither a physical device and key has been bound */
bool IsBound() { return m_device && m_keyindex != -1; }
void ClearBindings();
/** Indicate wheither a physical device and key has been bound. Returns the number of bindings set. */
int IsBound() const { return m_keybindings.Count(); }

protected:
void Update() { m_previous = m_current; m_current = IsBound() ? m_device->GetKey(m_keyindex) : false; }

const InputDevice* m_device;
int m_keyindex;
/** Update the binding value. Called internally by the controller, once per frame */
void Update()
{
m_previous = m_current;
m_current = false;
for (int i = 0; i < m_keybindings.Count(); ++i)
{
m_current = m_current || m_keybindings[i].m1->GetKey(m_keybindings[i].m2);
}
}

/** m1 is the InputDevice, m2 is the key index on the InputDevice */
Array<const InputDevice*, int> m_keybindings;
/** Value at the previous frame */
bool m_current;
/** Value at the current frame */
bool m_previous;

friend class Controller;
@@ -58,11 +68,7 @@ class AxisBinding
{
public:
AxisBinding()
: m_device(nullptr),
m_axisindex(-1),
m_minkeyindex(-1),
m_maxkeyindex(-1),
m_current(0.0f),
: m_current(0.0f),
m_previous(0.0f)
{}

@@ -70,28 +76,33 @@ public:
float GetValue() const { return m_current; }
/** Gets the current delta value of this axis */
float GetDelta() const { return m_current - m_previous; }
/** Bind a physical device and axis */
void Bind(const char* device_name, const char* axis_name);
/** Bind a physical device and key over this axis. The axis value will be 0 if the key is up and 1 if it's down */
void BindKey(const char* device_name, const char* key_name);
/** Bind physical device and keys over this axis. The axis value will be 0 if both the key are up, -1 if minkey is down, and 1 if maxkey is down */
void BindKeys(const char* device_name, const char* min_key_name, const char* max_key_name);
/** Unbind a previously bound physical device and axis. Returns true if the binding was existing. */
bool Unbind(const char* device_name, const char* axis_name);
/** Unbind a previously bound physical device and axis. Returns true if the binding was existing. */
bool UnbindKey(const char* device_name, const char* key_name);
/** Unbind a previously bound physical device and axis. Returns true if the binding was existing. */
bool UnbindKeys(const char* device_name, const char* min_key_name, const char* max_key_name);
/** Clear current binding */
void ClearBinding();
void ClearBindings();
/** Indicate wheither a physical device and axis has been bound. Returns the number of bindings set. */
int IsBound() const { return m_axisbindings.Count() + m_keybindings.Count(); }

/** Indicate wheither a physical device and axis has been bound */
bool IsBound() { return m_device &&
(m_axisindex != -1 || m_maxkeyindex != -1); }

protected:
void Update() { m_previous = m_current; m_current = IsBound() ? RetrieveCurrentValue() : 0.0f; }
float RetrieveCurrentValue();

const InputDevice* m_device;
int m_axisindex;
int m_minkeyindex;
int m_maxkeyindex;
/** m1 is the InputDevice, m2 is the axis index on the InputDevice, m3 and m4 are an optional key indices to bind one or two keys over the axis */
Array<const InputDevice*, int> m_axisbindings;
/** m1 is the InputDevice, m2 is the key index on the InputDevice for the negative value, m3 is the key index on the InputDevice for the positive value. Only one key is required to bind key over axis. */
Array<const InputDevice*, int, int> m_keybindings;
float m_current;
float m_previous;



+ 1
- 1
src/input/input.h Просмотреть файл

@@ -20,7 +20,7 @@ class InputDevice
{
public:
/** Gets the name of this input device */
const String& GetName();
const String& GetName() const { return m_name; }

/** Gets the index of the corresponding key, needed to call GetKey */
int GetKeyIndex(const char* name) const { return GetItemIndex(name, m_keynames); }


Загрузка…
Отмена
Сохранить