Created
August 1, 2019 20:34
-
-
Save kajott/7e9d9cd5aacd2c2e38145976ea924f9d to your computer and use it in GitHub Desktop.
joystick quantization visualization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if 0 | |
gcc -std=c99 -Wall -Wextra -pedantic -g -O4 -march=native $0 -lm || exit 1 | |
./a.out && feh joymap.ppm | |
exit $? | |
#endif | |
// visualization of analog joystick to 8-way digital direction quantization | |
// see https://github.com/sulix/omnispeak/pull/14 | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define NEW_QUANTIZER 1 | |
#define DEADZONE_PERCENT 30 | |
//#define DIAG_SLOPE 29,70 | |
#define DIAG_SLOPE 1,3 | |
#define OUTPUT_SIZE 256 | |
uint8_t img[OUTPUT_SIZE * OUTPUT_SIZE * 3]; | |
int deadzone, slopeA, slopeB; | |
uint32_t colors[9] = { | |
0x00E0FF, 0x00FF80, 0x80FF00, | |
0x0000FF, 0x000000, 0xFFFF00, | |
0x8000FF, 0xFF0080, 0xFF0000, | |
}; | |
#if NEW_QUANTIZER | |
void process(int inX, int inY, int *outX, int *outY) { | |
if ((inX * inX + inY * inY) < deadzone) { | |
*outX = *outY = 0; | |
return; | |
} | |
int signX = inX >> 31; | |
int signY = inY >> 31; | |
inX = abs(inX); | |
inY = abs(inY); | |
int resX = (inY * slopeA > inX * slopeB) ? 0 : 32767; | |
int resY = (inX * slopeA > inY * slopeB) ? 0 : 32767; | |
if (resX & resY) { resX = resY = 23168; } | |
*outX = (resX ^ signX) - signX; | |
*outY = (resY ^ signY) - signY; | |
} | |
#else | |
void process(int inX, int inY, int *outX, int *outY) { | |
*outX = ((inX * inX) < deadzone) ? 0 : inX; | |
*outY = ((inY * inY) < deadzone) ? 0 : inY; | |
} | |
#endif | |
int main(void) { | |
const int _s[2] = { DIAG_SLOPE }; | |
deadzone = DEADZONE_PERCENT * 32767 / 100; | |
deadzone *= deadzone; | |
slopeA = _s[0]; | |
slopeB = _s[1]; | |
uint8_t* p = img; | |
for (int iy = 0; iy < OUTPUT_SIZE; ++iy) { | |
for (int ix = 0; ix < OUTPUT_SIZE; ++ix) { | |
int x = ((ix * 65536 + 32767 + OUTPUT_SIZE/2) / OUTPUT_SIZE) - 32768; | |
int y = ((iy * 65536 + 32767 + OUTPUT_SIZE/2) / OUTPUT_SIZE) - 32768; | |
bool out = (x*x + y*y) > 0x40000000; | |
process(x, y, &x, &y); | |
x = (x < 0) ? 0 : (x > 0) ? 2 : 1; | |
y = (y < 0) ? 0 : (y > 0) ? 2 : 1; | |
uint32_t color = colors[y * 3 + x]; | |
if (out) { color = (color >> 2) & 0x3F3F3F; } | |
if (ix == (OUTPUT_SIZE / 2)) { color = ~((~color >> 1) & 0x7F7F7F); } | |
if (iy == (OUTPUT_SIZE / 2)) { color = ~((~color >> 1) & 0x7F7F7F); } | |
*p++ = (uint8_t) (color >> 16); | |
*p++ = (uint8_t) (color >> 8); | |
*p++ = (uint8_t) color; | |
} | |
} | |
FILE *f = fopen("joymap.ppm", "wb"); | |
fprintf(f, "P6\n%d %d\n255\n", OUTPUT_SIZE, OUTPUT_SIZE); | |
fwrite(img, OUTPUT_SIZE, OUTPUT_SIZE * 3, f); | |
fclose(f); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment