Skip to content

Instantly share code, notes, and snippets.

@kajott
Created August 1, 2019 20:34
Show Gist options
  • Save kajott/7e9d9cd5aacd2c2e38145976ea924f9d to your computer and use it in GitHub Desktop.
Save kajott/7e9d9cd5aacd2c2e38145976ea924f9d to your computer and use it in GitHub Desktop.
joystick quantization visualization
#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