diff options
-rw-r--r-- | mariokart01.cpp | 199 | ||||
-rw-r--r-- | mupen64plus-input-sdl.patch | 204 |
2 files changed, 374 insertions, 29 deletions
diff --git a/mariokart01.cpp b/mariokart01.cpp index bc0be6f..f3e0039 100644 --- a/mariokart01.cpp +++ b/mariokart01.cpp @@ -20,6 +20,8 @@ */ +#define FREEBSD + #include <vector> #include <unistd.h> #include <stdio.h> @@ -28,8 +30,17 @@ #include <pthread.h> #include <semaphore.h> #include <fcntl.h> + +#ifdef LINUX #include <linux/input.h> #include <linux/uinput.h> +#endif + +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/uio.h> + #include <iostream> #include <xcb/xcb.h> @@ -217,14 +228,71 @@ void XorgGrabber::read(Mat& mat) -#define THROTTLE_CNT_MAX 20 +#define THROTTLE_CNT_MAX 10 + + +#ifdef FREEBSD +typedef union { + unsigned int Value; + struct { + unsigned R_DPAD : 1; + unsigned L_DPAD : 1; + unsigned D_DPAD : 1; + unsigned U_DPAD : 1; + unsigned START_BUTTON : 1; + unsigned Z_TRIG : 1; + unsigned B_BUTTON : 1; + unsigned A_BUTTON : 1; + + unsigned R_CBUTTON : 1; + unsigned L_CBUTTON : 1; + unsigned D_CBUTTON : 1; + unsigned U_CBUTTON : 1; + unsigned R_TRIG : 1; + unsigned L_TRIG : 1; + unsigned Reserved1 : 1; + unsigned Reserved2 : 1; + + signed X_AXIS : 8; + signed Y_AXIS : 8; + }; +} BUTTONS; + + +char* pack(const BUTTONS* buttons, char* buf) +{ + buf[0]= (buttons->A_BUTTON ? 1 : 0) + + (buttons->B_BUTTON ? 2 : 0) + + (buttons->L_TRIG ? 4 : 0) + + (buttons->R_TRIG ? 8 : 0) + + (buttons->Z_TRIG ? 16 : 0) + + (buttons->START_BUTTON ? 32 : 0) + + 128; + + buf[1]= (buttons->R_DPAD ? 1 : 0) + + (buttons->L_DPAD ? 2 : 0) + + (buttons->U_DPAD ? 4 : 0) + + (buttons->D_DPAD ? 8 : 0) + + ((buttons->X_AXIS & 128) ? 16 : 0) + + ((buttons->Y_AXIS & 128) ? 32 : 0); + + buf[2]= (buttons->R_CBUTTON ? 1 : 0) + + (buttons->L_CBUTTON ? 2 : 0) + + (buttons->U_CBUTTON ? 4 : 0) + + (buttons->D_CBUTTON ? 8 : 0); + + buf[3]= (buttons->X_AXIS & 127); + + buf[4]= (buttons->Y_AXIS & 127); + + return buf; +} +#endif class Joystick { public: Joystick(); - ~Joystick(); - void steer(float dir, float dead_zone=0.0); void throttle(float t); void press_a(bool); @@ -232,14 +300,68 @@ class Joystick void process(); void reset(); - + private: +#ifdef FREEBSD + BUTTONS buttons; + void send_data(); + int fifo_fd; +#endif + float throt; int throttle_cnt; - int fd; }; +#ifdef FREEBSD +Joystick::Joystick() +{ + if ((fifo_fd=open("/var/tmp/mupen64plus_ctl", O_WRONLY )) == -1) {throw string(strerror(errno));} + cout << "opened" << endl; + if (fcntl(fifo_fd, F_SETFL, O_NONBLOCK) == -1) throw string("failed to set nonblocking io"); + + reset(); +} + +void Joystick::press_a(bool state) +{ + buttons.A_BUTTON=state; + send_data(); +} + +void Joystick::send_data() +{ + char buf[5]; + pack(&buttons, buf); + write(fifo_fd, buf, 5); +} + + + +void Joystick::steer(float dir, float dead_zone) +{ + if (dir<-1.0) dir=-1.0; + if (dir>1.0) dir=1.0; + + if (fabs(dir)<dead_zone) dir=0.0; + + buttons.X_AXIS = (signed) (127.0*dir); + send_data(); +} + +void Joystick::reset() +{ + memset(&buttons, sizeof(buttons), 0); + buttons.Z_TRIG=0; + buttons.R_TRIG=0; + buttons.L_TRIG=0; + buttons.A_BUTTON=0; + buttons.B_BUTTON=0; + send_data(); +} + +#endif +#ifdef LINUX Joystick::Joystick() { fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); @@ -298,21 +420,6 @@ void Joystick::steer(float dir, float dead_zone) write(fd, &ev, sizeof(ev)); } -void Joystick::throttle(float t) -{ - if (t<0.0) t=0.0; - if (t>1.0) t=1.0; - - throt=t; -} - -void Joystick::process() -{ - throttle_cnt++; - if (throttle_cnt>=THROTTLE_CNT_MAX) throttle_cnt=0; - - press_a((throttle_cnt < throt*THROTTLE_CNT_MAX)); -} void Joystick::press_a(bool a) { @@ -344,6 +451,25 @@ void Joystick::reset() cout << "A zeroed" << endl; } +#endif + + +void Joystick::throttle(float t) +{ + if (t<0.0) t=0.0; + if (t>1.0) t=1.0; + + throt=t; +} + +void Joystick::process() +{ + throttle_cnt++; + if (throttle_cnt>=THROTTLE_CNT_MAX) throttle_cnt=0; + + press_a((throttle_cnt < throt*THROTTLE_CNT_MAX)); +} + #define HIST_SMOOTH 7 @@ -420,7 +546,7 @@ void* thread1_func(void*) sem_wait(&thread1_go); // now we have our private image at thread1_img. - +/* cvtColor(thread1_img, gray, CV_BGR2GRAY); @@ -491,7 +617,7 @@ void* thread1_func(void*) cv::swap(gray_prev, gray); - + */ // now we must stop accessing thread1_img, main() may access it sem_post(&thread1_done); } @@ -511,13 +637,19 @@ try { string tmp; - Joystick joystick; - cout << "joystick initalized, now starting mupen." << endl; - +#ifdef LINUX + Joystick joystick; + cout << "joystick initalized, now starting mupen." << endl; +#endif if (fork()==0) { system("mupen64plus --nogui --noask ~/MarioKart64.rom"); exit(0); } - + +#ifdef FREEBSD + sleep(2); + Joystick joystick; +#endif + sleep(1); joystick.reset(); @@ -552,9 +684,18 @@ try { getchar();*/ cout << "waiting for game to start, press enter when started." << endl; + joystick.press_a(false); + joystick.reset(); getchar(); - - XorgGrabber capture("glN64");//("Mupen64Plus OpenGL Video"); +joystick.reset(); +joystick.press_a(true); +getchar(); +#ifdef LINUX + XorgGrabber capture("glN64"); +#endif +#ifdef FREEBSD + XorgGrabber capture("Mupen64Plus OpenGL Video"); +#endif int road_0=77, road_1=77, road_2=77; @@ -873,7 +1014,7 @@ try { joystick.steer(- 4* flopow( (((float)left_sum / (left_sum+right_sum))-0.5 )*2.0 , 1.6) ,0.05); } else - joystick.steer(0.0); + joystick.steer(0.0); diff --git a/mupen64plus-input-sdl.patch b/mupen64plus-input-sdl.patch new file mode 100644 index 0000000..20e1f91 --- /dev/null +++ b/mupen64plus-input-sdl.patch @@ -0,0 +1,204 @@ +diff -ru mupen64plus-bundle-src-1.99.4-orig/source/mupen64plus-input-sdl/src/plugin.c mupen64plus-bundle-src-1.99.4/source/mupen64plus-input-sdl/src/plugin.c +--- mupen64plus-bundle-src-1.99.4-orig/source/mupen64plus-input-sdl/src/plugin.c 2012-11-20 20:38:20.000000000 +0100 ++++ mupen64plus-bundle-src-1.99.4/source/mupen64plus-input-sdl/src/plugin.c 2012-11-26 18:17:51.000000000 +0100 +@@ -24,6 +24,12 @@ + #include <stdio.h> + #include <stdlib.h> + #include <string.h> ++#include <errno.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/uio.h> + + #include <SDL.h> + +@@ -133,6 +139,151 @@ + + static CONTROL temp_core_controlinfo[4]; + ++/* FIFO-Control functions by flo */ ++static BUTTONS unpack_fifo_data(const char* buf) ++{ ++ BUTTONS buttons; ++ ++ buttons.A_BUTTON = (buf[0] & 1) ? 1 : 0; ++ buttons.B_BUTTON = (buf[0] & 2) ? 1 : 0; ++ buttons.L_TRIG = (buf[0] & 4) ? 1 : 0; ++ buttons.R_TRIG = (buf[0] & 8) ? 1 : 0; ++ buttons.Z_TRIG = (buf[0] & 16) ? 1 : 0; ++ buttons.START_BUTTON = (buf[0] & 32) ? 1 : 0; ++ buttons.R_DPAD = (buf[1] & 1) ? 1 : 0; ++ buttons.L_DPAD = (buf[1] & 2) ? 1 : 0; ++ buttons.U_DPAD = (buf[1] & 4) ? 1 : 0; ++ buttons.D_DPAD = (buf[1] & 8) ? 1 : 0; ++ buttons.R_CBUTTON = (buf[2] & 2) ? 1 : 0; ++ buttons.L_CBUTTON = (buf[2] & 4) ? 1 : 0; ++ buttons.U_CBUTTON = (buf[2] & 8) ? 1 : 0; ++ buttons.D_CBUTTON = (buf[2] & 16) ? 1 : 0; ++ ++ buttons.X_AXIS = buf[3] | ((buf[1] & 16) ? 128 : 0); ++ buttons.Y_AXIS = buf[4] | ((buf[1] & 32) ? 128 : 0); ++ ++ return buttons; ++} ++ ++typedef struct ++{ ++ int fd; ++ int good; ++ char buf[5]; ++ int bufptr; ++ int recovering; ++ BUTTONS buttons; ++ ++} ctl_fifo_t; ++ ++static ctl_fifo_t init_ctl_fifo(const char* path) ++{ ++ ctl_fifo_t ctl_fifo; ++ ctl_fifo.fd=-1; ++ ctl_fifo.good=0; ++ ctl_fifo.bufptr=0; ++ ctl_fifo.recovering=0; ++ ++ if (unlink(path) < 0) ++ if (errno!=ENOENT) ++ { ++ fprintf(stderr, "The control fifo (%s) could not be unlinked, continuing without remote control support: %s", path, strerror(errno)); ++ ctl_fifo.good=0; ++ return ctl_fifo; ++ } ++ ++ ++ if (mkfifo(path, S_IRWXU)!=0) ++ { ++ fprintf(stderr, "The control fifo (%s) could not be created, continuing without remote control support: %s", path, strerror(errno)); ++ ctl_fifo.good=0; ++ return ctl_fifo; ++ } ++ ++ if ((ctl_fifo.fd=open(path, O_RDONLY | O_NONBLOCK))<0) ++ { ++ fprintf(stderr, "The control fifo (%s) could not be opened, continuing without remote control support: %s", path, strerror(errno)); ++ ctl_fifo.good=0; ++ return ctl_fifo; ++ } ++ ++ if (fcntl(ctl_fifo.fd, F_SETFL, O_NONBLOCK)==-1) ++ { ++ fprintf(stderr, "Could not set nonblocking io mode on control fifo, continuing without remote control support: %s", strerror(errno)); ++ close(ctl_fifo.fd); ++ ctl_fifo.fd=-1; ++ ctl_fifo.good=0; ++ return ctl_fifo; ++ } ++ ++ ctl_fifo.good=1; ++ ++ return ctl_fifo; ++} ++ ++static BUTTONS read_buttons_from_fifo(ctl_fifo_t* ctl_fifo) ++{ ++ ssize_t bytes; ++ ++ if (ctl_fifo->recovering) ++ { ++ do ++ { ++ ctl_fifo->bufptr=0; ++ if ((bytes = read(ctl_fifo->fd, ctl_fifo->buf, 1)) == -1 && errno!=EAGAIN) ++ { ++ printf("read error!\n"); ++ } ++ ++ //if (bytes==1) printf("\tread %c\n", ctl_fifo->buf[0]); ++ } while ((ctl_fifo->buf[0] & 128)==0 && bytes>0); ++ ++ if (ctl_fifo->buf[0] & 128) ++ { ++ printf("successfully recovered :)\n"); ++ ctl_fifo->recovering=0; ++ ctl_fifo->bufptr=1; ++ } ++ } ++ ++ ++ if (!ctl_fifo->recovering) ++ do ++ { ++ if ((bytes = read(ctl_fifo->fd, ctl_fifo->buf+ctl_fifo->bufptr, sizeof(ctl_fifo->buf)-ctl_fifo->bufptr)) == -1 ++ && (errno!=EAGAIN)) ++ { ++ printf("read error!\n"); ++ } ++ else if (bytes>0) ++ { ++ ctl_fifo->bufptr+=bytes; ++ if (ctl_fifo->bufptr==sizeof(ctl_fifo->buf)) ++ { ++ ctl_fifo->bufptr=0; ++ ++ if (ctl_fifo->buf[0] & 128) ++ { ++ ctl_fifo->buttons = unpack_fifo_data(ctl_fifo->buf); ++ } ++ else ++ { ++ printf("fifo data corrupt, entering recovery mode\n"); ++ ctl_fifo->recovering=1; ++ break; ++ } ++ } ++ } ++ } while (bytes>0); ++ ++ return ctl_fifo->buttons; ++} ++ ++static ctl_fifo_t ctl_fifo; ++static int ctl_fifo_inited=0; ++static int ctl_fifo_takeover=0; ++ ++ + /* Mupen64Plus plugin functions */ + EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, + void (*DebugCallback)(void *, int, const char *)) +@@ -454,6 +605,12 @@ + SDL_Event event; + unsigned char mstate; + ++ if (ctl_fifo_inited==0) ++ { ++ ctl_fifo=init_ctl_fifo("/var/tmp/mupen64plus_ctl"); ++ ctl_fifo_inited=1; ++ } ++ + // Handle keyboard input first + doSdlKeys(SDL_GetKeyState(NULL)); + doSdlKeys(myKeyState); +@@ -596,7 +753,21 @@ + #ifdef _DEBUG + DebugMessage(M64MSG_VERBOSE, "Controller #%d value: 0x%8.8X\n", Control, *(int *)&controller[Control].buttons ); + #endif +- *Keys = controller[Control].buttons; ++ ++ if (Control==0) ++ { ++ BUTTONS fromfifo = read_buttons_from_fifo(&ctl_fifo); ++ if (fromfifo.A_BUTTON) ++ ctl_fifo_takeover=1; ++ ++ if (ctl_fifo_takeover) ++ *Keys = fromfifo; ++ else ++ *Keys = controller[Control].buttons; ++ ++ } ++ else ++ *Keys = controller[Control].buttons; + + /* handle mempack / rumblepak switching (only if rumble is active on joystick) */ + #ifdef __linux__ |