GamePortAdapter

Dependencies:   mbed-rtos mbed USBDevice USBJoystick

main.cpp

Committer:
obsoleet37
Date:
2017-12-14
Revision:
5:c2e3d6e70d85
Parent:
4:17b8ede8063a
Child:
6:43b59cb5dcd9

File content as of revision 5:c2e3d6e70d85:

#include "mbed.h"
#include "USBMouseKeyboard.h"
#include "USBJoystick.h"
#include "rtos.h"
#include "string.h"

extern "C" void mbed_reset();

Serial pc(USBTX, USBRX);
//macOS: screen /dev/tty.usbmodem{num} {baud rate}
//Windows: Realterm lol

Timer y1_t;
Timer x1_t;
Timer y2_t;
Timer x2_t;

InterruptIn y1(p16);
InterruptIn x1(p15);
InterruptIn y2(p18);
InterruptIn x2(p17);

volatile int y1_pulse;
volatile int x1_pulse;
volatile int y2_pulse;
volatile int x2_pulse;
volatile int buttons;

DigitalOut trig(p19);

BusIn buttons_raw(p21, p22, p23, p24);

//first row: necessary garbage, size, mode, reserved x2
//following rows: input, min, max, output, value
int bindings[128][5];
/*int bindings[128][5] = {{0xFFFFFFFF, 7, 0, 0, 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 start_y1() {
    y1_t.reset();
    y1_t.start();
}

void stop_y1() {
    y1_t.stop();
    y1_pulse = y1_t.read_us();
}

void start_x1() {
    x1_t.reset();
    x1_t.start();
}

void stop_x1() {
    x1_t.stop();
    x1_pulse = x1_t.read_us();
}
void start_y2() {
    y2_t.reset();
    y2_t.start();
}

void stop_y2() {
    y2_t.stop();
    y2_pulse = y2_t.read_us();
}

void start_x2() {
    x2_t.reset();
    x2_t.start();
}

void stop_x2() {
    x2_t.stop();
    x2_pulse = x2_t.read_us();
}


void analog_thread() {
    
    buttons_raw.mode(PullUp);
    
    trig = 1;
    y1_pulse = 0;
    x1_pulse = 0;
    y2_pulse = 0;
    x2_pulse = 0;
    
    y1.rise(&start_y1);
    y1.fall(&stop_y1);
    
    x1.rise(&start_x1);
    x1.fall(&stop_x1);
    
    y2.rise(&start_y2);
    y2.fall(&stop_y2);
    
    x2.rise(&start_x2);
    x2.fall(&stop_x2);

    while(1) {
        trig = 0;
        trig = 1;
        buttons = ~buttons_raw&0xF;
        Thread::wait(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_pulse, y1_pulse, buttons&0x3);
        pc.printf("Joystick 2 - %d, %d, %X \r\n", x2_pulse, y2_pulse, (buttons>>2)&0x3);
        pc.printf("\r\n");
        Thread::wait(500);
    }
}


void keys_mouse_output_thread() {
    USBMouseKeyboard keys_mouse;
    int mouse[4];
    int value, trigval;
    
    while(true) {
        memset(mouse, 0, sizeof(mouse));
        
        for (int i=1; i<bindings[0][1]; i++) {
            //pc.printf("Checking %d: ", i);
            switch (bindings[i][0]) {
                case 0: value = x1_pulse; trigval = x1_pulse; break;
                case 1: value = y1_pulse; trigval = y1_pulse; break;
                case 2: value = x2_pulse; trigval = x2_pulse; break;
                case 3: value = y2_pulse; trigval = y2_pulse; break;
                case 4: trigval = (buttons & 0x1)*255; value = bindings[i][4]; break;
                case 5: trigval = ((buttons>>1) & 0x1)*255; value = bindings[i][4]; break;
                case 6: trigval = ((buttons>>2) & 0x1)*255; value = bindings[i][4]; break;
                case 7: trigval = ((buttons>>3) & 0x1)*255; value = bindings[i][4]; break;
            }
            
            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] = value/10; break; //Mouse X
                    case 1: mouse[1] = value/10; break; //Mouse Y
                    case 2: mouse[2] |= bindings[i][4]; break; //Mouse buttons
                    case 3: mouse[3] = value/10; break; //Mouse scroll
                    case 4: keys_mouse.keyCode(bindings[i][4]); break; //Keypress
                }  
            }
        }
        keys_mouse.update(mouse[0], mouse[1], mouse[2], mouse[3]);
        Thread::wait(20);
    }
}


void joystick_output_thread() {
    USBJoystick joystick;
    int joy[6];
    int value, trigval;
    
    while(true) {
        memset(joy, 0, sizeof(joy));
        
        for (int i=1; i<bindings[0][1]; i++) {
            //pc.printf("Checking %d: ", i);
            switch (bindings[i][0]) {
                case 0: value = x1_pulse; trigval = x1_pulse; break;
                case 1: value = y1_pulse; trigval = y1_pulse; break;
                case 2: value = x2_pulse; trigval = x2_pulse; break;
                case 3: value = y2_pulse; trigval = y2_pulse; break;
                case 4: trigval = (buttons & 0x1)*255; value = bindings[i][4]; break;
                case 5: trigval = ((buttons>>1) & 0x1)*255; value = bindings[i][4]; break;
                case 6: trigval = ((buttons>>2) & 0x1)*255; value = bindings[i][4]; break;
                case 7: trigval = ((buttons>>3) & 0x1)*255; value = bindings[i][4]; break;
            }
            
            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] = value; break;//Joy X
                    case 1: joy[3] = value; break; //Joy Y
                    case 2: joy[0] = value; break; //Joy throttle
                    case 3: joy[1] = value; break; //Joy rudder
                    case 4: joy[4] |= bindings[i][4]; break; //Joy buttons
                    case 5: joy[5] |= bindings[i][4]; break; //Joy hat
                }  
            }
        }
        joystick.update(joy[0], joy[1], joy[2], joy[3], joy[4], joy[5]);
        Thread::wait(20);
    }
}


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);
    
    Thread analogThread;
    Thread outputThread;
    
    analogThread.start(analog_thread);
    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;
    //debugThread.start(debug_thread);
    
    while(1) Thread::yield();
}