void input_manager::init() { std::map<char, action_id> keymap; std::string keymap_file_loaded_from; std::set<action_id> unbound_keymap; load_keyboard_settings(keymap, keymap_file_loaded_from, unbound_keymap); init_keycode_mapping(); load(FILENAMES["keybindings"], false); load(FILENAMES["user_keybindings"], true); if (keymap_file_loaded_from.empty() || (keymap.empty() && unbound_keymap.empty())) { // No keymap file was loaded, or the file has no mappings and no unmappings, // we can skip the remaining part of the function, especially the save function return; } t_actions &actions = action_contexts["DEFAULTMODE"]; std::set<action_id> touched; for(std::map<char, action_id>::const_iterator a = keymap.begin(); a != keymap.end(); ++a) { const std::string action_id = action_ident(a->second); // Put the binding from keymap either into the global context // (if an action with that ident already exists there - think movement keys) // or otherwise to the DEFAULTMODE context. std::string context = "DEFAULTMODE"; if (action_contexts[default_context_id].count(action_id) > 0) { context = default_context_id; } else if (touched.count(a->second) == 0) { // Note: movement keys are somehow special as the default in keymap // does not contain the arrow keys, so we don't clear existing keybindings // for them. // If the keymap contains a binding for this action, erase all the // previously (default!) existing bindings, to only keep the bindings, // the user is used to action_contexts[action_id].clear(); touched.insert(a->second); } add_input_for_action(action_id, context, input_event(a->first, CATA_INPUT_KEYBOARD)); } // Unmap actions that are explicitly not mapped for( const auto &elem : unbound_keymap ) { const std::string action_id = action_ident( elem ); actions[action_id].input_events.clear(); } // Imported old bindings from old keymap file, save those to the new // keybindings.json file. try { save(); } catch(std::exception &err) { debugmsg("Could not write imported keybindings: %s", err.what()); return; } catch(std::string err) { debugmsg("Could not write imported keybindings: %s", err.c_str()); return; } // Finally if we did import a file, and saved it to the new keybindings // file, delete the old keymap file to prevent re-importing it. if (!keymap_file_loaded_from.empty()) { remove_file(keymap_file_loaded_from); } }
void input_manager::init() { init_keycode_mapping(); std::ifstream data_file; std::string file_name = "data/raw/keybindings.json"; data_file.open(file_name.c_str(), std::ifstream::in | std::ifstream::binary); if(!data_file.good()) { throw "Could not read " + file_name; } JsonIn jsin(data_file); //Crawl through once and create an entry for every definition jsin.start_array(); while (!jsin.end_array()) { // JSON object representing the action JsonObject action = jsin.get_object(); const std::string action_id = action.get_string("id"); actionID_to_name[action_id] = action.get_string("name", action_id); const std::string context = action.get_string("category", "default"); // Iterate over the bindings JSON array JsonArray bindings = action.get_array("bindings"); const bool defaultcontext = (context == "default"); while (bindings.has_more()) { JsonObject keybinding = bindings.next_object(); std::string input_method = keybinding.get_string("input_method"); input_event new_event; if(input_method == "keyboard") { new_event.type = CATA_INPUT_KEYBOARD; } else if(input_method == "gamepad") { new_event.type = CATA_INPUT_GAMEPAD; } else if(input_method == "mouse") { new_event.type = CATA_INPUT_MOUSE; } if (keybinding.has_array("key")) { JsonArray keys = keybinding.get_array("key"); while (keys.has_more()) { new_event.sequence.push_back( get_keycode(keys.next_string()) ); } } else { // assume string if not array, and throw if not string new_event.sequence.push_back( get_keycode(keybinding.get_string("key")) ); } if (defaultcontext) { action_to_input[action_id].push_back(new_event); } else { action_contexts[context][action_id].push_back(new_event); } } } data_file.close(); }
void input_manager::init() { init_keycode_mapping(); std::ifstream data_file; picojson::value input_value; std::string file_name = "data/raw/keybindings.json"; data_file.open(file_name.c_str()); if(!data_file.good()) { throw "Could not read " + file_name; } data_file >> input_value; data_file.close(); if(!input_value.is<picojson::array>()) { throw file_name + "is not an array"; } //Crawl through once and create an entry for every definition const picojson::array& root = input_value.get<picojson::array>(); for (picojson::array::const_iterator entry = root.begin(); entry != root.end(); ++entry) { if( !(entry->is<picojson::object>()) ){ debugmsg("Invalid keybinding setting, entry not a JSON object"); continue; } // JSON object representing the action const picojson::value& action_object = *entry; const std::string& action_id = action_object.get("id").get<std::string>(); std::string context = "default"; if(action_object.contains("category")) { context = action_object.get("category").get<std::string>(); } // Iterate over the bindings JSON array const picojson::array& keybindings = action_object.get("bindings").get<picojson::array>(); for (picojson::array::const_iterator subentry = keybindings.begin(); subentry != keybindings.end(); ++subentry) { const picojson::value& keybinding = *subentry; const std::string& input_method = keybinding.get("input_method").get<std::string>(); input_event new_event; if(input_method == "keyboard") { new_event.type = CATA_INPUT_KEYBOARD; } else if(input_method == "gamepad") { new_event.type = CATA_INPUT_GAMEPAD; } if(keybinding.get("key").is<std::string>()) { const std::string& key = keybinding.get("key").get<std::string>(); new_event.sequence.push_back(inp_mngr.get_keycode(key)); } else if(keybinding.get("key").is<picojson::array>()) { picojson::array keys = keybinding.get("key").get<picojson::array>(); for(int i=0; i<keys.size(); i++) { const std::string& next_key = keybinding.get("key").get(i).get<std::string>(); new_event.sequence.push_back(inp_mngr.get_keycode(next_key)); } } if(context == "default") { action_to_input[action_id].push_back(new_event); } else { action_contexts[context][action_id].push_back(new_event); } } if(!action_object.contains("name")) { actionID_to_name[action_id] = action_id; } else { actionID_to_name[action_id] = action_object.get("name").get<std::string>(); } } }