fqlx / XboxKeyboardMouse

Keyboard and mouse for Xbox One streaming on Windows
Apache License 2.0
316 stars 66 forks source link

Fork strategy. #140

Open Kragrathea opened 6 years ago

Kragrathea commented 6 years ago

Sorry if this this is the wrong place to post this.

I have been using this program for playing Red Dead Redemption 2. For the most part it works great! But I have had to make a few code tweaks to get the best out of RDR2. For example allowing multiple keyboard bindings, two different DeadZone values (one for when aiming) and some changes to the default keyboard layout.

I could submit the changes via pull request. But they are not fully fleshed out (mostly lacking config UI) and some of the changes would break existing XKM configurations.

My goal is allow others to use this RDR version easily. To that end I want to do a binary release. But I also don't want to confuse anyone that it is a new version of the XboxKeyboardMouse app.

So I propose forking this project and creating a new app that can be installed along side this one. Possibly named RDR2XboxKeyboardMouse or RDRXKM or something. This would be a dead end branch only good for RDR2.

Any objections or alternate suggestions?

CallumCarmicheal commented 6 years ago

@Kragrathea Currently the ui is very combersome and i welcome anyway that it can be inproved. When i created that UI i was focusing more on style then functionality.

As for forking, we have a little information base here, any extra questions on this regard just ask.

Im thinking about making a way of extending this app by writing your own plugins and placing them in like a plugin folder although im very early into looking at that possibility. As for now what issue will be breaking existing configurations? I am also thinking about moving from INI files to move to json files which will allow more flexability.

Kragrathea commented 6 years ago

Mostly some hardcoded keybindings so far.

I am currently messing around with using HID to get joystick state so I can pass it through the simulated joystick. RDR only supports one controller at a time and on PC I want to be able to switch back and forth between Mouse/Keyboard and Xbox controller seamlessly.

Also Escape capture is not working for me even on 64bit. I am trying to fix that so I can rebind the Menu button to escape. I keep exiting streaming by mistake.

I would be happy to make a plugin if it supported it. But right now I just want to get it up and running so I can go back to playing RDR.:-)

CallumCarmicheal commented 6 years ago

@Kragrathea Sounds great, alot of those changes can be native if we move to a simpler configuration system something like:

// Plugins that store config information by their plugin id
    "plugins": {
        /*This plugin registers the precentage and precentage_rel engines*/
        "default_engine_percentage":     {
            "percent":  { /*percentage specific options*/ }
            "rel":      { /*percentage_rel specific options*/ }
        },

        /*This plugin registers the raw and raw_sens engines*/
        "default_engine_raw": {
            "raw":  {/*raw specific options*/},
            "sens": {/*raw_sens specific options*/}
        },

        /*This plugin registers the deadzone engine*/
        "default_engine_deadzone": {
            "size": 0,
            "bind_calibrate": "F12",
            "bind_finetune": "F11"
        }
    }

    // Cursor - mouse movement
    "cursor": {
        // INVERT Mouse input
        //      Plugins can ignore this or implement it.
        "invert_x": false,
        "invert_y": false,

        /*Mouse movement engine*/
        "engine": "deadzone"
    },

    // Storing our input inside an array allows for advanced key binding such as multiple keys
    //    per button.
    //
    // 2 required properties, the rest of the properties are optional to allow
    //      plugins to extend and add their own properties to keys, for example check their
    //      last key bind (macro)
    //
    // input:   mouse (these are stored in the button layout of 0 - 3, SLIMDX MouseState),
    //          keyboard.
    //          (possibly add a way of using another controller and passing it through?)
    //          {PLUGIN_EVENT} these are registered on plugin load
    //
    // action:  button,
    //          trigger   { trigger = [ left, right ], value = 0 to 255 }
    //          axis      { axis    = [ left_x, left_y, right_x, right_y ], value = -32,768 to 32,767 }
    //          {PLUGIN_ACTIONS}
    "input": [
        // Example mouse button input
        { "input": "mouse", "key": 0, "action": "axis", "trigger": "left", "value": 255 },

        // Key is the button defined in System.Windows.Input.Key ENUM (Virtual Keys)
        {"input": "keyboard", "key": "D1", "action": "button", "value": "BUTTON_Y"}

        // Toggle button (on and off)
        {"input": "keyboard", "key": "D2", "action": "button_toggle", "value": "BUTTON_Y"}

        // Set the left stick to 255 when ARROW_LEFT is pressed 
        {"input": "keyboard", "key": "Left", "action": "axis", "axis": "left", "value": "255"}

        // Example of a plugin: MACRO_MANAGER
        //      Play a named macro called halo2_bxr that pressed b, then x and fires right trigger.
        {"input": "keyboard", "key": "C", "action": "macro:play", "macro": "halo2_bxr"}
    ]

any thoughts on this layout ?

CallumCarmicheal commented 6 years ago

Accidently closed it, miss click.

Kragrathea commented 6 years ago

I think I see what you are going for. But If you are going to replace the config UI with a text based solution you I think you would be better off with something less complex than Json. Non technical people are probably going to be editing them. The Ini files you are using are actually pretty good. Maybe just expose them better. Say double click the profile opens it in a text editor. And maybe once saved it is also activated? I had some problems with forgetting to save the profile to have my changes take.

One other case to consider if you are going to be doing some redesign. With RDR you need to press two buttons as the same time to activate some features. It would be nice to bind that to one keyboard key. So Keyboard.T = Gamepad.R1 and Gamepad.L1 for example.

CallumCarmicheal commented 6 years ago

@Kragrathea Sorry for the late reply, i was given a ton of work to blast through for Uni and my job.

Okay so for that we could just add a new input type, i thought of that layout because it would be highly extensible and allow for change down the road.

I feel that the issue of people seeing json as complex is very mute, if it is hard for them we can give a tutorial that describes how it works, its a simple process "key", you need quotes surrounded by the key. Here are the required inputs for X command. The issue with INI right now is that for our current system sure it works but its not very extensible. If we wanted to create an array it would take a lot of work in parsing where as in json if needed we can modify the layout and have existing configurations work. Im thinking of ways of future proofing the project for extensibility.

I wont be able to start this for another week or 2, so until then i want to have a good idea on how this could be implemented, a example for your situation is:

...
{ 
   "input": "keyboard", 
   "key": "T", 
   "action": "multi",
   "actions": [
        // Press the buttons at the same time
        { "action": "button", "value": "LEFT_SHOULDER" },
        { "action": "button", "value": "RIGHT_SHOULDER" }
   ] 
},

{ 
   "input": "keyboard", 
   "key": "C", 
   "action": "multi",

   // Basically the same information as other inputs
   // could be an interface like: IAction
   "actions": [
        // Press the buttons at the same time
        { "action": "button", "value": "LEFT_SHOULDER" },
        { "action": "button", "value": "RIGHT_SHOULDER" },

        // Example of using other actions like macros and axis
        { "action": "axis", "axis": "left", "value": "255"}
        { "action": "macro:play", "macro": "halo2_bxr" }
   ] 
},
...
Kragrathea commented 6 years ago

I was able to get everything I needed out of the control bindings by just making two little changes. 1) I used a keymap that would allow a button to be mapped to more than one key (to allow multiple keys to fire one button) and 2) separated the clear button state loop from the set button state loop (allows one key to press multiple buttons). See here: https://github.com/Kragrathea/XKMForRDR2/blob/master/XboxKeyboardMouse/XboxController/Emulation/TranslateKeyboard.cs

Kragrathea commented 6 years ago

I wound up doing a simple text based configuration for the Keyboard. This allows multiple keys per button etc. Of note is that it uses refection (TryParse) to directly map the controller buttons to keyboard keys by enum name. This eliminates a lot of the complexity in the config and allows for buttons to mapped more flexibly. All this is accomplished just in the LoadKeymap() function here and the minor change I make to the input loop mentioned above. https://github.com/Kragrathea/XKMForRDR2/blob/master/XboxKeyboardMouse/XboxController/Emulation/TranslateKeyboard.cs