Пример #1
0
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);
    }
}
Пример #2
0
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();
}
Пример #3
0
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>();
        }
    }
}