Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for 8BitDo Lite SE(There seems to be a bug) #137

Open
CrowKing63 opened this issue May 26, 2024 · 6 comments
Open

Support for 8BitDo Lite SE(There seems to be a bug) #137

CrowKing63 opened this issue May 26, 2024 · 6 comments

Comments

@CrowKing63
Copy link

CrowKing63 commented May 26, 2024

Hello there.

First of all, I would like to thank you very much for working on such a handy project. I've been using an Arduino Leonardo and a USB host shield to remap the numeric keypad for a few years now, and it's relatively simple to remap the numeric keys to mouse clicks for better accessibility, or to set up macros for playing Diablo. I recently discovered that a joystick manufacturer called 8BitDo has released a product aimed at increasing accessibility for people with disabilities. I've tried it out and it's certainly much easier to use than other gamepads, but I have a severe disability, so I don't expect to be able to play games like Zelda using it as is.

In fact, I'm interested in something else. That is to remap the soft joystick of 8BitDo's Lite SE into a kind of 8-button switch(I think this is an economical way to press the most buttons with the least amount of movement. Or not...). To do this, I bought an additional developer board and started to learn about the joystick HID communication protocol, but was immediately frustrated: it's just too hard! I've been trying to figure out how to do it somehow, and I found your HID REMAPPER project. It speaks an unfamiliar language, but seems to be very fully accessible, and for that I am truly grateful.

Sorry, that was a long editorial.

I'm writing this because I'm stuck, and I'm also curious.

  1. does HID REMAPPER support 8BitDo Lite SE properly?

I flashed the "remapper_waveshare_rp2040_pizero.uf2" firmware with the 'r2024-05-23' version on my Waveshare RP2040-PiZero Development Board. After some testing, my mouse (https://www.pulsar.gg/collections/mice/products/xlite-v3-medium-gaming-mouse?variant=44387994173694) was recognized by the web configuration tool just fine, but the wired USB numpad for my Macally laptop (https://www.amazon.com/-/ko/gp/product/B079HF1HLM/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1) didn't even work (probably a power supply issue, judging by the blinking number lock LED?). 8BitDo Lite SE is recognized well. However, the first time I pressed a button(or pushed a joystick) on the 8BitDo Lite SE, the monitor tab of the web configuration tool detected a signal, and the mouse cursor was pushed to the bottom right corner. When I move the mouse cursor, it bounces back up, but until I uninstall the HID REMAPPER, the mouse cursor moves to the bottom right indefinitely. Just in case, I uploaded the previous version (r2024-04-19, remapper_waveshare_rp2040_pizero.uf2), but it doesn't even recognize 8BitDo Lite SE. This is the most recent version, and I have the same symptoms (infinite mouse cursor movement) on Windows as well as Mac. What else can I check? I need advice. If necessary, I'll get a feather board and test different firmware (but the board is out of stock and I doubt I'll ever get it back in stock).

  1. Lack of Expressions slots to turn a joystick into an 8-button switch

Reverse Polish Notation is a strange language to me. Plus I'm a beginner in coding, I think I need eight Expressions slots to turn one joystick into an 8-button switch. But then what about the other joystick? Need More Other Expressions? My simple idea seems to be lacking in eight Expressions slots. Of course, it's a hasty story because I still can't use the 8BitDo Lite SE properly. My first question is whether there are any plans to expand the Expressions slot, and whether there is a smarter way to remap the joystick with an 8-button switch.

As I wrote it, the writing became too long. I'm sorry.

@CrowKing63
Copy link
Author

Just in case, I tried another keyboard at home (I don't know the manufacturer because it's a cheap bundle), but it doesn't turn on at all. Am I doing something wrong? Is the board I bought defective? I don't know...

@jfedor2
Copy link
Owner

jfedor2 commented May 26, 2024

The runaway mouse cursor actually means it's working, believe it or not. To stop it from happening, disable the "Unmapped inputs passthrough" option in the "Settings" tab.

To map directions on an analog stick to keys, use a configuration like this:

Expression 1:

0x00010030 input_state -128 add dup mul /* stick x^2 */
0x00010031 input_state -128 add dup mul /* stick y^2 */
add /* x^2 + y^2 */
sqrt
1 store /* sqrt(x^2+y^2) */
0x00010030 input_state -128 add
0x00010031 input_state -128 add
atan2
2 store /* stick angle */

2 recall 45 gt /* angle > 45 */
135 2 recall gt /* angle < 135 */
mul
1 recall 64 gt /* deadzone */
mul
3 store

2 recall -135 gt /* angle > -135 */
-45 2 recall gt /* angle < -45 */
mul
1 recall 64 gt /* deadzone */
mul
4 store

2 recall 135 gt /* angle > 135 */
-135 2 recall gt /* angle < -135 */
bitwise_or
1 recall 64 gt /* deadzone */
mul
5 store

2 recall -45 gt /* angle > -45 */
45 2 recall gt /* angle < 45 */
mul
1 recall 64 gt /* deadzone */
mul
6 store

Then create mappings with Register 3, 4, 5, 6 as their inputs and whatever keys you want pressed as the outputs.

This gives you four buttons, one per cardinal direction. A similar thing could be done for 8 directions by adding four more similar entries and adjusting the angles.

As you can see with registers you're not limited by the number of expression slots as everything can go into the same slot pretty much.

@CrowKing63
Copy link
Author

It's a really simple and beautiful solution. Thank you for letting me know! I just turned off and tested all of the "Unmapped inputs passthrough" options, and made sure my mouse cursor was properly monitored without running away. Yay !

Looking at the Expressions 1 you wrote down, the method I envisioned was really an infantile idea at the level of 'if ~ else' (laughs). Thank you once again. I will take the time to open the code you wrote carefully and make good use of the registers.

Thank you.

@CrowKing63
Copy link
Author

CrowKing63 commented May 28, 2024

I'm sorry, but I have one more question.

Every time a device is connected for the first time, when the computer is turned on with the device connected, or when it is initialized by changing the settings, it starts with a certain input held.

I've tested it in many ways, and for now it looks like the output you set for Register 4 as input starts with hold.

(Although I changed the register number) If I set a scroll-up on Register 4, the scroll-up starts with a hold every time a device starts up, and when I assign a right mouse button to Register 4, the device will also start as if I were holding that button.

Register 4 is in the west direction, I tested it with the right stick just in case my left stick was defective, but it showed the same symptoms perfectly.

This symptom only occurs at the beginning, and disappears with other manipulations. I have also tried to explicitly initialize the register but it doesn't seem like the cause of the problem. I don't know what the hell is wrong.

I'm worried if I’m asking too a sa scrimbary question. Sorry.

@jfedor2
Copy link
Owner

jfedor2 commented May 28, 2024

Yeah, this is because the analog stick on a gamepad sends 0-255 values and the neutral position is 128, not 0.

After you connect it, or turn everything on, if you don't touch the gamepad, it doesn't send anything until you press some buttons or move the sticks. And HID Remapper's internal state for those inputs defaults to 0, which translates to northwest on the analog stick.

An inelegant solution to this is to change this part of the expression:

2 recall -135 gt /* angle > -135 */
-45 2 recall gt /* angle < -45 */
mul
1 recall 64 gt /* deadzone */
mul
4 store

to read:

2 recall -134 gt /* angle > -134 */
-45 2 recall gt /* angle < -45 */
mul
1 recall 64 gt /* deadzone */
mul
4 store

Making a 1-degree wide gap in the northwest corner that corresponds to the sticks initial position.

A more elegant solution would involve having a flag that basically means "have we seen movement on the stick yet".

Let's say register 32 will be that flag.

Then our expression would look like this:

/* update register 32 to 1 if there's a change in left stick state */
32 recall
0x00010030 input_state
0x00010030 prev_input_state
eq not bitwise_or
0x00010031 input_state
0x00010031 prev_input_state
eq not bitwise_or
32 store

0x00010030 input_state -128 add dup mul /* stick x^2 */
0x00010031 input_state -128 add dup mul /* stick y^2 */
add /* x^2 + y^2 */
sqrt
1 store /* sqrt(x^2+y^2) */
0x00010030 input_state -128 add
0x00010031 input_state -128 add
atan2
2 store /* stick angle */

2 recall 45 gt /* angle > 45 */
135 2 recall gt /* angle < 135 */
mul
1 recall 64 gt /* deadzone */
mul
32 recall mul
3 store

2 recall -135 gt /* angle > -135 */
-45 2 recall gt /* angle < -45 */
mul
1 recall 64 gt /* deadzone */
mul
32 recall mul
4 store

2 recall 135 gt /* angle > 135 */
-135 2 recall gt /* angle < -135 */
bitwise_or
1 recall 64 gt /* deadzone */
mul
32 recall mul
5 store

2 recall -45 gt /* angle > -45 */
45 2 recall gt /* angle < 45 */
mul
1 recall 64 gt /* deadzone */
mul
32 recall mul
6 store

The 32 recall mul part zeroes the value that we put in registers 3, 4, 5, 6 if there hasn't been any change in left stick state yet.

Though this is not perfect either, at least while you work on the configuration - when you save the configuration to the device, the input states are reset, but the register states aren't. So you get the same problem. But during normal use it should be fine. Something to think about for me perhaps.

@CrowKing63
Copy link
Author

Aha! I understood what was going on. Thank you so much for the easy and kind explanation. And thank you again for the solutions you wrote down. As you say, the solutions are elegant. It's like watching a puzzle game broadcast!

Wouldn't it be helpful to set the dead zone to reverse? Like 127 1 recall gt? It's fun because it feels like playing a game!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants