summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <florian.a.jung@web.de>2012-11-26 18:21:55 +0100
committerFlorian Jung <florian.a.jung@web.de>2012-11-26 18:21:55 +0100
commit45b9374c21022b3b905e11ede35a7cca4428c5ac (patch)
tree804ac5deb997870b81f3a96c56ca2c6224e7e434
parent234b363f11201ebe37519d1cd525634f4da9c0fd (diff)
parent2d4464532a8f796df23d6da0c27c6e6b64909fd7 (diff)
Merge branch 'master' of archie:programme/mariokart
-rw-r--r--mariokart01.cpp199
-rw-r--r--mupen64plus-input-sdl.patch204
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__