#🤖│community_dev
1 messages · Page 17 of 1
(that's actually how I found out about this keyboard)
Though the fundamentally broken assumption was that the source would be available
Because all these nerds customize the crap out of everything
You can get quality keyboards with QMK on it and play around with it. Or Input cub's hm TLL, I forgot the abbreviation or Keyboardio's what's the name again.
If we would be making a regular keyboard, we would of used one of the above as well.
But we're not and the above also can't fulfil the requirement for it.
and for what we've made, the most important part is the analog value part.
That's what people really want to play with.
Right, but why not cater to people who know what they're doing enough to see the value of the keyboard?
Bugs get found and fixed and it improves the base product for all the users
So, when we started, we gave raw access to the analog values of the keyboard. But you needed to go pretty low-level to understand it. Then we created the Analog SDK, now you can go much higher-level, more accessible. The next step is to further simplify and build useful tools on top of that.
So you can actually create value
Then firmware such as QMK, TLL and that of keyboardio can also connect with the Analog SDK
and enjoy the same type of valuable creations
Without touching each other's firmware nor limiting it to a single firmware
Because firmware is one hell of a messy work.
eh
I'm not so sure about that
The only messiness I've run into is crappy microprocessor design
Like atmega is so inconsistent
They pretend it's one base design but it's all these diverging things under the same label
There'll always be something, just a matter of what you can accept. But if your realistic and look a the % of the world population that can actually do firmware work. Versus people that can build something in python or javascript or any other language for that matter
You'd rather not create all the value in a single keyboard firmware
More like the percentage of people that can write decent code that does anything
People don't even care about understanding what they're doing
They just mash keys until they end up sweeping the most obvious problems under the rug
In all cases, this is the direction we're taking.
- Focus on value for the end-user
- Make analog input keyboard industry standard
Our firmware is our unique solution and isn't here to become the new standard nor the best firmware that exists nor compete with other open source projects. It's here to simple work exactly how we want it to work in the most efficient and effective way.
Oh, the analog thing
Yeah, I didn't really care much about it
I was slightly interested, but also curious about the switch actuation
Well, in this case, your ideal keyboard is a quality keyboard running QMK or another open-source firmware. Perhaps further down the road , they'll also have analog input hardware and make compatibility in their firmware.
Nah
We'd be actively encouraging and making it available for them to do so however.
But we won't do the firmware work for it. We don't want to do firmware work for others.
But also microcontrollers are slow
If I build something, it won't even have firmware
Just components
Alright, sounds like a DIY project then 😄
I still think not having the source open results in a lack of interest from the technically competent who would otherwise contribute
Same problem with the chronos 1.4
But in that case NDA is the limiting factor
That is true, and I don't deny that. We are just not at the point at which this is, for us, the best move forward.
Further down the road however, having more things established and our company/team grown, this might be a different story.
I love the keyboard but I think it lag behind on the software side. Because it is analog you can theoretical do some cool stuff with it that others don't, like per key actuation points. But there are still basic features missing, like macros.
And yes the most people don't care about all the fearures which products offers or don't use them quite often. But because the Wooting keyboards are in the premium class people buy them for a reason and I think if the keyboard would have more special features, more people would buy these because of that. For myself, I bought it because of the possibilities it has. But unfortunately I'm not experience enough to write my own windows driver to create a virtual device that reads the analog input from the keyboard and do all the stuff I want.
What do you mean by macros? AutoFire and the like? It's a ton of work for a small OEM such as wooting to implement stuff like that, and there are plenty of 3rd-party apps out there that will do that kind of stuff
Like for moba, you press a single key but it fires multiple keystrokes.
It's a pretty big project to make a GUI that supports those kinds of things
I know...
Too many OEMs as it is with software that is incompatible with other devices - eg with the wooting s/w you would probably never be able to make a binding for Shift on wooting + click on mouse
It would be possible but of course very complex.
So I just see it as a ton of work for something which is never going to satisfy all cases
It would be possible to add another interface for a mouse in the firmware for thinks like mouse clicks and so on.
But the normal way would be a virtual device for this kind of stuff.
I don't see it as Wooting's responsibility to write software to mutate mouse input
Yeah but the problem is blocking the native functionality of the mouse in that instance
This can be something that "others" do by just using the anolog API but as I say at the moment I'm not capable of.
You don't have to block the normal mouse...
If you wanted to make Shift+Click do something other than click you would
shift+click spams 1... you may well want to block the click
Yes, this would be even more complicated...
Plus stuff like joystick. It's never gonna happen that you would be able to merge input from another device onto the wooting XI or DI controller
Or rather highly unlikely
If the wooting itself handles that in hardware, probably impossible
Plus the alternative is not for you to write code yourself to do it via the API - it's to use a 3rd-party app that's written
Such as UCR, Joystick Gremlin, Input Mapper, Joy2Key, etc, etc
So do UCR support macros?
The new UCR does not currently support sending key combos (eg ALT+F1)
The old AHK version does
Well, the new version could, but we would need to write a custom plugin
in terms of things like rapid fire etc, I think there are some plugins for the old version, don't think we have them for the new one yet, but it would be simple to write
I think Joystick Gremlin has some nice macro stuff IIRC
But all the programs only emulate virtual joysticks right, not keyborads or mouses?
UCR can control keyboard and mouse
it uses the Interception device driver for that
Can send as a physical keyboard or mouse - indistinguishable from the real thing as it is coming from the driver
And you can block the original control?
Yes, it is blocked before the OS sees it
ultra-deep block, even blocks CTRL-ALT-DEL
And your driver hook up the USB driver right?
eh?
You change the control flow how windows handles the USB Bus driver
Interception is a filter driver, attaches to all keyboards and mice
I axpect you need driver signing for this.
It's signed
So you pay for it?
No, interception is not mine
I can get stuff signed tho if I need
Nefarius has a signing cert that he uses for ViGEm
If needs be, could probs raise the cash for my own - I raised the cash for the vJoy signing cert back in the day
We are thinking of trying to write our own version of Interception tho, there are limitations with it that the author wants $$$ to remove
He initially said he wanted $2,200 for a commercial license, then moved the goalposts on us
Then said he wanted $400/month via Patreon
For something he admitted he had already written...
A lot of money...
I expect you don't earn money from your UCR tool.
But to ask people to pay him a salary for 6 months while he added functionality we didn't want, while holding out on the functionality we did want (Which he already had), we said FU
I will never ever charge for it
No interest in making it my living, it's a hobby
Besides, too much burden of expectation if you charge for something
Besides, it's already been financially beneficial - UCR was instrumental in allowing me to change career from IT to Automated Test
anyone know how to decode the profile codes?
Decode?
as in know what keys are assigned to what analog input etc
i mean the wootility somehow does it
It's a GUID. I think they have a database where they look up the assignments
but wouldnt that mean to pmuch have a list of all possible combos?
It's a random generated ID so I don't think you can decode it
oh ya it is so its online database based
it communicated with a server
and send the profile there
and then loads it from there aswell
same but i checked with message analyzer
interesting
and the wootility communicates with dynamodb.us-west-2.amazonaws.com on port 1954
a raw encode would prob be better because it would work offline and save on cost
yeah, that's how i would implement it
how tho
well if i spoof the server that saves em and gives em back i can misuse it aswell
Wait what? Profiles requiring an internet connection?
That should be pretty easy to test.
wouldnt know why else ud get different codes for exactly the same profile
and how it would know what settings to apply
sad that the electron code is all obfuscated
üöus i think they dont like me poking around in it anyway
You can poke around in the wootility to see what it does.
oh we can? nice
so i guess weekend will be spend figuring out how it works
and prob writing my own
It's an Electron app which you can take appart
I'd be surprised if it needed to be online, that would be really stupid.
k will test this real quick i guess
cant share without internet
and cant import
it checks the clipboard for a valid profile string
and only then it shows the import profile button
it checks using the internet
same for sharing
so ya the wootility requires internet
at least for profile sharing/importing
nope
implemented a wrapper in c# but the is_connected function returns false everytime
so.. is_connected can be ignored?
The source on GitHub doesn't search for the twooting PID
^
yeah, guessed so
dont even need to build aurora they prob ship with the sdk dll
just replace dll with the custom one
Yeah true
ah. struct hid_device_info* hid_info = hid_enumerate(WOOTING_ONE_VID, WOOTING_ONE_PID);
Those are defined above
ye. obv changing the defines
Tell me if you get it working with Aurora, I'm curious :D
hm. currently struggling to find the vid and pid
too many usb devices connected
vid is 03EB and pid is FF02
wooting one is 03EB:FF01
so it's just a increment 😄
it works
well.. with the node example it does
aurora does not want to start
niiiice it works
@strong siren
thanks gottz
Ia aurora compatible with wooting two yet?
if you replace the wooting-rgb-sdk.dll with mine, then yes
I'll see if I can add a layout for it
@proud oasis does it might up the numpad if you choose a kb with one?
lemme check
Might not, idk how Simon made wooting.net
nope does not do anything with the numpad
so the wrapper needs a bit of tweaking i assume
but it changes lighting if i press a numpad button
so it's listening to them.
different api i know.
lemme dig through the code
Maybe the size of data sent to the keyboard is getting capped because the one doesn't have nunpad
I don't think there are any limitations to that in Aurora
derp. i should stop hopping between channels
// Converts the array index to a memory location in the RGB buffers
static uint8_t get_safe_led_idex(uint8_t row, uint8_t column) {
const uint8_t rgb_led_index[WOOTING_RGB_ROWS][WOOTING_RGB_COLS] = {
{ 0, NOLED, 11, 12, 23, 24, 36, 47, 85, 84, 49, 48, 59, 61, 73, 81, 80, 113, 114, 115, 116 },
{ 2, 1, 14, 13, 26, 25, 35, 38, 37, 87, 86, 95, 51, 63, 75, 72, 74, 96, 97, 98, 99 },
{ 3, 4, 15, 16, 27, 28, 39, 42, 40, 88, 89, 52, 53, 71, 76, 83, 77, 102, 103, 104, 100 },
{ 5, 6, 17, 18, 29, 30, 41, 46, 44, 90, 93, 54, 57, 65, NOLED, NOLED, NOLED, 105, 106, 107, NOLED },
{ 9, 8, 19, 20, 31, 34, 32, 45, 43, 91, 92, 55, NOLED, 66, NOLED, 78, NOLED, 108, 109, 110, 101 },
{ 10, 22, 21, NOLED, NOLED, NOLED, 33, NOLED, NOLED, NOLED, 94, 58, 67, 68, 70, 79, 82, NOLED, 111, 112, NOLED }
};
if (row < WOOTING_RGB_ROWS && column < WOOTING_RGB_COLS) {
return rgb_led_index[row][column];
} else {
return NOLED;
}
}
lookin good. the numpad is in
Yeah discuss here
dll works great
implemented pmuch a fix so the dll works with both
just wanted to share precompiled dlls for analog and rgb
including source
also PRd it to the repos on GH
bigbrainafk's fix (wooting one and two support)
am i blind or is there no way to set the brightness of the leds with the rgb library?
0 0 0 = black
127 0 0 = dark red
so.. there goes your brightness
#define WOOTING_RGB_ROWS 6
#define WOOTING_RGB_COLS 21
interestingly this was already in
yet wooting_rgb_array_set_full does not change the numpad
@proud pumice the libs are pretty minimalistic
ye. if you want proper brightness controls convert hsl to rgb instead
might work on the sdks or smth over the weekend cause i actually dont want to reverse the wootility. id wish it would be opensource
me too
ah okay. thanks
you can extract the electron app but then you end up with a release build. so.. pretty unreadable javascript
me too was related to the wootility
ya its obfuscated to shit
well not really obfuscated. just minified and optimized
setting the brightness works well but seems pretty inconvenient
thats pmuch obfuscated
but better than nothing. 😄
in js obfusctaed is almost the same as minfying and optimizing
looks the same and reads the same
i dont really see a difference to actual obfuscated code
variable names got replaced with the alphabet (ordered by frequence)
stuff like that is just part of the compile toolchain of webpack
and part of obfuscation
so.. they didn't do that on purpose. it's just part of the design of the toolchain
just saying that the toolchain pmuch obfuscates by default
well it reduces file size
just make it use random 6 character names instead of single letters
so.. less server bandwidth for shipping updates
i kinda see this from an enterprise point of view
i see this from an "the wootility doesnt really benefit from 20kb saved" point of view
cant imagine it saving that much space
it has been proven that gzip pretty much gives the same benefit as minification
so.. it actually does not matter to minify as long as stuff is gzipped
but people don't know.
also if you call .toString on functions they will return the actual code. wich means: it's also stored in ram
one day we get a cpp based wootility
so minification can reduce ram usage
compiling stuff down so it shows up as "native code" is also possible. but that requires some v8 tweaking in electron.
stack tracing that is impossible though
i don't get it
in wooting-usb.h there is #define RGB_RAW_BUFFER_SIZE 96 and it creates four rgb buffers that get initialized with that size. we have 6 rows and 21 cols.. should be sufficient right?
oh it isn't..
the colors_buffer is too small
or is it? i have no clue
@strong siren the problem is not aurora. it's clearly the sdk
(that the numpad does not get colors)
tampered a bit with the raw usb packages. it seems like the firmware restricts it
oooh where is that from
or well update them to new numbers
just update all checks with led index
or well the result of get_safe_led_index
ooh i see now
thats why it wont work
probably wee need a fifth buffer for this
yep we do
will try to add it
dont forget to add a new check for out of bounds tho just in case
ye
@proud oasis does this look corect
good find
wrong channel i guess :S
dont forget to pr it if it works gott
ye this looks nice
also the APP button should be FN
but apart from that it's great
same
ah i forgot that
hyped for the weekend helping out jeroen with some development work on the sdks
apart from that, all other layouts like DE ISO etc. can also be applied
standard layout
well imma go to sleep so i got enough power for the weekend infront of me
would be cool
hf
almost forgot
dont forget to only send the numpad buffer for w2
w1 prob wont like it
ye. already writing TODO comments for that
well then see ya
night
just wondering. screen mode and pause keys are in the wrong order, aren't they?
the wooting ships with them swapped
you can change brightness of the rgb with it
it gets brighter if you fn pause
and darker if you fn print
doesn't work for me
nope, no effect
we should certainly address that to the wooting guys
i guess it can be fixed with a firmware update
yeah, think so. they fixed the multimedia shortcuts aswell
ye they even work without the wootility
ooooh interesting
the fifth buffer seems to be the right one
it's already in the RGB_PARTS enum
HOLY SHIT! IT WORKS!!
what are you working on?
rgb sdk
oh, the numpad thingy?
now i need to make sure wooting ones don't get the fifth rgb buffer
i assume this sdk does not work with multiple wootings anyways right?
don't think so
anyone with a wooting one here and able to test the dll?
works with the twooting just fine
thanks
my keyboard is buggy again. "save to keyboard" just kills it and i don't know why
@quiet root i guess i'm done
Is here a good place to report a (possible) API-related firmware bug in the Two? wooting_rgb_direct_set_key has incorrect handling for key codes >= 96 (numpad, A1/2/3, etc). The API call itself works fine, however the keyboard modifies the wrong key. Numlock and numpad / modify F10; numpad *, -, +, enter, 7, 8, and 9 modify F9; numpad 4, 5, 6, 1, 2, 3, 0, dot, and A1 do nothing; and A2, A3, and FullsizeMode modify the equals key. Using the buffered version via wooting_rgb_array_change_single (and related) work as expected, it's only the direct calls that have the issue. Not sure if it's my end or the keyboard, though.
Here is good
Thanks
@proud oasis maybe check what emonas said out
@proud oasis It works for me.
nvm. I don't have a Wooting One, but I can confirm it works on the Wooting Two over here.
@boreal nest were you using my current implementation? i did fix a bug that didn't drop rgb calls to the numpad section on wooting ones
Fortunately (or unfortunately), the direct calls have no such protection. They just verify the row/col are valid against an internal table (that has the numpad) and passes the key code
The API call goes through fine, and the table appears valid
But yes I am using your current version. Setting keys >=96 works fine if you using the wooting_rgb_array_change_single (and similar) buffered calls works fine, it's just the wooting_rgb_direct_set_key and wooting_rgb_direct_reset_key calls that don't appear to handle them
will fix. hold on
agreed @boreal nest they don't call get_safe_led_idex(row, column);
The buffered ones do not, yeah. But the direct ones do
wooting_usb_send_feature(WOOTING_SINGLE_COLOR_COMMAND, get_safe_led_index(row, column), red, green, blue) is effectively all wooting_rgb_direct_set_key does (ignoring special handling of ANSI vs ISO left shift/return and sanity checks)
So wooting_usb_send_feature(WOOTING_SINGLE_COLOR_COMMAND, 96, 255, 255, 255) is the call for changing numlock to white, however it's actually changing F10
wait
you are calling the usb api directly?
so.. how do you expect sdk protection then 😄
No, I'm using wooting_rgb_direct_set_key
But calling the usb api directly with safe values produces the same result
For testing where the issue is I was cutting out middlemen to try to narrow it down
you on ansi?
Yeah
so i assume i'd just need to make get_safe_led_idex return NOLED on >= 96 if it's a wooting one?
wait.. i'm confused
Yes, that would be good for them. But I'm on a Two :P
Yep. As far as I can tell the call is completely valid
hm. sorry i got to go
No worries
maybe @quiet root can figure this out in my absence
going to go to a article 13 demo now
has prio
Take your time
no gui?
@boreal nest could u test with
dont have a wooting one and dont wanna try tricking it into thinking i got one
I have a Wooting Two, though lol
ohh
he has a wooting two with ansi layout
I take it that this doc is only really accurate for QWERTY layouts?
https://github.com/WootingKb/wooting-analog-sdk/blob/master/resources/keyboard-matrix-scan-index.png
ie column 1, row 2, is Q on QWERTY, and A on AZERTY?
america.. fuck yeah..
Yeah, it's not true scan code
I am just looking now into maybe building some helper functions or something
I have some handy code surrounding this
i looped through all numbers from 0 to 116 and it got wonky in the end
96 is numlock btw
and according to @boreal nest it will trigger a differnent key's rgb
for me at least
Are you ISO or ANSI?
im iso
when i tried setting 96 it also set f10
maybe i just failed to reproduce the issue yet
96/97 set f10, 98-104 sets f9, 105-113 does nothing, and 114-116 sets equals on my end
0-95 work as expected (skipping NO_LED slots)
Having a look at how it reports to the keyboard driver now
it seems to send perfectly normal scancodes
A1-3 and Mode send nothing
just sounds to me as if it addresses the second led controller and not the third one
(the twooting has three if i'm not mistaken)
going to play with it here now.. i'm not on my pc but i have my twooting with me
Does anyone have an ANSI keyboard? even a non-wooting
Can you tell me what your scancode for \ | is ?
that's dec?
ye
the one to the right of Left shift?
0xBF and 0xE2
0xE2 is to the right of left shift
they don't have that on ansi
it's a non existent key
Sorry, my bad
and 0xBF is on a different place for them
the one above enter
they have it below the backspace key and above return
I was talking about where it is on mine 😛
iso has it on the lower left of return
Lower left of return on UK ISO is # ~
ye. that's the key
on ansi it's just above return
on the upper right
directly next to the delete key
I am wondering about \ |, which on UK ISO is right of LShift, on US ANSI is above enter
Wondering if SC is consistent across ANSI/ISO
0xE2
it's a pain to use the german layout on ansi btw cause then you cannot type < > and |
That does not seem to match anything
yeah, thanks, it just confuses me a bit
E2 is a very high scancode and not on any list I can find
Mind you, what I am getting for that key doesn't match up for any table I can find 😛
try 0x3c
i actually have a new problem
just compiled a fresh copy of the rgb sdk
now i cant dllimport in c# anymore
noice
sounds weird
it acts as if i got some name mangling going on
btw you have push perm on my fork
because it claims wooting_rgb_reset isnt a valid entry point
would just add up into the pull request
would be interesting to know if the serial number could give some insight in regards to that
if so, it could be read from it
I don't see how this whole API is feasible without it
unless you load an ANSI or an ISO dll or something
it does some stuff i don't get though
That looks like it is responding to keys?
#define LED_LEFT_SHIFT_ANSI 9
#define LED_LEFT_SHIFT_ISO 7
#define LED_ENTER_ANSI 65
#define LED_ENTER_ISO 62
I don't see that it would be feasible, given the current API, to accurately work out the coordinates of the keys that vary
Yeah, but you would have to wait for one of those keys to be pressed surely to get a clue as to what kind of keyboard it was
<_< >_> there's a private API call for getting the device configuration, which has the keyboard layout. Nothing on the public side, though. Doubt something like the S/N would contain that since it's configurable
OK, sounds like a goer then
... I got way too curious and went digging. Can't help myself sometimes
So we need a layer of abstraction that applies different scancode <-> row/column or something
Even when the new analog API appears, you are always going to need to be able to convert
Wouldn't that be handled in the firmware? The key codes < 96 function fine. Key codes >= 96 work fine on the Two when not using the direct set/reset calls
Ahh
It's very difficult to interop with the wooting with no easy way to translate from between SC and wooting-specific codes
It also allows you a way to get a proper localized name for the key
you can use WinAPI to get layout-specific name for that key
ScanCode input has a code 1..255 plus an "extended" bit
browsers get the same data right?
convention generally is to pack that down to one number 1..512 with >255 signifying extended flag set
(If you want a single number unique ID for each key that is)
So IMHO, the analog API should be written with ScanCode as the UID for each key, and no mention of localized key names for a given code
that's decided at run-time
@proud oasis Heavily depends on mechanism used within browser I spose, but It's probably possible
@knotty night browsers are strainge
i clear on key down
the codes seem to match
' appears with the name "backslash" to me
and < > | as "IntlBackslash"
i didn't dig into the analog sdk yet. i assume it has the same issue as the rgb sdk had before we touched it
ye cause the wooting one and the wooting two have different product id's in usb
via the C# wrapper anyway
look at this
this is what i had to do to get rgb working for the twooting
rgb and analog are separate ye.
could I get a built copy of your dll tho?
lemme took a quick look at the analog sdk
wanna see if my code is happy with it
ta
i'm even using it in aurora right now
what is that, x86 or x64?
it verks!
neatzo
luckily it's open source
oh and i really appreciate the work they put into the wootility right now
I don't really do unmanaged 😦
before i learned how to use assembler in c, i wrote 8086 machine code into memory and flagged it executable. this.. in my opinion is unmanaged code
Well it's not that deep, but it's still outside my comfort zone
what if i tell you that i love javascript
JS is a cool language
so is the keycode thing fixed already?
it's staggering what you can do with it these days
ye.. some node.. some ffi.. voila.. c libraries in js
and creating native c++ modules for nodejs is easy too
Well it seems that the analog SDK is not compatible with the W2, so I am kind of roadblocked
i think @quiet root touched it
no point messing with scancodes if I can't read keys 😛
do have a 64bit dll
would rather x86 if you have it
sec
but i'll take either in a pinch
cheers man
hm. looking through the code.. it should work just fine
what?
the numpad
Result! thank you
when i just press through it fucks up at 96
exactly what was described by Emonas
the dll is not different from ur source except that it exports the wooting_usb functions aswell so i can use wooting_usb_send_feature
which is whats broken
Yeah, similar for me, seemed to be at 98 or something?
can you drop a wooting_usb_send_feature line here?
wooting_usb_send_feature(30, 96, 255, 255, 255)
it basically tells the keyboard to light up a single key and keycode 96 which is the same as if u call set key direct with the row and column for numlock
it's a firmware issue
does it work with the normal wooting_rgb functions?
as in setting just the numlock with row and column?
it works?
can u check with c#?
lemme install visual studio here
one value - code surely?
@knotty night well both are pmuch the same the direct key set gets the 96 from the magic table by row and column
so its pmuch the same as passing 96 directly
well the analog test in the C# wrapper manages to set the colour of NumLock
row 1, col 17 for me
wooting_rgb_array_change_single(1, 17, 0, 0, 0); wooting_rgb_array_update_keyboard(); works fine for changing numlock (96)
wooting_rgb_direct_set_key(1, 17, 0, 0, 0); however does not, and instead changes 0,11 (48, which is F10)
fact i don't like about microsofts visual studio installer: the bandwidth is never maxed out
just fyi in case anyone want to try aurora with twooting support.
this is col / row
but ye. i'm going to use the codes instead of the x/y
just fyi
mklink wooting-rgb-sdk64.dll c:\safe\twooting\wooting-rgb-sdk\windows\x64\Release\wooting-rgb-sdk64.dll
this way i can just compile and re run the tester
just fyi
const uint8_t rgb_led_index[WOOTING_RGB_ROWS][WOOTING_RGB_COLS] = {
{ 0, NOLED, 11, 12, 23, 24, 36, 47, 85, 84, 49, 48, 59, 61, 73, 81, 80, 113, 114, 115, 116 },
{ 2, 1, 14, 13, 26, 25, 35, 38, 37, 87, 86, 95, 51, 63, 75, 72, 74, 96, 97, 98, 99 },
{ 3, 4, 15, 16, 27, 28, 39, 42, 40, 88, 89, 52, 53, 71, 76, 83, 77, 102, 103, 104, 100 },
{ 5, 6, 17, 18, 29, 30, 41, 46, 44, 90, 93, 54, 57, 65, NOLED, NOLED, NOLED, 105, 106, 107, NOLED },
{ 9, 8, 19, 20, 31, 34, 32, 45, 43, 91, 92, 55, NOLED, 66, NOLED, 78, NOLED, 108, 109, 110, 101 },
{ 10, 22, 21, NOLED, NOLED, NOLED, 33, NOLED, NOLED, NOLED, 94, 58, 67, 68, 70, 79, 82, NOLED, 111, 112, NOLED }
};
so this is supposed to be the codes for numpad and A1 - Mode
to me it makes sense now that the iso has left shift on 9 and the ansi on 7. (pcb wiring to the led controller)
as well as the return button difference
@proud oasis You got an x86 build of that rgb sdk?
i can just build it. hold on
cheers
32 bit
also exporting the native usb funcs
typedef enum RGB_PARTS {
PART0,
PART1,
PART2,
PART3,
PART4
} RGB_PARTS;
WOOTINGRGBSDK_API void wooting_usb_set_disconnected_cb(void_cb cb);
WOOTINGRGBSDK_API void wooting_usb_disconnect(bool trigger_cb);
WOOTINGRGBSDK_API bool wooting_usb_find_keyboard();
WOOTINGRGBSDK_API bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t rgb_buffer[]);
WOOTINGRGBSDK_API bool wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3);
WOOTINGRGBSDK_API bool wooting_rgb_kbd_connected(void);
WOOTINGRGBSDK_API void wooting_rgb_set_disconnected_cb(void_cb cb);
WOOTINGRGBSDK_API bool wooting_rgb_reset(void);
WOOTINGRGBSDK_API bool wooting_rgb_direct_set_key(uint8_t row, uint8_t column, uint8_t red, uint8_t green, uint8_t blue);
WOOTINGRGBSDK_API bool wooting_rgb_direct_reset_key(uint8_t row, uint8_t column);
WOOTINGRGBSDK_API bool wooting_rgb_array_update_keyboard(void);
WOOTINGRGBSDK_API void wooting_rgb_array_auto_update(bool auto_update);
WOOTINGRGBSDK_API bool wooting_rgb_array_set_single(uint8_t row, uint8_t column, uint8_t red, uint8_t green, uint8_t blue);
WOOTINGRGBSDK_API bool wooting_rgb_array_set_full(const uint8_t *colors_buffer);
I seemed to need to add , CallingConvention = CallingConvention.Cdecl to my imports which I didn't before
but it's all good, that's what I normally have to do
works with x86 or x64
from what i can see there, i'd say the firmware needs an update
It lit up like a Christmas tree, isn't that what it's supposed to be doing?
na
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
[DllImport("wooting-rgb-sdk64.dll", CharSet = CharSet.Unicode)]
public static extern bool wooting_usb_send_feature(byte commandId, byte parameter0, byte parameter1,
int parameter2, int parameter3);
[DllImport("wooting-rgb-sdk64.dll", CharSet = CharSet.Unicode)]
public static extern void wooting_usb_disconnect(bool triggerCb);
static void Main(string[] args)
{
byte x = 0;
while (x <= 116)
{
Console.Clear();
Console.WriteLine("Setting " + x + " to white");
wooting_usb_send_feature(30, x, 255, 255, 255);
Thread.Sleep(100);
wooting_usb_send_feature(30, x, 0, 0, 0);
x++;
}
wooting_usb_send_feature(32, 0, 0, 0, 0);
wooting_usb_disconnect(false);
}
}
}
thanks to @quiet root for writing this test code
it essentially just iterates through all the id's
that's passing into this:
bool wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3) {
if (!wooting_usb_find_keyboard()) {
return false;
}
uint8_t report_buffer[WOOTING_COMMAND_SIZE];
report_buffer[0] = 0; // HID report index (unused)
report_buffer[1] = 0xD0; // Magic word
report_buffer[2] = 0xDA; // Magic word
report_buffer[3] = commandId;
report_buffer[4] = parameter3;
report_buffer[5] = parameter2;
report_buffer[6] = parameter1;
report_buffer[7] = parameter0;
if (hid_send_feature_report(keyboard_handle, report_buffer, WOOTING_COMMAND_SIZE) == WOOTING_COMMAND_SIZE) {
return true;
}
else {
wooting_usb_disconnect(true);
return false;
}
}
hmmmm
idea
ugly though
bool wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3) {
if (!wooting_usb_find_keyboard()) {
return false;
}
uint8_t report_buffer[WOOTING_COMMAND_SIZE +3];
bool done;
report_buffer[0] = 0; // HID report index (unused)
report_buffer[1] = 0xD0; // Magic word
report_buffer[2] = 0xDA; // Magic word
if (commandId == WOOTING_SINGLE_COLOR_COMMAND && parameter0 >= 96) {
report_buffer[3] = WOOTING_RAW_COLORS_REPORT;
report_buffer[4] = 2; // Slave nr
report_buffer[5] = parameter0 - 96; // Reg start address
report_buffer[6] = parameter1;
report_buffer[7] = parameter2;
report_buffer[8] = parameter3;
uint16_t crc = getCrc16ccitt(((uint8_t*)&report_buffer) +4, 5);
report_buffer[9] = (uint8_t)crc;
report_buffer[10] = crc >> 8;
printf("%u is part of the numpad section\n", parameter0);
printf("cmd: %u\n", report_buffer[3]);
printf("slave number: %u\n", report_buffer[4]);
printf("register offset: %u\n", report_buffer[5]);
printf("red: %u\n", report_buffer[6]);
printf("green: %u\n", report_buffer[7]);
printf("blue: %u\n", report_buffer[8]);
printf("crc: %u\n", report_buffer[9] + (report_buffer[10] << 8));
done = hid_send_feature_report(keyboard_handle, report_buffer, WOOTING_COMMAND_SIZE +3) == WOOTING_COMMAND_SIZE +3;
}
else {
report_buffer[3] = commandId;
report_buffer[4] = parameter3;
report_buffer[5] = parameter2;
report_buffer[6] = parameter1;
report_buffer[7] = parameter0;
done = hid_send_feature_report(keyboard_handle, report_buffer, WOOTING_COMMAND_SIZE) == WOOTING_COMMAND_SIZE;
}
if (done) {
return true;
}
else {
wooting_usb_disconnect(true);
return false;
}
}
this should work but does not
idea @knotty night?
ooooooh i see why
the buffers are actually much more complex than i thought. derp.
12 reds in a row. then nothingness to fill up to 16. then 12 greens in a row.. and so on
i should probably stop trying to break my keyboard
I have the basics down of a wooting wrapper for AutoHotkey
C# wrapper with CLR interface for AHK
Wooting := new WootingWrapper()
keyWatcher := Wooting.Instance.SubscribeKey(GetKeySC("1"), Func("AxisChanged"))
return
AxisChanged(value){
ToolTip % value
}
1::
return
Subscribe to 1 key analog value, and block it
Have not got all keys added to the SC->Row/Col lookup table yet
@boreal nest @quiet root @knotty night @proud pumice i'm sorry to say that.. but i cannot abuse the buffers to work with less than 12 buttons at once.. so i guess it's better to just use the buffers for now.
this issue has to be fixed in firmware unless it is a different usb api command
wooting_usb_send_feature(WOOTING_SINGLE_COLOR_COMMAND, 96, 255, 255, 255);
to
wooting_usb_send_feature(WOOTING_SINGLE_COLOR_COMMAND, 116, 255, 255, 255);
does not work properly.
wooting_usb_send_feature(WOOTING_SINGLE_RESET_COMMAND, 0, 0, 0, 96);
to
wooting_usb_send_feature(WOOTING_SINGLE_RESET_COMMAND, 0, 0, 0, 116);
don't work either
no worries. thanks for your efforts, you did a great job there 😃
look at #archived_feed_us_back i just dropped the latest version of the test code
I have the basics of the AHK wrapper down.
Full control over keys - get events for update of analog values from keys, turn on/off blocking of the digital key, application-specific blocking of the digital key
#include Lib\WootingWrapper.AHK
Wooting := new WootingWrapper()
last := A_TickCount
keyWatcher := Wooting.SubscribeKey("A" ; Subscribe to the A key - use the AHK key name
, Func("AxisChanged") ; Call the Function "AxisChanged" when it changes
, "ahk_class Notepad") ; Key Blocking is only active in Notepad
.SetBlock(1) ; Turn Key Blocking on
return
; Toggle disabling of key, even if in Notepad
F12::
keyWatcher.ToggleBlock() ; Toggle blocking
return
; Called and passed analog value when key changes state
AxisChanged(value){
static threshold := 100
static oldVal := 0
static lastEvent := "NONE"
if (oldVal == 0 && value){
; Press
lastEvent := "INITIAL PRESS"
}
if (oldval < threshold && value >= threshold){
; Press past 50 %
lastEvent := "PRESS PAST THRESH"
} else if (oldval >= threshold && value < threshold){
; Release past 50 %
lastEvent := "RELEASE PAST THRESH"
}
if (oldVal && value == 0){
; Full release
lastEvent := "FULL RELEASE"
}
ToolTip % "Axis Changed. Old Value: " oldVal ", New Value: " value ", Last Event: " lastEvent
oldVal := value
}
^Esc::
ExitApp
Demo for the A key
AxisChanged function fired when analog value changes
A key blocked while in Notepad
Turn on/off blocking with F12
Yeah, I was thinking it was a firmware issue but I wanted to rule other things out first. The buffers are probably a better choice when driving a lot of keys, but I ran into another oddity. Open Wootility -> change Escape to, for example, 184,64,0 (a sort of bronze) -> use wooting_rgb_direct_set_key to change key 0,0 (Escape) to 184,64,0. It changes to a brighter yellow color, inconsistent with the color the Wootility sets. wooting_rgb_array_change_single exhibits the same inconsistent behavor, but it's easier to demo with a single key
@boreal nest remember that if you have some RGB FX active that you only get a brightness of 0 - 30% 
The API disables (or well, pauses) any running FX that's set. I didn't have one enabled, anyway. Lemme get a comparison pic for it, one sec
... if I can get this camera to not wash out the colors
Surrounding keys are set to 192,67,0 via the Wootility while that S is set to 192,67,0 via wooting_rgb_direct_set_key
i noticed that in aurora too. the led's loose dynamic as brighter they get. we should either do some wizzardry to the wootility code to figure this out or just wait
rgb values are pretty much not linear
It must be something about how the firmware handles these commands as the USB calls the Wootility uses to change the values works fine
I've dug through the Wootility already out of curiousity of how it all functions. Implementing the USB calls it uses, I tested changing LEDs and they work the same as from the Wootility with no special handling. Going to use some pseudo-code this time... profileColorMap = getCurrentProfileColorMap(); profileColorMap[0..2] = [ 192, 67, 0 ] /* set Escape explicitly */ setProfileColorMap(profileColorMap); and the LEDs were the proper colors. Putting that color map through wooting_rgb_array_* calls yields the inconsistent colors
Specifically using the non-permanent calls the profile editor uses to preview it on the keyboard (so the normal wooting_rgb_reset() call undoes any changes made)
Not really sure I want to elaborate, since they must not be public for a reason (though the ability to read the current color map would be useful for the public one in my opinion.. have something to fill the wooting_rgb_array_* buffers with) but yeah.. the inconsistency seems limited to the calls the public API uses
imo the sdk should be able todo the same as the wootility
would be useful to also read A1, A2, A3 and the digital profile presence
like.. what mode the keyboard is currently on
reading the original color map could also be useful for tools like aurora. this way the original color scheme could be used as base layer and then any modifications you do based on scripting would apply on top
last night i also came up with an idea that would allow us to have some kind of rgb / analog proxy so multiple applications could use the sdk
essentially checking a mutex to see if a sdk daemon is running and if it's not, the sdk will perform direct usb communication
so people don't necessarily need to install the daemon
To a point I agree the API should be able to do the same as the Wootility. Things like updating the firmware or what appears to be a way to change the serial number, on the other hand, should definitely stay far, far away from any public API
reading colors, reading profiles, applying profiles
well.. applying could stay in the wootility since it does a good job for that i think
I'd be slightly weary of having the proper profile saving calls public as well. Don't need someone going overboard and wiping the saved profiles from the keyboard by accident
hm. reading could also result in games banning analog usage
i kinda flex my thoughts there a bit.. don't take that for granted
as of right now, games and stuff that implements the sdk needs to update the sdk when a new peripheral from wooting arrives
that's bad i think
razer for example just uses a centralized daemon that does the usb stuff and the api just connects to that instead
would also result in less usb api calls since stuff could be grouped
Not much that can be done about that. Suppose you could read what the name of the HID device rather than PID/VID but I'd expect that to be far less reliable
Since the Two, at least, reports a name of "Wooting WootingTwo"
hm. weird name
Eh, vendor name followed by product name
You'd still need to update for new devices that way, come to think of it. Nevermind heh
if the usb api would be separated into a daemon it could also easily be patches for issues
while the sdk itself cannot
there are always devs out there who don't update stuff
when extracting the usb stuff into a separate daemon the question arises how to do the ipc
Right now my main concern is that the public API uses an RGB call that specifically pauses a lot of background tasks running on the keyboard (RGB FX, honoring the Wootility's RGB-related calls, etc) which I'd imagine is to cut down on processor load while it's being driven manually. I don't know what sort of side effects heat/load-wise there would be to driving the LEDs via the Wootility's API since they don't pause the RGB FX
But as it is right now, the Wootility's calls are more accurate when it comes to colors... so it would be the obvious target for devs to use
interestingly, while you run this, the fx do get paused too
even though it's just single key and not using the buffers
and if u close it they are still paused
Sending COLOR_INIT_COMMAND does the pausing. You must follow with RESET_ALL_COMMAND to unpause
but ye. as soon as the application using the sdk will crash, it will not recover back to the unmodified state
unless you do teh reset
color_init_command? i don't send that
And the firmware straight-up crashes if you try to use direct_* or array_* calls before calling init
wooting_usb_find_keyboard automatically calls it as part of the initial discovery
wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0, 0, 0, 0);
i also had a weird crash yesterday that rendered the xinput useless. it just didn't do anything until i rebooted. even after replugging usb
static void Main(string[] args) {
if (!wooting_usb_find_keyboard()) {
Console.WriteLine("no wooting keyboard detected.");
Console.ReadKey();
return;
}
byte x = 0;
while (x <= 116) {
Console.Clear();
Console.WriteLine("switching key id " + x);
wooting_usb_send_feature(30, x, 255, 255, 255);
Thread.Sleep(100);
wooting_usb_send_feature(30, x, 255, 0, 255);
if (x > 0) wooting_usb_send_feature(31, 0, 0, 0, x -1);
x++;
}
wooting_usb_send_feature(32, 0, 0, 0, 0);
wooting_usb_disconnect(false);
}
this is the console app
no color init command
Yeah it's done as part of wooting_usb_find_keyboard
why a sleep tho why not read key
// Once the keyboard is found send an init command and abuse two reads to make a 50 ms delay to make sure the keyboard is ready
cause it iterates from 0 to 116
At that point
so.. readkey would be pain
There's no call for reading back a single key. There's a pair of calls for grabbing the entire map of all keys at once
oh true. it does the color init in the find keyboard code
this also explains why the rgb sdk and the analog sdk are separate
Yeah, and that call pauses the FX and some other things
You could fix that fairly easily
ye
gott did u se the difference between the array setting and the direct setting of key colors?
one sends a completely different usb command than the other
did you see my attempt to fake single key through WOOTING_RAW_COLORS_REPORT?
no
Move them to a wooting_rgb_init function and note down both HID devices (analog is highest interface ID, leds are highest-4)
i failed epicly when i realized how the buffers are actually structured
0x00 - 0x0d is red, 0x10 - 0x1d is green, 0x20 - 0x2d is blue
so.. the buffer has to contain at least 0x2f bytes
i wonder what e and f do
i doubt it's checksums
since it's 16 bit it could be flags or something
I wonder why that pwm map has 48 entries when the only code that uses it explicitly only uses the lower 24
maybe for future shit
well i just explained why it has 48
simply said, look at it
const uint8_t pwm_mem_map[48] =
{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d
};
uint8_t buffer_index = pwm_mem_map[led_index % 24]; though
0x00 to 0x2F is rgb of 12 keys.
That's the only line that uses the pwm map, and it specifically limits to the lower 24
why 24 you ask?
there:
switch (part_number) {
case PART0: {
report_buffer[4] = 0; // Slave nr
report_buffer[5] = 0; // Reg start address
break;
}
case PART1: {
report_buffer[4] = 0; // Slave nr
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
break;
}
case PART2: {
report_buffer[4] = 1; // Slave nr
report_buffer[5] = 0; // Reg start address
break;
}
case PART3: {
report_buffer[4] = 1; // Slave nr
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
break;
}
case PART4: {
if (is_wooting_one) {
return true;
}
report_buffer[4] = 2; // Slave nr
report_buffer[5] = 0; // Reg start address
break;
}
the reg start address
the packages could be twice as big
yes, the pwm_mem_map only is used 50% but you could use the whole map if you just change the outgoing buffer
you could also just change 12 keys instead of 24
or 36
in one usb hid call
True
uint8_t buffer_index = pwm_mem_map[led_index % 24];
buffer_pointer[buffer_index] = red;
buffer_pointer[buffer_index + 0x10] = green;
buffer_pointer[buffer_index + 0x20] = blue;
A single call cannot go above 124 bytes as I recall, though
this is the first time i touch usb so.. no clue. thanks for that intel
WOOTING_REPORT_SIZE is 129. wooting_usb_send_buffer has the first byte 0, next 2 are magic, fourth byte is command, 123 bytes of data, then 2 checksum bytes at the very end
Not sure if that's a USB limitation or a Wooting-imposed limitation though
Keep having to tab to the github for function/variable names. I ported the API over to NodeJS straight (so there's no .dll or anything involved) and expanded it, so the naming conventions are a little different. const { Keyboard } = require('./wooting.js'); let kb = Keyboard.get(); kb.enableLeds(); kb.directSetKey(Keyboard.LEDs.Escape, 255, 255, 255); etc. Was very careful to make sure it was identical to it
Weary on sharing 'cause uhm... there's also Keyboard.getCurrentRgbProfile(), Keyboard.loadRgbProfile(index)...
Using node-hid
NodeJS bindings on top of the same hid library the C API uses
lul what a coincidence
anyways.. i g2g now.. will be back soon and do some testing with the rgb buffer. maybe i find something fun and the whole twootings colors could be set in two usb calls
well.. two for the one, three for the two
would also be interesting if i could just change 12 keys with one call. this would mean i could improve the rgb_buffer0_changed = true; stuff etc.
partitioning
less data = more speed
Given how the colors report call is laid out, it might unfortunately not be possible with it
is this turning into speedwhoring
First 2 bytes are flags for which of the 5 buffers are given from the looks of it
Or well, less so flags and more like.. addressing math? There's 5 total parts, 96 bytes each, for 480 total bytes. That's enough space to fit 160 RGB triplets in. Granted there's dead space in the buffers that are never written to. 120 bytes in total for the Two and 96 for the One. Every 6 keys there's a spacer of 6 bytes. Removing that from the total and there's just enough space for the full key map in 5 calls for the Two and 4 for the One. I don't think you can squeeze less calls out of it with any tricks
Not a single clue what the dead zones are for other than maybe memory alignment
well
the hid command also specifies the command length
so i assume the firmware can see the size of that buffer that is being transferred
so.. the experiment that i'm going to write now will alter the package size to see if it works
I might have an idea of what those odd unused bytes might be in the buffers. Brightness.
oh
i just noticed something interesting
do you have separate color schemes for A1 - A3 and mode?
run this and change the modes
this is interesting
Ah, the moment when not being on Windows and Wine being annoying makes an appearance lol
System.EntryPointNotFoundException: wooting_usb_find_keyboard welp
interesting
well
byte x = 0;
while (x <= 116) {
Console.Clear();
Console.WriteLine("switching key id " + x);
wooting_usb_send_feature(30, x, 255, 255, 255);
Thread.Sleep(100);
wooting_usb_send_feature(30, x, 255, 0, 255);
if (x > 0) wooting_usb_send_feature(31, 0, 0, 0, x -1);
x++;
}
wooting_usb_send_feature(32, 0, 0, 0, 0);
wooting_usb_disconnect(false);
simply run something similar to that and change the modes
i'll capture a video of it now
In theory it shouldn't let you change modes. At least from testing I've done before - the RGB init call blocks the keyboard from making any changes of its own, even capslock/numlock/fnlock don't change for me
Ahhh I see. Even though the keyboard isn't allowed to modify the LEDs, it still honors the mode switching, which changes the active profile. Reset call sets the key to what that key is in the active profile. Neat
yep
would be fun if the firmware would just flag keys that were changed through single
so then the w00ting effects and profile color schemes would shine through as "background" layer
but judging from trial and error i'd say single and buffered is pretty much direct led controller access
except for reset
Would make sense
finally could upload it..
phone -> syncthing -> homeserver
laptop -> samba -> websocket port forwarding proxy i made -> homeserver
ssl cert expired -> websocket proxy didn't work anymore, thus no samba
That's ... one hell of a chain
ye but it even works behind the chinese firewall
since it's valid websocket traffic
https://gitfap.de/GottZ/websocketproxy this is dumb btw
made that with some alcohol during a day
ssh port forwarding would ofc do too
Can verify the unknown bytes of the buffer appear to do nothing at all
Even though it seems perfectly set up for controlling individual key brightness with it
i assume the led controllers have 16 channels and just 12 of them are wired out.
multiplexing has to be done somewhere somehow.. unless we reverse engineer the wooting hardware we could never know for sure xD
Yeah, not keen on going quite that far lol
i would. i just assume the wooting team would be open about this if we just ask politely though
especially in regards to the issues we just figured out
All this started by my crazy idea of having CPU/GPU load/temps show on the F row and number row lol Long since had that done, but curiosity peaked and now picking apart how to do it better
well.. feel free to port Aurora to linux
const leds = {
map: [],
mode: LED_MODES.DIRECT,
init() {
let { DIRECT, ARRAY, NAUGHTY } = LED_MODES;
kb.loadCurrentRgbProfile();
switch (leds.mode) {
case DIRECT: return kb.enableLeds();
case ARRAY: if (!kb.enableLeds()) { return false; } return kb.setColormap(kb.profile.colorMap);
case NAUGHTY: return leds.copyMap(kb.profile.colorMap);
default: return false;
}
},
copyMap(colorMap) {
let { map } = leds;
if (leds.mode != LED_MODES.NAUGHTY) { return false; }
for (let i = 0, l = colorMap.length; i < l; i++) { map[i] = colorMap[i]; }
return true;
},
setKey(key, r, g, b) {
let { DIRECT, ARRAY, NAUGHTY } = LED_MODES;
switch (leds.mode) {
case DIRECT: return kb.directSetKey(key, r, g, b);
case ARRAY: return kb.changeSingleKey(key, r, g, b);
case NAUGHTY:
{ let { map } = leds; map[key*3] = r; map[key*3+1] = g; map[key*3+2] = b; }
return true;
default: return false;
}
},
resetKey(key) {
let { DIRECT, ARRAY, NAUGHTY } = LED_MODES, { colorMap } = kb.profile;
switch (leds.mode) {
case DIRECT: return kb.directResetKey(key);
case ARRAY: return kb.changeSingleKey(key, colorMap[key*3], colorMap[key*3+1], colorMap[key*3+2]);
case NAUGHTY:
{ let { map } = leds; for (let i = 0; i < 3; i++) { map[key*3+i] = colorMap[key*3+i]; } }
return true;
default: return false;
}
},
updateKeys() {
let { DIRECT, ARRAY, NAUGHTY } = LED_MODES;
switch (leds.mode) {
case DIRECT: return true;
case ARRAY: return kb.updateKeyboard();
case NAUGHTY: return kb.setProfileColormap(leds.map);
default: return false;
}
}
};```
This is going to be long, isn't it
... yep
Makes experimenting easier
Hello I am scripting my keyboard with node.js and in basic example I have this code
const ffi = require("ffi")
// Define the functions from the DLL
const wootingAnalog = ffi.Library('./libs/wooting-analog-sdk.dll', {
"wooting_kbd_connected": [ 'bool', [] ],
"wooting_read_analog": [ 'uint8', ['uint8', 'uint8'] ]
});
const keyboardConnected = wootingAnalog.wooting_kbd_connected()
if(!keyboardConnected) {
console.log('Keyboard not connected')
};
// Every millisecond, read the W-key with index 2:2
setInterval(() => {
const row = 2
const column = 2
const analogValue = wootingAnalog.wooting_read_analog(row, column)
console.log(`Analog value: ${analogValue}`)
}, 1)
Its good ?
a simple way to integrate dlls into node
i do have the same Problem as @gusty blaze :/
@gusty blaze @glacial sable npm i ffi in your project. But make sure to install the prerequisites first: https://github.com/nodejs/node-gyp#installation
Hey guys, I just started trying to use the RGB SDK with node, but the wooting_rgb_kbd_connected function always returns false even though my keyboard is connected 
I used the example script btw
ah, I figured this might be what's the problem here: https://github.com/WootingKb/wooting-rgb-sdk/pull/10
😅
Hey guys, I've moved countries last weekend (back to asia) so haven't been able to jump onto everything immediately. I'll get on the PR's today or tomorrow. I also saw the Dinput feedback, thanks @knotty night
Please let me know if there's something important I missed
@hybrid lake
I don't know how important, but with the Wooting Two...
- The Elevator binding in DInput doesn't appear to work and Trigger is missing entirely under Linux
- Escape doesn't appear to work when bound to anything in DInput nor XInput under Linux (using xboxdrv for XInput support)
- Fn+Mode uses Scroll Lock instead of the Two's Mode key
- the USB SINGLE_COLOR_COMMAND and SINGLE_RESET_COMMAND commands don't work correctly for keys >= 96 (numpad, A1/2/3, Mode). 96-97 modify 48 (F10), 98-104 modify 49 (F9), 105-113 do nothing, and 114-116 modify 95 (Underscore)
- don't know if this is an issue or if SINGLE_COLOR_COMMAND and RAW_COLORS_REPORT simply handle RGB differently, but there's some inconsistency between RGB values set to keys/shown on the Wootility and the same values sent over the API. For example, setting a key to 184,64,0 via the Wootility results in an orange, while setting the same value over the API results in more of a yellow
Sorry for so many, but I've been playing around with things a lot the past few days
@boreal nest For 1) can you please test it on https://html5gamepad.com/ again under windows. Elevator would be axis 9 on it.
I'm a Linux user, so "under Windows" is a problem. OS shouldn't matter, though. For me, there's axis 0-8, with Elevator presumably being 7. Binding the same key to Throttle, Elevator, and Accelerator, axis 6 and 8 span 0-255 as expected, but axis 7 remains 0
Year I remember there was a problem with a value under linux...
Oh, I didn't expect it to be a Linux-specific thing. Lemme edit to specify
When I tested it, please give me a few minutes...
Take your time
Yes, Elevator an Trigger are not working under linux for me with W1. The problem is that linux don't understand it. Can't tell for shure because I have to do much more tests.
Did you have problems with the Trigger to?
Yeah, I hadn't tested Trigger. There's not even an axis for it registered it seems
Yes, one is missing and one value are not registered correct.
Yeah. Very strange
I'm kinda onto it because I tested a lot of the HID stuff with the Wooting lately for my self, because I want to learn the HID USB stuff. I'm not finished right now. When I'm finished I want to provide a few improvement to them.
I wish you luck with that
🤔
@boreal nest could u try setting a key to pure red with the wootility and sdk and see if theres a difference
ok and could u also try putting in hex values instead of decimal so 0xYY
maybe we understand the commands wrong
cant really imagine there only being a problem with mixing colors
It's still writing as 24bit RGB either way
code does weird shit sometimes
I don't think it's the command specifically, as the direct set ones also exhibit the behavor
There might be some post-processing that isn't applied to the SDK calls that's the difference. I'm not really sure
but wouldnt it do it on any color then as in even pure red would be less red
Depends on what the post-processing does
thats some weird pp if it only affects rgb values where 2 values are greater than 0
like if its smth that changes the rgb values it would always do it
I think it's more about the individual values. 127,127,127 triggers it as well (the SDK's version of it is brighter)
So it could be adjusting pwm values differently between the SDK and the calls the Wootility makes
Another example: 127,127,0 via the SDK looks closer to 255,220,0 based on me trying to eyeball it
So it definitely seems like there's some post-processing going on firmware-side with the Wootility calls that don't happen via the SDK. But what it's doing exactly I'm not sure
@boreal nest could the 2 look like this maybe? http://hslpicker.com/#7f8000 http://hslpicker.com/#ff0
cause it seems like a luminance thing
i compared both rgbs u send and the most obvious difference was that one was half as bright in HSL
Similar, but the SDK is more orange
Just got my wooting and I haven't been in the loop about any software development going on. Have there been any cool ideas or features using the analog input for typing/programming that you've heard of?
@gusty blaze Ta eu ta réponse
@grizzled wolf i cant think of any good use for analog in typing/programming tbh
How good is the wooting (two) at detecting key press velocity? Is the sample rate of position detection sufficient?
Imagine backspacing a character/word/line depending on how hard you press backspace
j'ai vu @karmic storm
@hybrid lake There are some other issues with DI too, although I am not 100% sure on what is "right and what is "wrong". From what I understand, DI basically only supports 8 usages - X, Y, Z, Rx, Ry, Rz, SL0, SL1.
However, there seem to be some other usages which are aliases of these - eg I think "Wheel" is an alias for X.
From what I understand - "Elevator" is not one of these axes, and this is borne out by the fact that I cannot bind it in any of the games that I have tried
Also, some of the axes in Wootility only have one binding (eg "Throttle"), whereas most have high/low (eg X, Y etc).
In DI, AFAIK axes are not flagged as being a "normal / centering" or "pedal / trigger" type axis - you could, in theory, use any axis for either a normal or a pedal style axis
So IMHO what needs to be done is all axes in Wootility should have two bindings for them, but all of them should support only one key being bound to either high or low
In that instance, that one key should use all the axis (Like the throttle axis does now)
Or, as mentioned before, once you bind a 2nd key to that axis, it should split the axis between the two keys
Interestingly, "Elevator" does show up in DIView
So not quite sure what is going on there.
It doesn't show up in joy.cpl tho
@knotty night As far as I found informations on this Dinput supports 8 axis and 2 sliders (Throttle and Rudder, but the last is supported by the hardware but not allocable in the wootility). Because the other three (Elevator, Accelerator, Trigger) are not supported by the Dinput interface you can't see them under "joy.cpl" and DIView.
AFAIK it's 8 axes including the 2 sliders
The throttle / wheel axes appear to be aliases
Its different but transparent for the applications.
right
Yes, they are aliases
And yes, to split up the two sliders would be a good think, like one for 0.5 to 1.0 and the other from 0.5 to 0. Because it can be calibrated on the Dinput interface there are no downfalls I think.
But not all applications seems to use the Dinput interface.
Well, it's not technically hard to have it so that no matter if one key or two keys are bound to an axis, the full range is used
(Maths-wise anyway)
You are familar with using the Dinput interface or?
But it uses the DirectX API so I guess it uses Dinput.
You programm rely on the values from the same values that you can see in "joy.cpl" right?
But it doesn't shield you from the underlying API too much
So if you calibrate the controller under "joy.cpl" did it effect your values too or not?
Yeah, in SharpDX, DI uses the native ushort values, and XI uses the native short values
?
DirectInput reports axis values as short (0..65535)
Did a controller calibration changes the value you see?
XInput reports axis values as ushort -32768...32767
In DI, when you read an axis, you get the post calibration values
(Black values in DIView)
I'm confussed because a Xbox 360 Controller only have possitive values.
No the HID Report Descriptor from the Xbox 360 controller form my W1.
You can see the picture of it in the helpdesk section
The Xinput API reports values in the range -32768..32767 for normal axes, 0..255 for triggers
I dunno what it uses at the HID level
Oh my god, have you SEEN the HID usage tables - the amount of crazy stuff that is in the spec??
Like they have a whole "Sports" usage page, with a specially defined usage for golf clubs
Ok, you are right. I caputured the data. Its from -32768 to 0 to 32767.
Annoyingly, it's not possible to perfectly convert between DI and XI ranges
Yes, there are a lot special stuff, and nearly noone uses this.
DI considers mid-point to be 32767
On DI, the upper side of the scale is bigger, but on XI the lower side of the scale is bigger
So if you just shift scale up / down to convert DI/XI, your mid-point will be off by 1
Just shifted, but I saw the RAW data, and its seems to be signed, because on the deppest press for down I got x8000 and for up x7fff.
Also, when working with stick axes, if using signed integers, bear in mind that you cannot invert a signed integer with * -1 !!
-32768 * -1 == -32768!!
if using a short
Amazed at how many coders don't realize that - have caught out numerous people with that in job interviews 😛
I forgot this things long time ago, was like *-1 and plus or minus 1 or something like that.
Give me a few minutes...
There's no one "right" answer
There is one
that only doesnt work for -32768 tho
-2 = ^(2 - 1)
since the result would be 32768 which overflows to -32768
highest positive number is 32767
No Multiplication, bitwise xor
the negative values can be one more than the possitive ones
thats inverting the bits tho
-32768 to 32767
That is what I mean
a value xor with themselves is inverting
no
that is bullshit
no xor at all 😃
a value xor with itself is everytime 0

public static short Invert(short value)
{
if (value == 0) return 0;
if (value == short.MaxValue)
{
return short.MinValue;
}
if (value == short.MinValue)
{
return short.MaxValue;
}
return (short) (value * -1);
}
This is what I use
Has funcs for Deadzone, Sensitivity curves, Invert
And circular DZ
now ur invert misses 1 value tho
Yes, as I said, no perfect solution
You just have to pick a compromise
My thinking is to make sure max deflection is always possible
and lose fidelity at 1 unit from the extremes
where it is likely to be less of an issue
it's one in 65k units, so it's hardly the end of the world, especially if it is not a significant (eg max value or center) point
-32766 being unreachable is hardly a big deal
You can do a negation by multiplictaion with "-1" OR by a subtraction with 1 and a bitwise invertation afterwards. Nearly everytime when you use the first method your complier uses in reality the other method because it is much faster.
oops, -32767 rather
If you use +1 or -1 you will break mid-point
which for me is a bigger deal if you invert an axis and it does not sit at exactly 0
Because of the midpoint you can just use -32767 to 32767
With modern hall sensor sticks, they are that precise that it is noticeable if you have no deadzone
public static short Invert(short number) {
return number == short.MinValue ? short.MaxValue : number * -1;
}
done
now u miss 0 numbers
