summaryrefslogtreecommitdiff
path: root/mariokart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mariokart.cpp')
-rw-r--r--mariokart.cpp438
1 files changed, 5 insertions, 433 deletions
diff --git a/mariokart.cpp b/mariokart.cpp
index dc6eaa9..ff5fbaa 100644
--- a/mariokart.cpp
+++ b/mariokart.cpp
@@ -20,8 +20,8 @@
*/
-#define FREEBSD
-//#define LINUX
+#include "os.h"
+
#include <vector>
#include <unistd.h>
@@ -32,15 +32,6 @@
#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 "util.h"
#include "steer_interface.h"
@@ -48,9 +39,11 @@
#include "road_thresholder_iface.h"
#include "road_thresholder.h"
+#include "xorg_grabber.h"
+#include "joystick.h"
+
#include <iostream>
#include <list>
-#include <xcb/xcb.h>
#include <assert.h>
#include <opencv2/opencv.hpp>
@@ -58,433 +51,12 @@
using namespace std;
using namespace cv;
-class XorgGrabber
-{
- public:
- XorgGrabber(const char* win_title);
- ~XorgGrabber();
- void read(Mat& mat);
-
- private:
- xcb_connection_t* conn;
- xcb_window_t grabbed_win;
- int grab_width, grab_height;
- xcb_screen_t* grab_screen;
- xcb_get_image_reply_t* img;
-
-};
-
-XorgGrabber::XorgGrabber(const char* win_title)
-{
- conn=xcb_connect(NULL,NULL);
-
- bool found_win=false;
- grab_screen=NULL;
- img=NULL;
-
- /* Find configured screen */
- const xcb_setup_t* setup = xcb_get_setup(conn);
- for (xcb_screen_iterator_t i = xcb_setup_roots_iterator(setup);
- i.rem > 0; xcb_screen_next (&i))
- {
- xcb_screen_t* scr = i.data;
- xcb_query_tree_reply_t* reply = xcb_query_tree_reply( conn, xcb_query_tree(conn, scr->root), NULL);
- if (reply)
- {
- int len = xcb_query_tree_children_length(reply);
- xcb_window_t* children = xcb_query_tree_children(reply);
- xcb_get_window_attributes_cookie_t* cookies = new xcb_get_window_attributes_cookie_t[len];
- for (int i=0; i<len; ++i)
- cookies[i]=xcb_get_window_attributes(conn, children[i]);
-
- for (int i=0; i<len; ++i)
- {
- xcb_get_window_attributes_reply_t* attr =
- xcb_get_window_attributes_reply (conn, cookies[i], NULL);
-
-
- xcb_get_property_reply_t* title_reply = xcb_get_property_reply(conn,
- xcb_get_property(conn, false, children[i], XCB_ATOM_WM_NAME, XCB_GET_PROPERTY_TYPE_ANY, 0, 128),
- NULL );
-
- if (!attr->override_redirect && attr->map_state == XCB_MAP_STATE_VIEWABLE)
- {
- char* title=(char*)(title_reply+1);
- cout << title << endl;
- if (strstr(title, win_title))
- {
- xcb_get_geometry_reply_t* geo;
- geo = xcb_get_geometry_reply (conn, xcb_get_geometry (conn, children[i]), NULL);
- if (geo)
- {
- grab_width=geo->width;
- grab_height=geo->height;
-
- free(geo);
-
- grabbed_win=children[i];
- found_win=true;
-
- grab_screen=scr;
- }
- else
- {
- cerr << "geo==NULL!" << endl;
- }
- }
- }
-
- free(title_reply);
- free(attr);
- }
-
- free(reply);
- delete[] cookies;
- }
- else
- {
- cout << "xcb_get_setup failed" << endl;
- }
- }
-
- if (found_win)
- {
- xcb_get_image_reply_t* img = xcb_get_image_reply (conn,
- xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, grabbed_win,
- 0, 0, grab_width, grab_height, ~0), NULL);
-
-
-
- xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(grab_screen);
-
- int ndepths=xcb_screen_allowed_depths_length(grab_screen);
-
- for (int i=0; i<ndepths; ++i)
- {
- if (depth_iterator.data->depth == img->depth)
- {
- xcb_visualtype_t* visuals = xcb_depth_visuals(depth_iterator.data);
- int nvisuals = xcb_depth_visuals_length(depth_iterator.data);
-
- for (int j=0;j<nvisuals;j++)
- {
- if (visuals[j].visual_id==img->visual)
- {
- assert(visuals[j]._class==XCB_VISUAL_CLASS_TRUE_COLOR || visuals[j]._class==XCB_VISUAL_CLASS_DIRECT_COLOR);
- cout << (int)visuals[j]._class << "," << XCB_VISUAL_CLASS_TRUE_COLOR << endl;
- cout << visuals[j].red_mask << endl;
- cout << visuals[j].green_mask << endl;
- cout << visuals[j].blue_mask << endl;
- break;
- }
- }
-
- break;
- }
-
- xcb_depth_next(&depth_iterator);
- }
-
-
-
- int nformats = xcb_setup_pixmap_formats_length(setup);
- xcb_format_t* formats = xcb_setup_pixmap_formats(setup);
- for (int i=0;i<nformats;i++)
- {
- if (formats[i].depth==img->depth)
- {
- cout << (int)formats[i].bits_per_pixel << endl;
- cout << (int)formats[i].scanline_pad << endl;
- break;
- }
- }
-
- cout << grab_width << "x" << grab_height << endl;
-
- free(img);
-
- }
- else
- {
- throw string("FATAL: did not find window, exiting.");
- }
-
-
-}
-
-XorgGrabber::~XorgGrabber()
-{
- if (img) free(img);
- xcb_disconnect(conn);
-}
-
-void XorgGrabber::read(Mat& mat)
-{
- if (img) free(img);
-
-
- // mat gets invalid when the next read() is called!
- img = xcb_get_image_reply (conn,
- xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, grabbed_win,
- 0, 0, grab_width, grab_height, ~0), NULL);
-
- mat = Mat(grab_height, grab_width, CV_8UC4, xcb_get_image_data(img));
- mat.addref();
-}
-
-
-
-
-#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);
-
-
- void process();
- void reset();
-
- private:
-#ifdef FREEBSD
- BUTTONS buttons;
- void send_data();
- int fifo_fd;
-#endif
-#ifdef LINUX
- int fd;
-#endif
-
- float throt;
- int throttle_cnt;
-
-};
-
-#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();
-}
-
-Joystick::~Joystick()
-{
- close(fifo_fd);
-}
-#endif
-#ifdef LINUX
-Joystick::Joystick()
-{
- fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
- if(fd < 0) {
- cerr << "open uinput failed. do you have privilegies to access it? (try chown flo:root /dev/uinput)" << endl;
- exit(EXIT_FAILURE);
- }
-
- int ret;
-
- ret=ioctl(fd, UI_SET_EVBIT, EV_KEY);
- ret=ioctl(fd, UI_SET_EVBIT, EV_SYN);
- ret=ioctl(fd, UI_SET_KEYBIT , BTN_A);
- ioctl(fd, UI_SET_EVBIT, EV_ABS);
- ioctl(fd, UI_SET_ABSBIT, ABS_X);
- ioctl(fd, UI_SET_ABSBIT, ABS_Y);
-
- struct uinput_user_dev meh;
- memset(&meh,0,sizeof(meh));
-
- strcpy(meh.name, "flotest");
- meh.id.bustype=BUS_USB;
- meh.id.vendor=0xdead;
- meh.id.product=0xbeef;
- meh.id.version=1;
- meh.absmin[ABS_X]=0;
- meh.absmax[ABS_X]=10000;
- meh.absmin[ABS_Y]=0;
- meh.absmax[ABS_Y]=10000;
-
-
- ret=write(fd, &meh, sizeof(meh));
-
- ioctl(fd,UI_DEV_CREATE);
-
- reset();
-}
-
-Joystick::~Joystick()
-{
- ioctl(fd, UI_DEV_DESTROY);
- close(fd);
-}
-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;
-
- struct input_event ev;
- ev.type=EV_ABS;
- ev.code=ABS_X;
- ev.value=5000+dir*5000;
- write(fd, &ev, sizeof(ev));
-}
-void Joystick::press_a(bool a)
-{
- struct input_event ev;
- ev.type=EV_KEY;
- ev.code=BTN_A;
- ev.value = a ? 1 : 0;
- write(fd, &ev, sizeof(ev));
-}
-void Joystick::reset()
-{
- struct input_event ev;
- ev.type=EV_ABS;
- ev.code=ABS_Y;
- ev.value=5001;
- write(fd, &ev, sizeof(ev));
- ev.value=5000;
- write(fd, &ev, sizeof(ev));
-
- cout << "Y zeroed" << endl;
-
- steer(0.1);
- steer(0);
- cout << "X zeroed" << endl;
-
- press_a(true);
- press_a(false);
- 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