Skip to content

Commit

Permalink
UPDATED input mapping. Multiple controls can now be assigned to an ac…
Browse files Browse the repository at this point in the history
…tion.

They are stored in the configuration file as a pipe separated string, i.e.

  <Input>
    <a_button>left shift|right shift</a_button>
    <b_button>space</b_button>
    <c_button>left control|right control</c_button>
    <d_button>escape</d_button>
    <move_east>right</move_east>
    <move_north>up</move_north>
    <move_south>down</move_south>
    <move_west>left</move_west>
  </Input>
  • Loading branch information
Kai Sterker committed Oct 17, 2010
1 parent 6efd365 commit 82f04db
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 30 deletions.
34 changes: 34 additions & 0 deletions src/base/configuration.cc
Expand Up @@ -403,3 +403,37 @@ string configuration::create_filename (const string & name) const
// add file name to configuration data directory
return base::Paths.cfg_data_dir () + name + ".xml";
}

vector<string> configuration::split_value (const string & values, const char & separator)
{
string::size_type i, idx, pos = 0;
vector<string> result;

// split pipe separated list of controls
do
{
idx = values.find (separator, pos);
string value = values.substr (pos, idx - pos);

// trim whitespace
if ((i = value.find_last_not_of(' ')) != string::npos)
{
// strip back
value.erase (i + 1);
if ((i = value.find_first_not_of(' ')) != string::npos)
{
// strip front
value.erase (0, i);
}

// found a possibly valid control
result.push_back (value);
}
// else: only whitespace, so we skip it

pos = idx + 1;
}
while (idx != string::npos);

return result;
}
8 changes: 8 additions & 0 deletions src/base/configuration.h
Expand Up @@ -323,6 +323,14 @@ namespace base
* @return %configuration setting.
*/
string get_string (const string & section, const string & option, const string & value);

/**
* Split a string of values into the individual tokens.
* @param values a string of values, delimited by a special character.
* @param separator the delimiting character. Default is a pipe ('|').
* @return list of individual values, with whitespace trimmed.
*/
static vector<string> split_value (const string & values, const char & separator = '|');
//@}

/**
Expand Down
71 changes: 41 additions & 30 deletions src/input/control_event.cc
Expand Up @@ -69,8 +69,8 @@ namespace input
keyboard_event::DOWN_KEY,
keyboard_event::RIGHT_KEY,
keyboard_event::LEFT_KEY,
keyboard_event::LSHIFT_KEY, // run
keyboard_event::SPACE_KEY, // jump
keyboard_event::LSHIFT_KEY, // run
keyboard_event::SPACE_KEY, // jump
keyboard_event::LCTRL_KEY,
keyboard_event::ESCAPE_KEY
};
Expand All @@ -86,42 +86,53 @@ namespace input
// read setting for each of our controls
for (u_int32 i = control_event::UP_BUTTON; i < control_event::NBR_BUTTONS; i++)
{
control_event::button_type btn = (control_event::button_type) i;
control_event::button_type btn = (control_event::button_type) i;

// get name of control (= config option)
key = control_event::name_for_button ((control_event::button_type) btn);

// get mapped control, using given default if not set yet
value = cfg.get_string ("Input", key, keyboard_event::name_for_key (default_key (btn)));

// setup internal mapping tables
keyboard_event::key_type kt = keyboard_event::key_for_name (value);
if (kt != keyboard_event::UNKNOWN_KEY)
{
map_keyboard_key (kt, (control_event::button_type) btn);
continue;
}

mouse_event::button_type mb = mouse_event::button_for_name (value);
if (mb != mouse_event::NO_BUTTON)
// get mapped controls, using given default if not set yet
std::string control_list = cfg.get_string ("Input", key, keyboard_event::name_for_key (default_key (btn)));

std::vector<std::string> controls = base::configuration::split_value (control_list);
if (controls.empty())
{
map_mouse_button (mb, (control_event::button_type) btn);
continue;
// controls might be empty if there was a configuration error
controls.push_back (keyboard_event::name_for_key (default_key (btn)));
}
joystick_event::button_type jb = joystick_event::button_for_name (value);
if (jb != joystick_event::NO_BUTTON)

// we're guaranteed to get back at least one value (the default)
for (std::vector<std::string>::const_iterator value = controls.begin(); value != controls.end(); value++)
{
// TODO: get proper joystick number
map_joystick_button (0, jb, (control_event::button_type) btn);
continue;
// setup internal mapping tables
keyboard_event::key_type kt = keyboard_event::key_for_name (*value);
if (kt != keyboard_event::UNKNOWN_KEY)
{
map_keyboard_key (kt, (control_event::button_type) btn);
continue;
}

mouse_event::button_type mb = mouse_event::button_for_name (*value);
if (mb != mouse_event::NO_BUTTON)
{
map_mouse_button (mb, (control_event::button_type) btn);
continue;
}

joystick_event::button_type jb = joystick_event::button_for_name (*value);
if (jb != joystick_event::NO_BUTTON)
{
// TODO: get proper joystick number
map_joystick_button (0, jb, (control_event::button_type) btn);
continue;
}

// invalid control value --> use default, but don't update configuration
fprintf (stderr, "*** control_event::map_controls: unknown control '%s' for action '%s'!\n", value->c_str(), key.c_str());
kt = default_key (btn);
fprintf (stderr, " substituting default key '%s' instead!\n", keyboard_event::name_for_key (kt).c_str ());
map_keyboard_key (kt, (control_event::button_type) btn);
}

// invalid control value --> use default, but don't update configuration
fprintf (stderr, "*** control_event::map_controls: unknown control '%s' for action '%s'!\n", value.c_str(), key.c_str());
kt = default_key (btn);
fprintf (stderr, " substituting default key '%s' instead!\n", keyboard_event::name_for_key (kt).c_str ());
map_keyboard_key (kt, (control_event::button_type) btn);
}
}

Expand Down

0 comments on commit 82f04db

Please sign in to comment.