konsumer / rm8

M8 headless display - Rust
MIT License
28 stars 4 forks source link

RG353P input bindings #2

Open konsumer opened 1 year ago

konsumer commented 1 year ago

Jack Grbovic said this:

Hey, I can load the M8 on JELOS, but cannot do anything. I feel like this may have something to do with the fact that none of the JSON in the rm8-RG353P seems to correspond with the buttons of the device, it just references buttons on the keyboard (the file named rm8 has all of this in it of course).

konsumer commented 1 year ago

Essentially, if you have JELOS setup, and the joystick is working, it should be fairly automatic. rm8 just uses SDL, so it connects the same input-bindings. rm8-RG353P.json is bound to the joystick id of 190000004b4800000111000000010000. The idea is you rename it to rm8.json, and it will work on that specific joystick GUID. I got this by going into settings with a USB keyboard plugged into the device (Alt + C, then go to J section to bind) and setting up the joystick. A cheap USB-C hub can help with this.

Screenshot 2023-03-31 at 5 51 42 PM

You can see the GUID, but also you should be able to navigate the config with keyboard (SHIFT + arrows), and set each joystick button, under A (axis) and B (buttons) config screens (using Z on your keyboard for A-button, and arrows to scroll through what they do.)

It's a pain, but you should be able to skip most of it by saving your partial config, then merge the 2 JSONs, mostly (the button/axis probly match my joystick, just with a different joystick GUID.)

Screenshot 2023-03-31 at 5 56 17 PM

You can see from the 2 screenshots, I am on a mac, right now. I have a 8bitdo bluetooth SNES-style controller, and so I saved my map, just to inject the ID, then pasted in the joystick section into rm8.json, like this:

  "joysticks": {
    "030082795e040000e002000003096800": {
      "buttons": {
        "15": "Left",
        "16": "Right",
        "8": "Escape",
        "14": "Down",
        "0": "Option",
        "1": "Edit",
        "2": "Play",
        "17": "Escape",
        "3": "Shift",
        "13": "Up",
        "9": "Config"
      },
      "axes": {
        "4": {
          "sensibility": 20000
        },
        "5": {
          "sensibility": 20000
        },
        "3": {
          "sensibility": 20000
        },
        "2": {
          "sensibility": 20000
        },
        "0": {
          "negative": "Left",
          "positive": "Right",
          "sensibility": 20000
        },
        "1": {
          "negative": "Up",
          "positive": "Down",
          "sensibility": 20000
        }
      }
    }
  },

And it seems to match fairly well (axis and buttons seem to work ok) but you can also tune your config to whatever makes sense.

Screenshot 2023-03-31 at 6 00 52 PM Screenshot 2023-03-31 at 6 00 41 PM

Originally, I figured out the button-numbers with a bit of trial-and-error (make a change, see which button does what) but it should save you most of that work. If you are down to test & play with it a bit, I'll totally include a js-config for your device, to save others the work of trying different combos.

psederberg commented 1 year ago

I'm having a similar problem to the original post on my new RG353P. I figured I'd try first with the stock OS, so I installed rm8 into the ports directory as per the instructions. It ran correctly, but with two issues:

  1. The waveform didn't update properly (as in issue #7)
  2. The sound was a bit choppy, even with very simple single instruments

So, I figured I'd try with two brand new (faster) SD cards, one with a fresh JELOS image and the other formatted by JELOS for the games. I followed the same instructions to install rm8 and it opens, but the joystick or buttons have no effect and I have to hard reboot to quit. I don't have a USB-C hub to be able to plug in both the Teensy and a keyboard to try the suggestions above, so I'm wondering if you have any other suggestions or ideas.

Other games and menu navigation works fine, but could it be that there's a different joystick ID for this device? It's strange that it would work just fine on the stock OS, but not work on a fresh JELOS install. Perhaps there is there a simple SDL tool that I could run to print out the GUID of the device to stick into the json file?

Any suggestions for how to proceed would be much appreciated!

konsumer commented 1 year ago

I will look into making a little cli program (run in ssh) to do this. I think it would all be a lot simpler using the SDL gamepad API, which auto-maps different types of joysticks to "like an xbox" (so they have the same layout) using a database of devices. Basically, I could just write code to grab joystick 0, and auto-map it. I am not great with rust, and don;t have a lot of time right now, so implementing this sort of stuff here is very slow for me. I might look into porting it to nim, or something, if I have more time.

  1. This is probably some low-level problem with SDL, or the gpu/cpu is not fast enough to draw it.
  2. The sound is a total hack, taking samples from the input device and sending to output. SDL is very slow for this kind of thing. I suspect this is the problem on windows issue too, as it's even worse at realtime audio stuff, without heavy optimization

Have you tried m8c? I'm not sure what is going on here, but I have a feeling it will take a long time to fix it here (if I don't just rewrite the whole thing in nim.) You will have to deal with routing the audio yourself, but they have instructions for doing it, and linux audio routes really nice and low-latency, with very little cpu usage.

konsumer commented 1 year ago

I wrote this in C, to identify your joysticks:

// gcc -o joylist joylist.c $(pkg-config --libs --cflags sdl2)

#include "SDL.h"

int main(int argc, char* argv[]) {
  SDL_Event event;

  if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
    return 3;
  }

  printf("Ctrl-C to quit.\n");

  while (1) {
    SDL_PollEvent(&event);
    if (event.type == SDL_QUIT) {
      break;
    }

    if (event.type == SDL_JOYDEVICEADDED) {
      SDL_JoystickGUID g = SDL_JoystickGetDeviceGUID(event.jdevice.which);
      char guid[35];
      SDL_JoystickGetGUIDString(g, guid, 35);
      printf("added: %d: %s - %s\n", event.jdevice.which, SDL_JoystickNameForIndex(event.jdevice.which), guid);
    }
  }

  SDL_Quit();
  return 0;
}

On mac, I get this:

Ctrl-C to quit.
added: 0: Nintendo Switch Pro Controller - 030056fb7e0500000920000001006803

I compiled it for arm64 linux, for you: joylist.zip

psederberg commented 1 year ago

Thank you so much! I ssh'd into the RG353p, copied over the joylist exe you compiled, ran it and received the following:

added: 0: retrogame_joypad - 19009b4d4b4800000111000000010000

So, it looks like there's another GUID from either the JELOS or its version of SDL, given that it ran (though with the issues above) on the stock OS. I then simply replaced the GUID in the rm8.json file and it worked right away.

I am also happy to report that the sound is much better, though I can't be sure whether it's JELOS, a newer version of SDL, or the faster SIM cards.

The screen still has the refresh issue. I have no experience with rust, but I do have some with SDL, so I'll try and take a look to see if there's something obvious with the drawing of the waveform. Even if it's lagging, it probably should be clearly the waveform before drawing the next line.

Thanks again for making the script to help me get this going. I'm likely not the only person to run into this, so I hope it helps others until you/we add in the auto-joystick configuration. I think your suggestion for grabbing the first joystick if none are supplied could get most of the way.