GamePortAdapter
Dependencies: mbed-rtos mbed USBDevice USBJoystick
main.cpp
- Committer:
- obsoleet37
- Date:
- 2017-12-21
- Revision:
- 6:43b59cb5dcd9
- Parent:
- 5:c2e3d6e70d85
File content as of revision 6:43b59cb5dcd9:
#include "mbed.h" #include "USBMouseKeyboard.h" #include "USBJoystick.h" #include "rtos.h" #include "string.h" #define min(a, b) (a)<(b) ? (a) : (b) #define max(a, b) (a)>(b) ? (a) : (b) #define clamp(val, floor, ceil) min(max(val, floor), ceil) extern "C" void mbed_reset(); Serial pc(USBTX, USBRX); //macOS: screen /dev/tty.usbmodem{num} {baud rate} //Windows: Realterm class Axis { public: Axis(PinName pin) : _pin(pin) { _t.reset(); _center = 0; _scale = 1.0; _pin.rise(this, &Axis::start); _pin.fall(this, &Axis::stop); } int8_t read() { int val = _t.read_us(); return val < 1000 ? clamp((val - _center)*_scale, -128, 127) : -128; } int16_t read_raw() { return _t.read_us(); } void setup(int center, int range) { _center = center; _scale = 255.0/range; } bool connected() { int val = _t.read_us(); return val == clamp(val, 10, 1000); } private: InterruptIn _pin; Timer _t; int _center; float _scale; void start() { _t.reset(); _t.start(); } void stop() { _t.stop(); } }; Axis x1 = Axis(p15); Axis y1 = Axis(p16); Axis x2 = Axis(p17); Axis y2 = Axis(p18); volatile int buttons; DigitalOut trig(p19); //1st row: necessary garbage, size, mode, reserved, reserved //2nd row: x1 center, x1 range, y1 center, y1 range, reserved //3rd row: x2 center, x2 range, y2 center, y2 range, reserved //following rows: input, min, max, output, value int bindings[128][5]; /*int bindings[128][5] = {{0xFFFFFFFF, 9, 0, 0, 0}, {128, 255, 128, 255, 0}, {128, 255, 128, 255, 0}, {0, 0, 100, 4, (int)'a'}, {0, 400, 1000, 4, (int)'d'}, {1, 0, 100, 4, (int)'w'}, {1, 400, 1000, 4, (int)'s'}, {4, 128, 255, 4, (int)'1'}, {5, 128, 255, 4, (int)'2'}};*/ /*int bindings[8][5] = {{0, 0, 1000, 0, 0}, {1, 0, 1000, 1, 0}, {4, 128, 255, 4, 0x1}, {5, 128, 255, 4, 0x2}};*/ LocalFileSystem local("local"); void analog_trig() { trig = 0; trig = 1; } void debug_thread() { pc.printf("Beginning Joystick Test...\r\n"); pc.printf("---------------------------------\r\n"); while(1) { pc.printf("Joystick 1 - %d, %d, %X \r\n", x1.read_raw(), y1.read_raw(), buttons&0x3); pc.printf("Joystick 2 - %d, %d, %X \r\n", x2.read_raw(), y2.read_raw(), (buttons>>2)&0x3); pc.printf("\r\n"); Thread::wait(500); } } void keys_mouse_output_thread() { USBMouseKeyboard keys_mouse; BusIn buttons_raw(p21, p22, p23, p24); buttons_raw.mode(PullUp); int mouse[4]; int value, trigval; while(true) { memset(mouse, 0, sizeof(mouse)); buttons = ~buttons_raw&0xF; for (int i=3; i<bindings[0][1]; i++) { //pc.printf("Checking %d: ", i); switch (bindings[i][0]) { case 0: trigval = x1.read(); break; case 1: trigval = y1.read(); break; case 2: trigval = x2.read(); break; case 3: trigval = y2.read(); break; case 4: trigval = (buttons & 0x1)*127; break; case 5: trigval = ((buttons>>1) & 0x1)*127; break; case 6: trigval = ((buttons>>2) & 0x1)*127; break; case 7: trigval = ((buttons>>3) & 0x1)*127; break; } value = bindings[i][4]; if (trigval >= bindings[i][1] && trigval <= bindings[i][2]) { //pc.printf("Triggered : %d, %d, %d\r\n", i, trigval, value); switch (bindings[i][3]) { case 0: mouse[0] = trigval/value; break; //Mouse X case 1: mouse[1] = trigval/value; break; //Mouse Y case 2: mouse[2] |= value; break; //Mouse buttons case 3: mouse[3] = trigval/value; break; //Mouse scroll case 4: keys_mouse.keyCode(value); break; //Keypress } } } keys_mouse.update(mouse[0], mouse[1], mouse[2], mouse[3]); Thread::wait(15); } } void joystick_output_thread() { USBJoystick joystick; BusIn buttons_raw(p21, p22, p23, p24); buttons_raw.mode(PullUp); int joy[6]; int value, trigval; while(true) { memset(joy, 0, sizeof(joy)); buttons = ~buttons_raw&0xF; for (int i=3; i<bindings[0][1]; i++) { //pc.printf("Checking %d: ", i); switch (bindings[i][0]) { case 0: trigval = x1.read(); break; case 1: trigval = y1.read(); break; case 2: trigval = x2.read(); break; case 3: trigval = y2.read(); break; case 4: trigval = (buttons & 0x1)*127; break; case 5: trigval = ((buttons>>1) & 0x1)*127; break; case 6: trigval = ((buttons>>2) & 0x1)*127; break; case 7: trigval = ((buttons>>3) & 0x1)*127; break; } value = bindings[i][4]; if (trigval >= bindings[i][1] && trigval <= bindings[i][2]) { //pc.printf("Triggered : %d, %d, %d\r\n", i, trigval, value); switch (bindings[i][3]) { case 0: joy[2] = trigval/value; break;//Joy X case 1: joy[3] = trigval/value; break; //Joy Y case 2: joy[0] = trigval/value; break; //Joy throttle case 3: joy[1] = trigval/value; break; //Joy rudder case 4: joy[4] |= value; break; //Joy buttons case 5: joy[5] |= value; break; //Joy hat } } } joystick.update(joy[0], joy[1], joy[2], joy[3], joy[4], joy[5]); Thread::wait(15); } } int main() { //Load bindings from file FILE *bf = fopen("/local/bindings", "rb"); fread(bindings, 5*sizeof(int), 1, bf); fread(bindings[1], 5*sizeof(int), bindings[0][1]-1, bf); fclose(bf); x1.setup(bindings[1][0], bindings[1][1]); y1.setup(bindings[1][2], bindings[1][3]); x2.setup(bindings[2][0], bindings[2][1]); y2.setup(bindings[2][2], bindings[2][3]); //Thread analogThread(analog_thread); Ticker analog_ticker; analog_ticker.attach(&analog_trig, 0.05); Thread outputThread; //Thread::wait(100); switch(bindings[0][2]) { case 0: outputThread.start(keys_mouse_output_thread); break; case 1: outputThread.start(joystick_output_thread); break; } Thread debugThread(debug_thread); while(1) Thread::yield(); }