enum DirectionBits {
LEFT = 0x01,
RIGHT = 0x02,
UP = 0x04,
DOWN = 0x08
};
int lookup[3][3] = {
{LEFT|UP, UP, UP|RIGHT},
{LEFT, 0, RIGHT},
{LEFT|DOWN,DOWN,DOWN|RIGHT}
};
int dir = lookup[...];
if( dir == UP|LEFT )
DoUpLeftThing();
if( dir & LEFT )
DoAnyLeftThing();
Direction Booleans into single Integer
The single Direction ID is only used to be passed forward to the HID Class Driver. So i am not using it other than that i need to generate and forward it.
When i want to check for directions myself i still have my initial Booleans.
I thought this is a nice way to represent it if you go with a lookup... Array has only the values you need, and theyre arranged visually so its easy to change them if you want. You can easily extend it into 3D too if you need another axis of freedom.int lookup[3][3] = { {8,1,2}, {7,0,3}, {6,5,4} }; int direction = lookup[1+down-up][1+right-left];
That's brilliant. I'm going to steal this from now on instead of the bitfield-lookup approach.
int64_t x = 3 * (up - down) + left - right;
return x * (x * (x * (x * (x * (x * (x * (x * (-31) - 28) + 938) + 840) - 8519) - 6972) + 24412) + 12880) / 3360;
More seriously, the full factorial interaction matrix has 16 different possible coefficients, but the solution had 14 non-zero coefficients. For the polynomial evaluation, there are nine coefficients, and eight of them were non-zero. This basically says that the mapping structure is slightly more regular than just random assignment, but not by much. I'm not going to say there isn't some clever way to do this computation more efficiently, but the horrible brute force techniques aren't simplifying into anything nice.
The more I think about it, there's entirely too much danger that someone might actually understand the full factorial interaction matrix approach I used in my first try. So I give you the polynomial evaluation version:
More seriously, the full factorial interaction matrix has 16 different possible coefficients, but the solution had 14 non-zero coefficients. For the polynomial evaluation, there are nine coefficients, and eight of them were non-zero. This basically says that the mapping structure is slightly more regular than just random assignment, but not by much. I'm not going to say there isn't some clever way to do this computation more efficiently, but the horrible brute force techniques aren't simplifying into anything nice.int64_t x = 3 * (up - down) + left - right; return x * (x * (x * (x * (x * (x * (x * (x * (-31) - 28) + 938) + 840) - 8519) - 6972) + 24412) + 12880) / 3360;
No, it isn't random at all, but rather based on angles!
auto x = (float)right-left;
auto y = (float)up-down;
if(!(x || y)) return 0;
return 1+(int(round((4.f/3.14159265f)*atan2(x, y)))+8)%8;
Wait a second, is this related to a hat device or such? Because it sounds like 0-8 is what the device is returning (it is mentioned it's driver code, and I recall hats being returned as angles). That'd explain why the values can't be changed.
In this case yeah, a look-up table sounds like the best approach.
Yes, it is for my Wiimote Device Driver.
I get the input from the DPad as booleans and need them to be converted to the hat switch angles for the HID report.
So you actually need the opposite look-up table, i.e. you have an entry for each boolean combination and the values in the table are the hat angle.
I'd suggest you to treat opposite directions as negating each other, i.e. if both get pressed simultaneously for some reason then set the table like nothing was pressed. The look-up table would look like this (assuming the order is up, down, left, right):
unsigned dpad_to_hat[] =
{
0, 1, 5, 0,
7, 8, 6, 7,
3, 2, 4, 3,
0, 1, 5, 0
};
It may the best approach, but the branchless polynomial version would be more fun to see in code.
In this case yeah, a look-up table sounds like the best approach.
Even if you comment it out and use the table (which is probably the best idea) it would absolutely make my day to see that commented out in the source code.
// The branchless polynomial version:
// int64_t x = 3 * (up - down) + left - right;
// return x * (x * (x * (x * (x * (x * (x * (x * (-31) - 28) + 938) + 840) - 8519) - 6972) + 24412) + 12880) / 3360;
// the boring but faster table version:
int lookup[9] = ...
I love seeing gems like that in code. It can make me smile for days on end.