Replaced btn_map array with proper class

This commit is contained in:
Ingo Ruhnke 2010-05-19 23:30:43 +02:00
parent 7635e63934
commit 642e7f4648
8 changed files with 287 additions and 95 deletions

View file

@ -53,6 +53,7 @@ env.Program('xboxdrv', ['src/xboxdrv.cpp',
'src/button_event.cpp',
'src/axis_event.cpp',
'src/arg_parser.cpp',
'src/button_map.cpp',
'src/pretty_printer.cpp',
'src/helper.cpp',
'src/modifier.cpp',

62
src/button_map.cpp Normal file
View file

@ -0,0 +1,62 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2010 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "button_map.hpp"
ButtonMap::ButtonMap()
{
clear();
}
void
ButtonMap::bind(int code, const ButtonEvent& event)
{
btn_map[XBOX_BTN_UNKNOWN][code] = event;
}
void
ButtonMap::bind(int shift_code, int code, const ButtonEvent& event)
{
btn_map[shift_code][code] = event;
}
ButtonEvent
ButtonMap::lookup(int code) const
{
return btn_map[XBOX_BTN_UNKNOWN][code];
}
ButtonEvent
ButtonMap::lookup_shift(int shift_code, int code) const
{
return btn_map[shift_code][code];
}
void
ButtonMap::clear()
{
for(int shift_code = 0; shift_code < XBOX_BTN_MAX; ++shift_code)
{
for(int code = 0; code < XBOX_BTN_MAX; ++code)
{
btn_map[shift_code][code] = ButtonEvent::invalid();
}
}
}
/* EOF */

126
src/button_map.hpp Normal file
View file

@ -0,0 +1,126 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2010 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEADER_XBOXDRV_BUTTON_MAP_HPP
#define HEADER_XBOXDRV_BUTTON_MAP_HPP
#include <assert.h>
#include <iostream>
#include "button_event.hpp"
#include "xboxmsg.hpp"
class ButtonMap
{
private:
ButtonEvent btn_map[XBOX_BTN_MAX][XBOX_BTN_MAX];
public:
ButtonMap();
void bind(int code, const ButtonEvent& event);
void bind(int shift_code, int code, const ButtonEvent& event);
ButtonEvent lookup(int code) const;
ButtonEvent lookup_shift(int shift_code, int code) const;
void clear();
template<class Pred>
bool contains(const Pred& pred)
{
for(int shift_code = 0; shift_code < XBOX_BTN_MAX; ++shift_code)
{
for(int code = 0; code < XBOX_BTN_MAX; ++code)
{
if (pred(btn_map[shift_code][code]))
{
return true;
}
}
}
return false;
}
struct iterator
{
friend class ButtonMap;
private:
ButtonMap& btn_map;
int j;
int i;
iterator(ButtonMap& btn_map_) :
btn_map(btn_map_),
j(0),
i(0)
{}
iterator(ButtonMap& btn_map_, int j_, int i_) :
btn_map(btn_map_),
j(j_),
i(i_)
{}
public:
void operator++()
{
assert(j < XBOX_BTN_MAX);
i += 1;
if (i == XBOX_BTN_MAX)
{
i = 0;
j += 1;
}
}
const ButtonEvent& operator*() const
{
return btn_map.btn_map[j][i];
}
const ButtonEvent& operator->() const
{
return btn_map.btn_map[j][i];
}
ButtonEvent& operator*()
{
return btn_map.btn_map[j][i];
}
ButtonEvent& operator->()
{
return btn_map.btn_map[j][i];
}
bool operator!=(const iterator& rhs) const
{
assert(&btn_map == &rhs.btn_map);
return (j != rhs.j || i != rhs.i);
}
};
iterator begin() { return iterator(*this); }
iterator end() { return iterator(*this, XBOX_BTN_MAX, 0); }
};
#endif
/* EOF */

View file

@ -180,7 +180,7 @@ CommandLineOptions::CommandLineOptions() :
.add_text("Report bugs to Ingo Ruhnke <grumbel@gmx.de>");
}
void set_ui_button_map(ButtonEvent* ui_button_map, const std::string& str)
void set_ui_button_map(ButtonMap& ui_button_map, const std::string& str)
{
std::string::size_type i = str.find_first_of('=');
if (i == std::string::npos)
@ -196,7 +196,7 @@ void set_ui_button_map(ButtonEvent* ui_button_map, const std::string& str)
if (btn != XBOX_BTN_UNKNOWN)
{
ui_button_map[btn] = event;
ui_button_map.bind(btn, event);
}
else
{
@ -367,8 +367,7 @@ CommandLineOptions::parse_args(int argc, char** argv)
case OPTION_UI_CLEAR:
std::fill_n(opts.uinput_config.axis_map, static_cast<int>(XBOX_AXIS_MAX), AxisEvent::invalid());
for(int i = 0; i < XBOX_BTN_MAX; ++i)
std::fill_n(opts.uinput_config.btn_map[i], static_cast<int>(XBOX_BTN_MAX), ButtonEvent::invalid());
opts.uinput_config.btn_map.clear();
break;
case OPTION_UI_AXISMAP:
@ -376,7 +375,7 @@ CommandLineOptions::parse_args(int argc, char** argv)
break;
case OPTION_UI_BUTTONMAP:
arg2apply(opt.argument, boost::bind(&set_ui_button_map, opts.uinput_config.btn_map[XBOX_BTN_UNKNOWN], _1));
arg2apply(opt.argument, boost::bind(&set_ui_button_map, opts.uinput_config.btn_map, _1));
break;
case OPTION_ID:

View file

@ -33,19 +33,40 @@
#include "uinput.hpp"
#include "uinput_deviceid.hpp"
bool is_keyboard_event(const ButtonEvent& event)
{
if (event.type == EV_KEY && uInput::is_keyboard_button(event.code))
{
return true;
}
else
{
return false;
}
}
bool is_mouse_event(const ButtonEvent& event)
{
if (event.type == EV_KEY && uInput::is_mouse_button(event.code))
{
return true;
}
else if (event.type == EV_REL)
{
return true;
}
else
{
return false;
}
}
bool
uInput::need_keyboard_device()
{
for(int j = 0; j < XBOX_BTN_MAX; ++j)
if (cfg.btn_map.contains(is_keyboard_event))
{
for(int i = 0; i < XBOX_BTN_MAX; ++i)
{
if (cfg.btn_map[j][i].type == EV_KEY &&
is_keyboard_button(cfg.btn_map[j][i].code))
{
return true;
}
}
return true;
}
for(int i = 0; i < XBOX_AXIS_MAX; ++i)
@ -64,20 +85,9 @@ uInput::need_keyboard_device()
bool
uInput::need_mouse_device()
{
for(int j = 0; j < XBOX_BTN_MAX; ++j)
if (cfg.btn_map.contains(is_mouse_event))
{
for(int i = 0; i < XBOX_BTN_MAX; ++i)
{
if (cfg.btn_map[j][i].type == EV_KEY &&
is_mouse_button(cfg.btn_map[j][i].code))
{
return true;
}
else if (cfg.btn_map[j][i].type == EV_REL)
{
return true;
}
}
return true;
}
for(int i = 0; i < XBOX_AXIS_MAX; ++i)
@ -131,12 +141,9 @@ uInput::uInput(const XPadDevice& dev, uInputCfg config_) :
create_uinput_device(0);
}
for(int j = 0; j < XBOX_BTN_MAX; ++j)
for(ButtonMap::iterator i = cfg.btn_map.begin(); i != cfg.btn_map.end(); ++i)
{
for(int i = 0; i < XBOX_BTN_MAX; ++i)
{
cfg.btn_map[j][i].device_id = create_uinput_device(cfg.btn_map[j][i]);
}
(*i).device_id = create_uinput_device(*i);
}
for(int i = 0; i < XBOX_AXIS_MAX; ++i)
@ -657,9 +664,9 @@ uInput::update(int msec_delta)
if (i->time >= i->next_time)
{
get_mouse_uinput()->send(EV_REL, cfg.btn_map[XBOX_BTN_UNKNOWN][i->button].code,
static_cast<int>(cfg.btn_map[XBOX_BTN_UNKNOWN][i->button].rel.value * button_state[i->button]));
i->next_time += cfg.btn_map[XBOX_BTN_UNKNOWN][i->button].rel.repeat;
get_mouse_uinput()->send(EV_REL, cfg.btn_map.lookup(i->button).code,
static_cast<int>(cfg.btn_map.lookup(i->button).rel.value * button_state[i->button]));
i->next_time += cfg.btn_map.lookup(i->button).rel.repeat;
needs_syncronization = true;
}
}
@ -680,7 +687,7 @@ uInput::send_button(int code, bool value)
{
button_state[code] = value;
const ButtonEvent& event = cfg.btn_map[XBOX_BTN_UNKNOWN][code];
const ButtonEvent& event = cfg.btn_map.lookup(code);
send_key(event.device_id, event.code, value);
}
@ -803,7 +810,7 @@ uInput::add_axis(int code, int min, int max)
void
uInput::add_button(int code)
{
const ButtonEvent& event = cfg.btn_map[XBOX_BTN_UNKNOWN][code];
const ButtonEvent& event = cfg.btn_map.lookup(code);
if (event.type == EV_KEY)
{

View file

@ -102,8 +102,9 @@ private:
bool need_keyboard_device();
bool need_joystick_device();
bool is_mouse_button(int ev_code);
bool is_keyboard_button(int ev_code);
public:
static bool is_mouse_button(int ev_code);
static bool is_keyboard_button(int ev_code);
};
#endif

View file

@ -29,44 +29,41 @@ uInputCfg::uInputCfg() :
force_feedback(false),
extra_devices(true)
{
for(int i = 0; i < XBOX_BTN_MAX; ++i)
std::fill_n(btn_map[i], static_cast<int>(XBOX_BTN_MAX), ButtonEvent::invalid());
btn_map.clear();
std::fill_n(axis_map, static_cast<int>(XBOX_AXIS_MAX), AxisEvent::invalid());
ButtonEvent* bmap = btn_map[XBOX_BTN_UNKNOWN]; // FIXME: little hacky to abuse XBOX_BTN_UNKNOWN
// Button Mapping
bmap[XBOX_BTN_START] = ButtonEvent::create(EV_KEY, BTN_START);
bmap[XBOX_BTN_GUIDE] = ButtonEvent::create(EV_KEY, BTN_MODE);
bmap[XBOX_BTN_BACK] = ButtonEvent::create(EV_KEY, BTN_SELECT);
btn_map.bind(XBOX_BTN_START, ButtonEvent::create(EV_KEY, BTN_START));
btn_map.bind(XBOX_BTN_GUIDE, ButtonEvent::create(EV_KEY, BTN_MODE));
btn_map.bind(XBOX_BTN_BACK, ButtonEvent::create(EV_KEY, BTN_SELECT));
bmap[XBOX_BTN_A] = ButtonEvent::create(EV_KEY, BTN_A);
bmap[XBOX_BTN_B] = ButtonEvent::create(EV_KEY, BTN_B);
bmap[XBOX_BTN_X] = ButtonEvent::create(EV_KEY, BTN_X);
bmap[XBOX_BTN_Y] = ButtonEvent::create(EV_KEY, BTN_Y);
btn_map.bind(XBOX_BTN_A, ButtonEvent::create(EV_KEY, BTN_A));
btn_map.bind(XBOX_BTN_B, ButtonEvent::create(EV_KEY, BTN_B));
btn_map.bind(XBOX_BTN_X, ButtonEvent::create(EV_KEY, BTN_X));
btn_map.bind(XBOX_BTN_Y, ButtonEvent::create(EV_KEY, BTN_Y));
bmap[XBOX_BTN_GREEN] = ButtonEvent::create(EV_KEY, BTN_0);
bmap[XBOX_BTN_RED] = ButtonEvent::create(EV_KEY, BTN_1);
bmap[XBOX_BTN_YELLOW] = ButtonEvent::create(EV_KEY, BTN_2);
bmap[XBOX_BTN_BLUE] = ButtonEvent::create(EV_KEY, BTN_3);
bmap[XBOX_BTN_ORANGE] = ButtonEvent::create(EV_KEY, BTN_4);
btn_map.bind(XBOX_BTN_GREEN, ButtonEvent::create(EV_KEY, BTN_0));
btn_map.bind(XBOX_BTN_RED, ButtonEvent::create(EV_KEY, BTN_1));
btn_map.bind(XBOX_BTN_YELLOW, ButtonEvent::create(EV_KEY, BTN_2));
btn_map.bind(XBOX_BTN_BLUE, ButtonEvent::create(EV_KEY, BTN_3));
btn_map.bind(XBOX_BTN_ORANGE, ButtonEvent::create(EV_KEY, BTN_4));
bmap[XBOX_BTN_WHITE] = ButtonEvent::create(EV_KEY, BTN_TL);
bmap[XBOX_BTN_BLACK] = ButtonEvent::create(EV_KEY, BTN_TR);
btn_map.bind(XBOX_BTN_WHITE, ButtonEvent::create(EV_KEY, BTN_TL));
btn_map.bind(XBOX_BTN_BLACK, ButtonEvent::create(EV_KEY, BTN_TR));
bmap[XBOX_BTN_LB] = ButtonEvent::create(EV_KEY, BTN_TL);
bmap[XBOX_BTN_RB] = ButtonEvent::create(EV_KEY, BTN_TR);
btn_map.bind(XBOX_BTN_LB, ButtonEvent::create(EV_KEY, BTN_TL));
btn_map.bind(XBOX_BTN_RB, ButtonEvent::create(EV_KEY, BTN_TR));
bmap[XBOX_BTN_LT] = ButtonEvent::create(EV_KEY, BTN_TL2);
bmap[XBOX_BTN_RT] = ButtonEvent::create(EV_KEY, BTN_TR2);
btn_map.bind(XBOX_BTN_LT, ButtonEvent::create(EV_KEY, BTN_TL2));
btn_map.bind(XBOX_BTN_RT, ButtonEvent::create(EV_KEY, BTN_TR2));
bmap[XBOX_BTN_THUMB_L] = ButtonEvent::create(EV_KEY, BTN_THUMBL);
bmap[XBOX_BTN_THUMB_R] = ButtonEvent::create(EV_KEY, BTN_THUMBR);
btn_map.bind(XBOX_BTN_THUMB_L, ButtonEvent::create(EV_KEY, BTN_THUMBL));
btn_map.bind(XBOX_BTN_THUMB_R, ButtonEvent::create(EV_KEY, BTN_THUMBR));
bmap[XBOX_DPAD_UP] = ButtonEvent::create(EV_KEY, BTN_BASE);
bmap[XBOX_DPAD_DOWN] = ButtonEvent::create(EV_KEY, BTN_BASE2);
bmap[XBOX_DPAD_LEFT] = ButtonEvent::create(EV_KEY, BTN_BASE3);
bmap[XBOX_DPAD_RIGHT] = ButtonEvent::create(EV_KEY, BTN_BASE4);
btn_map.bind(XBOX_DPAD_UP, ButtonEvent::create(EV_KEY, BTN_BASE));
btn_map.bind(XBOX_DPAD_DOWN, ButtonEvent::create(EV_KEY, BTN_BASE2));
btn_map.bind(XBOX_DPAD_LEFT, ButtonEvent::create(EV_KEY, BTN_BASE3));
btn_map.bind(XBOX_DPAD_RIGHT, ButtonEvent::create(EV_KEY, BTN_BASE4));
// Axis Mapping
axis_map[XBOX_AXIS_X1] = AxisEvent::create(EV_ABS, ABS_X);
@ -87,39 +84,37 @@ uInputCfg::mimic_xpad()
extra_devices = false;
ButtonEvent* bmap = btn_map[XBOX_BTN_UNKNOWN]; // FIXME: little hacky to abuse XBOX_BTN_UNKNOWN
btn_map.bind(XBOX_BTN_START, ButtonEvent::create(EV_KEY, BTN_START));
btn_map.bind(XBOX_BTN_GUIDE, ButtonEvent::create(EV_KEY, BTN_MODE));
btn_map.bind(XBOX_BTN_BACK, ButtonEvent::create(EV_KEY, BTN_BACK));
bmap[XBOX_BTN_START] = ButtonEvent::create(EV_KEY, BTN_START);
bmap[XBOX_BTN_GUIDE] = ButtonEvent::create(EV_KEY, BTN_MODE);
bmap[XBOX_BTN_BACK] = ButtonEvent::create(EV_KEY, BTN_BACK);
btn_map.bind(XBOX_BTN_A, ButtonEvent::create(EV_KEY, BTN_A));
btn_map.bind(XBOX_BTN_B, ButtonEvent::create(EV_KEY, BTN_B));
btn_map.bind(XBOX_BTN_X, ButtonEvent::create(EV_KEY, BTN_X));
btn_map.bind(XBOX_BTN_Y, ButtonEvent::create(EV_KEY, BTN_Y));
bmap[XBOX_BTN_A] = ButtonEvent::create(EV_KEY, BTN_A);
bmap[XBOX_BTN_B] = ButtonEvent::create(EV_KEY, BTN_B);
bmap[XBOX_BTN_X] = ButtonEvent::create(EV_KEY, BTN_X);
bmap[XBOX_BTN_Y] = ButtonEvent::create(EV_KEY, BTN_Y);
btn_map.bind(XBOX_BTN_GREEN, ButtonEvent::create(EV_KEY, BTN_0));
btn_map.bind(XBOX_BTN_RED, ButtonEvent::create(EV_KEY, BTN_1));
btn_map.bind(XBOX_BTN_YELLOW, ButtonEvent::create(EV_KEY, BTN_2));
btn_map.bind(XBOX_BTN_BLUE, ButtonEvent::create(EV_KEY, BTN_3));
btn_map.bind(XBOX_BTN_ORANGE, ButtonEvent::create(EV_KEY, BTN_4));
bmap[XBOX_BTN_GREEN] = ButtonEvent::create(EV_KEY, BTN_0);
bmap[XBOX_BTN_RED] = ButtonEvent::create(EV_KEY, BTN_1);
bmap[XBOX_BTN_YELLOW] = ButtonEvent::create(EV_KEY, BTN_2);
bmap[XBOX_BTN_BLUE] = ButtonEvent::create(EV_KEY, BTN_3);
bmap[XBOX_BTN_ORANGE] = ButtonEvent::create(EV_KEY, BTN_4);
btn_map.bind(XBOX_BTN_WHITE, ButtonEvent::create(EV_KEY, BTN_TL));
btn_map.bind(XBOX_BTN_BLACK, ButtonEvent::create(EV_KEY, BTN_TR));
bmap[XBOX_BTN_WHITE] = ButtonEvent::create(EV_KEY, BTN_TL);
bmap[XBOX_BTN_BLACK] = ButtonEvent::create(EV_KEY, BTN_TR);
bmap[XBOX_BTN_LB] = ButtonEvent::create(EV_KEY, BTN_TL);
bmap[XBOX_BTN_RB] = ButtonEvent::create(EV_KEY, BTN_TR);
btn_map.bind(XBOX_BTN_LB, ButtonEvent::create(EV_KEY, BTN_TL));
btn_map.bind(XBOX_BTN_RB, ButtonEvent::create(EV_KEY, BTN_TR));
bmap[XBOX_BTN_LT] = ButtonEvent::create(EV_KEY, BTN_TL2);
bmap[XBOX_BTN_RT] = ButtonEvent::create(EV_KEY, BTN_TR2);
btn_map.bind(XBOX_BTN_LT, ButtonEvent::create(EV_KEY, BTN_TL2));
btn_map.bind(XBOX_BTN_RT, ButtonEvent::create(EV_KEY, BTN_TR2));
bmap[XBOX_BTN_THUMB_L] = ButtonEvent::create(EV_KEY, BTN_THUMBL);
bmap[XBOX_BTN_THUMB_R] = ButtonEvent::create(EV_KEY, BTN_THUMBR);
btn_map.bind(XBOX_BTN_THUMB_L, ButtonEvent::create(EV_KEY, BTN_THUMBL));
btn_map.bind(XBOX_BTN_THUMB_R, ButtonEvent::create(EV_KEY, BTN_THUMBR));
bmap[XBOX_DPAD_UP] = ButtonEvent::create(EV_KEY, BTN_BASE);
bmap[XBOX_DPAD_DOWN] = ButtonEvent::create(EV_KEY, BTN_BASE2);
bmap[XBOX_DPAD_LEFT] = ButtonEvent::create(EV_KEY, BTN_BASE3);
bmap[XBOX_DPAD_RIGHT] = ButtonEvent::create(EV_KEY, BTN_BASE4);
btn_map.bind(XBOX_DPAD_UP, ButtonEvent::create(EV_KEY, BTN_BASE));
btn_map.bind(XBOX_DPAD_DOWN, ButtonEvent::create(EV_KEY, BTN_BASE2));
btn_map.bind(XBOX_DPAD_LEFT, ButtonEvent::create(EV_KEY, BTN_BASE3));
btn_map.bind(XBOX_DPAD_RIGHT, ButtonEvent::create(EV_KEY, BTN_BASE4));
// Axis Mapping
axis_map[XBOX_AXIS_X1] = AxisEvent::create(EV_ABS, ABS_X, 16, 128);

View file

@ -21,6 +21,7 @@
#include "axis_event.hpp"
#include "button_event.hpp"
#include "button_map.hpp"
#include "xboxmsg.hpp"
class uInputCfg
@ -34,8 +35,8 @@ public:
bool force_feedback;
bool extra_devices;
ButtonEvent btn_map[XBOX_BTN_MAX][XBOX_BTN_MAX];
AxisEvent axis_map[XBOX_AXIS_MAX];
ButtonMap btn_map;
AxisEvent axis_map[XBOX_AXIS_MAX];
uInputCfg();