Homebrew [Android] IRdA - InputRedirection client for Android

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
IRdA (which 100% has nothing to do with IrDa) is an InputRedirection client for Android 3.1 and above.

Note: this application has no on-screen controls. This is only for using external controllers via Bluetooth or USB (or built-in controls for those all-in-one gaming tablets).

Features:
- button binding
- axis binding
- power saving mode*
- persistent config
- "NoDefault" option to disable default Android key press action for unhandled keys
- no accidental config resetting via recovery-style "yes" selection
- autoconnect option on program open

Bugs (wontfix):
- rotating the screen restarts the application
- input is not pollable in the background
- input is not pollable when the screen goes to sleep
- some graphics drivers die when entering power save mode*
- analog triggers aren't bindable to L/R/ZL/ZR
- DPAD behavior is weird

Screenshots:
upload_2018-2-27_8-52-0.png

upload_2018-2-27_8-53-11.png

Usage (first time setup):
1) Download and install IRdA.apk
2) Open IRdA
3) Open menu, and if not checked, check "CAL Button"
4) For each button you want to bind, press that button and follow the on-screen instructions (there aren't any)
5) Open menu, and uncheck "CAL Button"
6) Open menu again, and select "CAL Axis"
7) Follow the on-screen instructions (what instructions?) to bind all axes
8) Select Cancel to exit out of the Axis CAL dialog
9) Open menu, change "Autoconnect" and "NoDefault" to your liking
A) Open menu, select "Set IP" and enter the IP address of your 3DS
B) Open menu, select "Commit config"

Usage:
1) Open IRdA
2) If autoconnect is not set, open menu, and select "Connect"
*) Alternatively touch tne screen to enable power saving mode and prevent the phone from entering sleep mode

*note: on some devices setting the display brightness to 0% will cause the graphics driver to crash every time you try to unlock the device, and thus the backlight will never turn on, and there won't be any screen either (not even if you shine a light at the screen, there's no image). The "<unnamed>" option in menu is not saved, and is there if you want to try out if 0% brightness works on your device without the bad side effects. Please avoid using it, as using it could result in permanent damage to your screen or backlight!

Note: this program uses the standard Android API for polling the joystick for data. If your controller doesn't work then it's most likely not recognized by Android itself, or the controller is reporting incompatible data to the system. Please read the bugs list before posting a bug report!

Download links have been removed. Sorry for the inconvenience.
Try alternative projects, they have more features.
 
Last edited by Sono,

SilverfalconLP

Well-Known Member
Member
Joined
Dec 23, 2013
Messages
111
Trophies
0
Age
40
XP
913
Country
Look good but can you add fakemii proxy?yo your apk(for simulate ninten server Connect for play whithout requiere internet access ,fakemii source on Git)

Sorry im spanish
 
Last edited by SilverfalconLP,

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
Now this app deserves a Thanks and an in-depth review. You did a good job in this App.

1. Simplistic UI is a PLUS. The dark theme seem to consume reasonable amount of battery on my device and i used it for 30 minutes. This app is not power hungry.

2. Button mapping is a PLUS. Easy to configure and use. Now the tricky part is the analog stick mapping but imho, this cant get any simpler. I just got to mess a few tweaks to get what each setting does for the analog but all worked great.

3. Latency is a PLUS. There isnt a significant delay and it feels fluid. I got few crashes at the beginning but eventually made it work.

Known BUGS:
1. C-stick analog/ Right Analog Stick: the X axis is inverted giving the c-stick counterclockwise rotation when iam rotating it clockwise. I cant seem to make it work right even with the available settings for analog mapping.

KUDOS to the well written android app! This is fully functional.
 
  • Like
Reactions: Craftyawesome

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
Now this app deserves a Thanks and an in-depth review. You did a good job in this App.

1. Simplistic UI is a PLUS. The dark theme seem to consume reasonable amount of battery on my device and i used it for 30 minutes. This app is not power hungry.

2. Button mapping is a PLUS. Easy to configure and use. Now the tricky part is the analog stick mapping but imho, this cant get any simpler. I just got to mess a few tweaks to get what each setting does for the analog but all worked great.

3. Latency is a PLUS. There isnt a significant delay and it feels fluid. I got few crashes at the beginning but eventually made it work.

Known BUGS:
1. C-stick analog/ Right Analog Stick: the X axis is inverted giving the c-stick counterclockwise rotation when iam rotating it clockwise. I cant seem to make it work right even with the available settings for analog mapping.

KUDOS to the well written android app! This is fully functional.

1) The dark theme is because not all devices support Holo Dark, so I just programatically forced it to be black, so people who have Holo Dark won't be eyeraped if I were to force black text on white background. Also, it's not power hungry because it's event-based, but there's a timeout so on slow networks it'll send input anyways in case it didn't arrive to the 3DS.

2) It's not easy to use xD Well... button mapping is straight-forward, but axis mapping is very confusing due to having support for joystick axes which only go from 0 to 1, not -1 to 1. There's a checkbox for "Mirror axis", you can use that to invert the direction which gets sent to the 3DS.

3) It has a low latency because it's timeout-event -based. If an input event gets received, the timeout event gets signalled before it could time out, hence it'll send data as soon as it gets acknowledged. As for the crashes, please tell me what crashes you got.
 

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
This app has a lot of potential.
I dont mind the joystick mapping as i totally understand 0 to 1, axis and positive and negative etc. I just dont know if how significantly harder it is to understand for the less technical people. I prefer this manual text status indicators as its less prone to bugs and stuff.


1) As for the crashes, please tell me what crashes you got.

Crashes i encountered are local. Controller to phone connection causes hang. I just need to clear my configs because its all messed up.

The only bug i noticed, and i would deeply appreciate if you look into it, is the C-Stick inverted X- Axis. This couldnt be fixed with the current button mapping. Else, everything is wonderful.
 

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
The only bug i noticed, and i would deeply appreciate if you look into it, is the C-Stick inverted X- Axis. This couldnt be fixed with the current button mapping. Else, everything is wonderful.

I forgot to mention, but the way I wrote the callibration code, it only cares about the axis you press, not the value of the axis. So it doesn't matter you press the right axis to left or right, it'll treat it as if it were pressed in the same direction. When it asks you to set the attributes for that mapping, check the first checkbox to invert the value which gets sent to the 3DS.

Edit: here is the relevant code:
1b7aa36f0f.png

58104dad3d.png

ef03f76d1a.png
 
Last edited by Sono,

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
I did fiddle a bit around the IRdA app and manage to somehow make the axis go with each other. I even tried not touching and mapping it raw with my controller but still, it is inverted.

I did managed to make it the same on the axis with my controller but something is messed up with the combination of x and y axis.

Hopefully someone could test if the same problem persists with their device.
 

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
I did fiddle a bit around the IRdA app and manage to somehow make the axis go with each other. I even tried not touching and mapping it raw with my controller but still, it is inverted.

I did managed to make it the same on the axis with my controller but something is messed up with the combination of x and y axis.

Hopefully someone could test if the same problem persists with their device.

Make sure you're only selecting CStk X1, not X2 (the ones which end in 2 are only there for those controllers where the axes only go from 0 to 1), make sure the third checkbox is checked (Mirror cofig), and select the first or the second checkbox (don't check both), and then click OK. It works on my end just fine :unsure:
 

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
Make sure you're only selecting CStk X1, not X2 (the ones which end in 2 are only there for those controllers where the axes only go from 0 to 1), make sure the third checkbox is checked (Mirror cofig), and select the first or the second checkbox (don't check both), and then click OK. It works on my end just fine :unsure:


Okay. This is wierd. I just remapped my controller regularly and indeed, it just fetches the value of my controller. It could detect the mapped button on regular axes, +/- X and y axes. But when it is combined it is inverted. When i swing my analog to the positive x and y axis, it switches to negative x and y axis. Vice versa.
 

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
What app are you using for this btw? Been off the programming scene for a while since symbian days. Might possibly look into it. Thanks
 

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
What app are you using for this btw? Been off the programming scene for a while since symbian days. Might possibly look into it. Thanks

If you meant how I develop my Android programs, I'm using ye good ol' Eclipse with the DDMS plugin, because I hate the absolute slowness of Gradle. I like how with Eclipse it compiles and sends over the updated build almost instantly, where Android Studio with Gradle takes a whole minute, or more usually two just to compile it!

Other than that, I'm not even using compatibility libraries, just the standard Android API. And the source is... uuuuuuuuuh
d4f2e5c41f.png
yeah, no. It's messy, very hacky, and I have no living power to rebase the UI code as I hate making UIs so much (especially in Android, it makes it a living hell). If you feel like disassembling it, go ahead, but be prepared that the axis callibration code won't give itself so easily :wtf:

Edit: just realized you said you were a Symbian dev... :bow:
 
  • Like
Reactions: chirogan

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
Im not a full pledged Dev. Im just part of a modding/cracking team of symbian apps in a local forum from our country. Was involved in a few projects but then i was in the last breaths of Symbian Era. Android emerged and ios was introduced and symbian was forgotten. I got work and permanently left the scene. Watched it grow with better programmers like you and just moved to console gaming.

Anyway. I will check it out if i got time but i dont expect to fully fix it. Thanks for the heads up btw.

EDIT: i somehow managed to open the package but having trouble translating the language. While im on it, i noticed that the axes are working fine up to a certain value. But when i swing the analog, it switches up to the other side. Maybe just a mixup with the limits. Check out the video so you could visualize the scenario.

 
Last edited by chirogan,
  • Like
Reactions: Sono

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
i somehow managed to open the package but having trouble translating the language

Sorry, I tried my best to make it the least chinglish as possible.

While im on it, i noticed that the axes are working fine up to a certain value. But when i swing the analog, it switches up to the other side. Maybe just a mixup with the limits

I had the same problem, but eventually found what caused it and fixed it. It seems like I didn't fix it after all :/
What percentage does it show when you move your axis to the left or to the right all the way? It should not overflow.

Check out the video so you could visualize the scenario

Sadly I can't see what I should look at on the video. I can't watch videos in higher resolution than 240p, so if I should be looking at something detailed small thing then make a new video in landscape rotation and zoomed in on the important part if it's important to see.
 
  • Like
Reactions: Subtle Demise

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
Sorry, I tried my best to make it the least chinglish as possible.

Nah. I meant my decompiler was garbage. Cant find a decent builder for apk so tge best i could do is find a viewer for classes. Your codes are neat.



I had the same problem, but eventually found what caused it and fixed it. It seems like I didn't fix it after all :/
What percentage does it show when you move your axis to the left or to the right all the way? It should not overflow.

Its good to hear were on the same page to resolve the bug. Wrong choice of words i guess. I mean the limits of referencing the point value. The problem exists not on the axis where we got the value for calibration, its present when we combined the 2 axes. In fact, the x and y axis reads the value perfectly and the problem does not persist on those axes. It becomes present when we move the analogs to the quadrants. Does that makes sense?


Sadly I can't see what I should look at on the video. I can't watch videos in higher resolution than 240p, so if I should be looking at something detailed small thing then make a new video in landscape rotation and zoomed in on the important part if it's important to see.

Sorry for the potato cam quality. Ill try to reupload an HD video. I used another phone and it got downscaled when i transferred it online.

Basically what the video shows are the effect of the bug. On the 3ds, i used @8BitWonder 's app to detect the effect of the keymap presses. The x and y axes works fine. But when i swing the analog in between those axes, the input messes up or changes direction in about 60-80% of the analog stick. I read the codes you wrote above and it value designation seems perfect.

EDIT: Correct me if im wrong but during your for loop, you set i as a container for the axis value and the limit should be one isn't it? Then the value of the bytes just gets inverted if it goes the oppossite side. Here, you wrote the command to increment until it reaches 2.
58104dad3d.png
 
Last edited by chirogan,

Sono

cripple piss
OP
Developer
Joined
Oct 16, 2015
Messages
2,821
Trophies
2
Location
home
XP
9,319
Country
Hungary
Nah. I meant my decompiler was garbage. Cant find a decent builder for apk so tge best i could do is find a viewer for classes. Your codes are neat.

I see. Personally I use BytecodeViewer for Java stuff, but very rarely (when I need to patch the dex bytecode too) I use APK Studio.

Its good to hear were on the same page to resolve the bug. Wrong choice of words i guess. I mean the limits of referencing the point value. The problem exists not on the axis where we got the value for calibration, its present when we combined the 2 axes. In fact, the x and y axis reads the value perfectly and the problem does not persist on those axes. It becomes present when we move the analogs to the quadrants. Does that makes sense?

I don't know what a quadrant is, but I think you mean that when you move your joystick halfway thru' it jumps over and gets inverted. I can't reproduce the bug as I have fixed it for my controller, so sadly I can't attach a debugger to poke where the error happens :(

Sorry for the potato cam quality. Ill try to reupload an HD video. I used another phone and it got downscaled when i transferred it online.

I don't think it was the video quality. As I said, I can't view videos bigger than 240p because it loads so slow that I end up wasting an hour waiting for a video to load while having killed all applications because any other activity will kill the download, essentially having wasted time due to needing to restart the download.

Also, try to film in landscape, that way youtube won't compress the aspect ratio so badly, and it will show up much bigger.

Basically what the video shows are the effect of the bug. On the 3ds, i used 8BitWonder's app to detect the effect of the keymap presses. The x and y axes works fine. But when i swing the analog in between those axes, the input messes up or changes direction in about 60-80% of the analog stick. I read the codes you wrote above and it value designation seems perfect.

Yeah, no matter how many times I re-read the code, I can't see any problem with it. But hey, who knows, I have found a mistake after TWO YEARS in good-looking code, so we may not know yet.

EDIT: Correct me if im wrong but during your for loop, you set i as a container for the axis value and the limit should be one isn't it? Then the value of the bytes just gets inverted if it goes the oppossite side. Here, you wrote the command to increment until it reaches 2.
58104dad3d.png

I don't get what you said, so I'll just explain in-depth what this does:

But first of all, don't let the variable names fool you, it's misleading! MotionEvent is part of the Android API, and by the time it gets here it has been properly filtered, so it's definitely sent by a joystick. The "int axis" parameter is actually the axis for the 3DS!
0 = CPad X
1 = CPad Y
2 = CStick X
3 = CStick Y
4 = DPAD X (partially unused)
5 = DPAD Y (partially unused)

The CitroPad.ckal field is a CitroPad.AxisConfig[6], and contains null if that 3DS axis is not mapped yet, or non-null if at least one of the axes are mapped. Usually both mappings in an AxisConfig are set (because only setting one makes no sense), and are usually perfectly mirrored.

AxisConfig contains two entries because there are some very weird controllers where the ranges go from 0 to 1 instead of -1 to 1 (like most joysticks normally do).

The value of 0xFF is the mask for the axis in MotionEvent, hence it's used as a magic value for invalid/unset axis.
Since you're supposed to set the first entry first, it iterates in order instead of checking both (I was not bothered to hide unset values from the GUI).

ClampAxis converts the --
[at this point I realized where I made the mistake in the program, let me fix it after I type this]
-- axis value provided by Android into the value used internally by my program while doing various checks on it to make sure it's a valid.

After that it checks if the given axis is supposed to be triggered on the negative axis or on the positive axis. If the "axis polarity" matches, it inverts the value --
[realized another fail related to returning a negative value, silly me]
-- so the axis which will be sent to the 3DS will be inverted.

tl;dr: returns a sanitized value from a MotionEvent for the given 3DS axis based on axis config which I can easily work with when sending it to the 3DS. Also, blame Java for not having unsigned.
 

chirogan

The Engineer
Member
Joined
Feb 28, 2018
Messages
379
Trophies
0
XP
396
Country
Philippines
I tried the latest build but still no luck. The right analog stick/ C-stick still changes direction.


I see. Personally I use BytecodeViewer for Java stuff, but very rarely (when I need to patch the dex bytecode too) I use APK Studio.



I don't know what a quadrant is, but I think you mean that when you move your joystick halfway thru' it jumps over and gets inverted. I can't reproduce the bug as I have fixed it for my controller, so sadly I can't attach a debugger to poke where the error happens :(



I don't think it was the video quality. As I said, I can't view videos bigger than 240p because it loads so slow that I end up wasting an hour waiting for a video to load while having killed all applications because any other activity will kill the download, essentially having wasted time due to needing to restart the download.

Also, try to film in landscape, that way youtube won't compress the aspect ratio so badly, and it will show up much bigger.



Yeah, no matter how many times I re-read the code, I can't see any problem with it. But hey, who knows, I have found a mistake after TWO YEARS in good-looking code, so we may not know yet.



I don't get what you said, so I'll just explain in-depth what this does:

But first of all, don't let the variable names fool you, it's misleading! MotionEvent is part of the Android API, and by the time it gets here it has been properly filtered, so it's definitely sent by a joystick. The "int axis" parameter is actually the axis for the 3DS!
0 = CPad X
1 = CPad Y
2 = CStick X
3 = CStick Y
4 = DPAD X (partially unused)
5 = DPAD Y (partially unused)

The CitroPad.ckal field is a CitroPad.AxisConfig[6], and contains null if that 3DS axis is not mapped yet, or non-null if at least one of the axes are mapped. Usually both mappings in an AxisConfig are set (because only setting one makes no sense), and are usually perfectly mirrored.

AxisConfig contains two entries because there are some very weird controllers where the ranges go from 0 to 1 instead of -1 to 1 (like most joysticks normally do).

The value of 0xFF is the mask for the axis in MotionEvent, hence it's used as a magic value for invalid/unset axis.
Since you're supposed to set the first entry first, it iterates in order instead of checking both (I was not bothered to hide unset values from the GUI).

ClampAxis converts the --
[at this point I realized where I made the mistake in the program, let me fix it after I type this]
-- axis value provided by Android into the value used internally by my program while doing various checks on it to make sure it's a valid.

After that it checks if the given axis is supposed to be triggered on the negative axis or on the positive axis. If the "axis polarity" matches, it inverts the value --
[realized another fail related to returning a negative value, silly me]
-- so the axis which will be sent to the 3DS will be inverted.

tl;dr: returns a sanitized value from a MotionEvent for the given 3DS axis based on axis config which I can easily work with when sending it to the 3DS. Also, blame Java for not having unsigned.

Thanks for breaking it down. Ill try to look through it and not get confused.
 
  • Like
Reactions: Sono

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Veho @ Veho: Firefox users be like "look at what they have to do to mimic a fraction of our power."