Skip to content

Instantly share code, notes, and snippets.

@Ryochan7
Last active March 23, 2016 08:08
Show Gist options
  • Save Ryochan7/8cb6264f3b3d27b8daa3 to your computer and use it in GitHub Desktop.
Save Ryochan7/8cb6264f3b3d27b8daa3 to your computer and use it in GitHub Desktop.
WiimoteGlue Experiments
diff --git a/Makefile b/Makefile
index 0350d14..c937f90 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
LINK_LIBS += -ludev
LINK_LIBS += -lxwiimote
+LINK_LIBS += -lm
EXTRA_CFLAGS += $(CONFIG_FLAGS)
wiimoteglue: src/*.c
diff --git a/src/device_management.c b/src/device_management.c
index a5442a3..46827dd 100644
--- a/src/device_management.c
+++ b/src/device_management.c
@@ -142,6 +142,8 @@ int open_wii_device(struct wiimoteglue_state *state, struct wii_device* dev) {
} else {
xwii_iface_close(wiidev,XWII_IFACE_IR);
}
+
+ xwii_iface_open(wiidev, XWII_IFACE_MOTION_PLUS);
/*LEDs only checked after opening,
*and we want to store the state
@@ -311,4 +313,4 @@ int set_led_state(struct wiimoteglue_state* state, struct wii_device *dev, bool
}
}
return okay;
-}
\ No newline at end of file
+}
diff --git a/src/epoll.c b/src/epoll.c
index 07a5411..35cef21 100644
--- a/src/epoll.c
+++ b/src/epoll.c
@@ -1,6 +1,8 @@
#include <sys/epoll.h>
#include <string.h>
#include <stdio.h>
+#include <sys/timeb.h>
+#include <unistd.h>
#include "wiimoteglue.h"
@@ -8,9 +10,10 @@
* This should prevent using unecessary CPU time.
*/
-#define EPOLL_MAX_EVENTS 10
+#define EPOLL_MAX_EVENTS 100
struct epoll_event event;
struct epoll_event events[EPOLL_MAX_EVENTS];
+struct timeb the_time;
int wiimoteglue_epoll_init(int *epfd) {
*epfd = epoll_create(EPOLL_MAX_EVENTS);
@@ -53,8 +56,14 @@ void wiimoteglue_epoll_loop(int epfd, struct wiimoteglue_state *state) {
int n;
int i;
+ ftime(&the_time);
+
while (state->keep_looping > 0) {
- n = epoll_wait(epfd, events, EPOLL_MAX_EVENTS, -1);
+
+ struct timeb current_time;
+ ftime(&current_time);
+ n = epoll_wait(epfd, events, EPOLL_MAX_EVENTS, 0);
+
for (i = 0; i < n; i++) {
if (events[i].data.ptr == state->monitor) {
//HANDLE UDEV STUFF
@@ -74,6 +83,19 @@ void wiimoteglue_epoll_loop(int epfd, struct wiimoteglue_state *state) {
wiimoteglue_handle_wii_event(state,events[i].data.ptr);
}
}
+
+ if (n == 0)
+ {
+ wiimoteglue_handle_ir_event(state);
+ //wiimoteglue_handle_mp_event(state);
+ ftime(&the_time);
+
+ struct timespec temptime;
+ temptime.tv_sec = 0;
+ //temptime.tv_nsec = 16000000;
+ temptime.tv_nsec = 10000000;
+ nanosleep(&temptime, 0);
+ }
}
}
diff --git a/src/main.c b/src/main.c
index 6fe4a7b..0ab1cbd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -121,6 +121,7 @@ int main(int argc, char *argv[]) {
init_keyboardmouse_mappings(&keymouse->maps);
set_slot_specific_mappings(&state.slots[0],&keymouse->maps);
+ initIRTesting();
/*The device list is cyclic*/
state.dev_list.next = &state.dev_list;
diff --git a/src/process_xwiimote_events.c b/src/process_xwiimote_events.c
index 26e1270..b7f8ea6 100644
--- a/src/process_xwiimote_events.c
+++ b/src/process_xwiimote_events.c
@@ -3,6 +3,8 @@
#include <linux/input.h>
#include <string.h>
#include <unistd.h>
+#include <math.h>
+#include <sys/timeb.h>
#include "wiimoteglue.h"
@@ -13,6 +15,80 @@
*
*/
+static struct timeHelper
+{
+ bool running;
+ struct timeb startTime;
+};
+
+extern struct irpos lastPos;
+extern struct testir_info ir_stuff[4];
+
+static bool ratchet = false;
+static bool holdCursor = false;
+static unsigned int holdCursorCount = 0;
+#define HOLDCURSORNUMPOLL 1
+
+static struct xwii_event_abs *currentIREvent = 0;
+
+static struct xwii_event_abs currentIREvent2[XWII_ABS_NUM];
+static struct xwii_event_abs currentAccelEvent2[XWII_ABS_NUM];
+static struct xwii_event_abs currentMpEvent[XWII_ABS_NUM];
+
+static struct event_map* devicemapping = 0;
+static struct event_map* mpmapping = 0;
+static bool hasMpEvent = false;
+
+static double remainderX = 0.0;
+static double remainderY = 0.0;
+
+static double previousPointerRatioX = 0.5;
+static double previousPointerRatioY = 0.5;
+
+#define SMOOTHXBUFFERLEN 2
+#define SMOOTHYBUFFERLEN 2
+
+static int smoothXBuffer[SMOOTHXBUFFERLEN];
+static int smoothYBuffer[SMOOTHYBUFFERLEN];
+static int smoothXBufferLen = SMOOTHXBUFFERLEN;
+static int smoothYBufferLen = SMOOTHYBUFFERLEN;
+
+static int smoothXBufferHead = 0;
+static int smoothYBufferHead = 0;
+static int smoothXBufferTail = 0;
+static int smoothYBufferTail = 0;
+static int smoothXBufferCount = 0;
+static int smoothYBufferCount = 0;
+
+static struct timeHelper deltaEasingTimeX;
+static struct timeHelper deltaEasingTimeY;
+
+static double accelHelperX = 0.0;
+static double accelHelperY = 0.0;
+
+static double accelTravelX = 0.0;
+static double accelTravelY = 0.0;
+
+static struct timeHelper outOfReachElapsed;
+static bool outOfReachStatus = true;
+
+static struct timeHelper initialInReachElapsed;
+static bool initialInReachStatus = false;
+
+static struct timeHelper regionEasingX;
+
+static unsigned int calibratePollCount = 0;
+static bool wmpCalibrated = false;
+static int wmpSumCalibrateX = 0;
+static int wmpSumCalibrateY = 0;
+static int wmpFinalCalibrateX = 0;
+static int wmpFinalCalibrateY = 0;
+static unsigned int ignoreMpEventCount = 0;
+
+// Measured in milliseconds
+static const int OUTOFREACH_ELAPSED_TIME = 1000;
+static const int INITIAL_INREACH_ELAPSED_TIME = 125;
+static const double PI = acos(-1.0);
void handle_key(int uinput_fd, int button_map[], struct xwii_event_key *ev);
@@ -22,6 +98,24 @@ void handle_pro(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]
void handle_accel(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]);
void handle_IR(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]);
void handle_balance(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]);
+void handle_mp(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]);
+
+static void rotateIRPoints(double *x, double *y, double rotation);
+static double findIRRotation(float rawirx1, float rawirx2,
+ float rawiry1, float rawiry2);
+
+static void addSmoothBufferValues(int xval, int yval);
+static void getSmoothBufferValues(int *xval, int *yval);
+
+static void moveVirtualMouseTwo(int uinput_fd, int x, int y, bool outOfRange);
+
+static void calibrateMpPoll(struct xwii_event_abs ev[]);
+
+static unsigned int timeElapsedInMilliseconds(struct timeHelper *time);
+static void timeRestart(struct timeHelper *time);
+static void timeStop(struct timeHelper *time);
+static void timeStart(struct timeHelper *time);
+static void timeInit(struct timeHelper *time);
int wiimoteglue_update_all_wiimote_ifaces(struct wii_device_list *devlist) {
if (devlist == NULL)
@@ -91,6 +185,7 @@ int wiimoteglue_update_extensions(struct wiimoteglue_state *state, struct wii_de
int wiimoteglue_handle_wii_event(struct wiimoteglue_state *state, struct wii_device *dev) {
struct xwii_event ev;
+
if (dev == NULL) {
return -1;
}
@@ -109,8 +204,8 @@ int wiimoteglue_handle_wii_event(struct wiimoteglue_state *state, struct wii_dev
struct event_map* mapping;
-
mapping = dev->map;
+ bool ireventused = false;
switch(ev.type) {
case XWII_EVENT_KEY:
@@ -129,19 +224,44 @@ int wiimoteglue_handle_wii_event(struct wiimoteglue_state *state, struct wii_dev
handle_pro(dev->slot->uinput_fd, mapping, ev.v.abs);
break;
case XWII_EVENT_ACCEL:
+ //handle_accel(dev->slot->uinput_fd, mapping, ev.v.abs);
+ memcpy(currentAccelEvent2, ev.v.abs, sizeof(struct xwii_event_abs[XWII_ABS_NUM]));
+
handle_accel(dev->slot->uinput_fd, mapping, ev.v.abs);
break;
case XWII_EVENT_IR:
+ //handle_IR(dev->slot->uinput_fd, mapping, ev.v.abs);
+ if (currentIREvent)
+ {
+ free(currentIREvent);
+ currentIREvent = 0;
+ }
+
+ currentIREvent = (struct xwii_event_abs*)malloc(sizeof(struct xwii_event_abs[XWII_ABS_NUM]));
+ memcpy(currentIREvent, ev.v.abs, sizeof(struct xwii_event_abs[XWII_ABS_NUM]));
+
+ memcpy(currentIREvent2, ev.v.abs, sizeof(struct xwii_event_abs[XWII_ABS_NUM]));
+
+ //devicemapping = (struct event_map*)malloc(sizeof(struct event_map));
+ //memcpy(devicemapping, mapping, sizeof(struct event_map));
+ devicemapping = mapping;
handle_IR(dev->slot->uinput_fd, mapping, ev.v.abs);
break;
case XWII_EVENT_BALANCE_BOARD:
handle_balance(dev->slot->uinput_fd, mapping, ev.v.abs);
break;
+ case XWII_EVENT_MOTION_PLUS:
+ {
+ //handle_mp(dev->slot->uinput_fd, mapping, ev.v.abs);
+ mpmapping = mapping;
+ memcpy(currentMpEvent, ev.v.abs, sizeof(struct xwii_event_abs[XWII_ABS_NUM]));
+ hasMpEvent = true;
+ break;
+ }
case XWII_EVENT_WATCH:
case XWII_EVENT_GONE:
wiimoteglue_update_extensions(state,dev);
break;
-
}
}
@@ -160,6 +280,30 @@ void handle_key(int uinput_fd, int button_map[], struct xwii_event_key *ev) {
out.code = SYN_REPORT;
out.value = 0;
write(uinput_fd, &out, sizeof(out));
+
+ // Holding Nunchuk Z button locks view.
+ if (ev->code == XWII_KEY_Z && ev->state)
+ {
+ ratchet = true;
+ }
+ else if (ev->code == XWII_KEY_Z && !ev->state)
+ {
+ ratchet = false;
+ }
+
+ if ((ev->code == XWII_KEY_A || ev->code == XWII_KEY_B) && ev->state)
+ {
+ // Pressing A or B button on Wiimote locks view for one poll.
+ // Duration could be longer but even one poll helps a lot.
+ holdCursor = true;
+ holdCursorCount = 0;
+ }
+ else if ((ev->code == XWII_KEY_A || ev->code == XWII_KEY_B) && !ev->state)
+ {
+ // Releasing A or B button on Wiimote locks view for one poll.
+ holdCursor = true;
+ holdCursorCount = 0;
+ }
}
void handle_nunchuk(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]) {
@@ -167,10 +311,10 @@ void handle_nunchuk(int uinput_fd, struct event_map *map, struct xwii_event_abs
memset(&out,0,sizeof(out));
out.type = EV_ABS;
out.code = map->stick_map[WG_N_X][AXIS_CODE];
- out.value = ev[0].x * map->stick_map[WG_N_X][AXIS_SCALE];
+ out.value = (ev[0].x + 10) * map->stick_map[WG_N_X][AXIS_SCALE];
write(uinput_fd, &out, sizeof(out));
out.code = map->stick_map[WG_N_Y][AXIS_CODE];
- out.value = ev[0].y * map->stick_map[WG_N_Y][AXIS_SCALE];
+ out.value = (ev[0].y - 5) * map->stick_map[WG_N_Y][AXIS_SCALE];
write(uinput_fd, &out, sizeof(out));
out.type = EV_SYN;
@@ -182,13 +326,13 @@ void handle_nunchuk(int uinput_fd, struct event_map *map, struct xwii_event_abs
out.type = EV_ABS;
out.code = map->accel_map[WG_N_ACCELX][AXIS_CODE];
- out.value = ev[1].x * map->accel_map[WG_N_ACCELX][AXIS_SCALE];
+ out.value = ev[1].x * (map->accel_map[WG_N_ACCELX][AXIS_SCALE] / 2.0);
write(uinput_fd, &out, sizeof(out));
out.code = map->accel_map[WG_N_ACCELY][AXIS_CODE];
- out.value = ev[1].y * map->accel_map[WG_N_ACCELY][AXIS_SCALE];
+ out.value = ev[1].y * (map->accel_map[WG_N_ACCELY][AXIS_SCALE] / 2.0);
write(uinput_fd, &out, sizeof(out));
out.code = map->accel_map[WG_N_ACCELZ][AXIS_CODE];
- out.value = ev[1].z * map->accel_map[WG_N_ACCELZ][AXIS_SCALE];
+ out.value = ev[1].z * (map->accel_map[WG_N_ACCELZ][AXIS_SCALE] / 2.0);
write(uinput_fd, &out, sizeof(out));
out.type = EV_SYN;
@@ -273,37 +417,401 @@ void handle_accel(int uinput_fd, struct event_map *map, struct xwii_event_abs ev
out.value = 0;
write(uinput_fd, &out, sizeof(out));
}
+
void handle_IR(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]) {
struct input_event out;
- memset(&out,0,sizeof(out));
+ memset(&out, 0, sizeof(out));
out.type = EV_ABS;
+
int num = 0;
- float x = 1023;
- float y = 1023;
- int i;
+ int x = 1023;
+ int y = 1023;
+
+ float ir_x[2];
+ float ir_y[2];
+ memset(&ir_x, 0, sizeof(ir_x));
+ memset(&ir_y, 0, sizeof(ir_y));
+
+ bool outtest = true;
+
+ int irfound = 0;
+ bool irseen[4];
+ memset(&irseen, 0, sizeof(irseen));
+
+ for (int i = 0; i < 4; i++)
+ {
+ ir_stuff[i].x = ev[i].x;
+ ir_stuff[i].y = ev[i].y;
+ if ((ev[i].x != 0 || ev[i].y != 0) &&
+ xwii_event_ir_is_valid(&ev[i]))
+ {
+ irfound++;
+ irseen[i] = true;
+ }
+ }
+
+ if (irfound <= 1)
+ {
+ x = lastPos.x;
+ y = lastPos.y;
+ outtest = lastPos.outOfRange;
+ for (int i = 0; i < 4; i++)
+ {
+ ir_stuff[i].x = 1023;
+ ir_stuff[i].y = 1023;
+ ir_stuff[i].using = false;
+ }
+
+ num = 0;
+ }
+ else if (irfound == 2)
+ {
+ int i = 0;
+ for (int j = 0; j < 4; j++)
+ {
+ ir_stuff[j].using = irseen[j];
+ if (irseen[j])
+ {
+ ir_x[i] = ir_stuff[j].x;
+ ir_y[i] = ir_stuff[j].y;
+ i++;
+ }
+ }
+
+ x = (ir_x[0] + ir_x[1]) / 2.0;
+ y = (ir_y[0] + ir_y[1]) / 2.0;
+ num = 2;
+ }
+ // Perform action if more than 2 IR points are seen at once.
+ else if (irfound > 2)
+ {
+ int numActive = 0;
+ // Check for previously active points.
+ for (int i = 0; i < 4; i++)
+ {
+ if (ir_stuff[i].using && irseen[i])
+ {
+ // Increment known seen IR trackers.
+ numActive++;
+ }
+ }
+
+ // Only two points were previously seen. Use those IR points.
+ if (numActive == 2)
+ {
+ // Find two used IR trackers and get points.
+ int j = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ if (ir_stuff[i].using)
+ {
+ // Found previously used IR tracker. Get IR point coordinates.
+ ir_x[j] = ir_stuff[i].x;
+ ir_y[j] = ir_stuff[i].y;
+ j++;
+ }
+ }
+
+ x = (ir_x[0] + ir_x[1]) / 2.0;
+ y = (ir_y[0] + ir_y[1]) / 2.0;
+ num = 2;
+ }
+ // Don't apply mouse movement if not using only two IR points.
+ else
+ {
+ // Reset stats for IR trackers.
+ x = lastPos.x;
+ y = lastPos.y;
+ outtest = lastPos.outOfRange;
+ for (int i = 0; i < 4; i++)
+ {
+ ir_stuff[i].x = 1023;
+ ir_stuff[i].y = 1023;
+ ir_stuff[i].using = false;
+ }
+
+ num = 0;
+ }
+ }
+
+ /*
for (i = 0; i < 4; i++) {
int ir_x = ev[i].x;
int ir_y = ev[i].y;
+
if (ir_x < x && ir_x != 1023 && ir_x > 1) {
x = ir_x;
y = ir_y;
num++;
}
}
- if (num != 0) {
- out.code = map->IR_map[WG_IR_X][AXIS_CODE];
- out.value = (int) (-((x - 512) * map->IR_map[WG_IR_X][AXIS_SCALE]));
- write(uinput_fd, &out, sizeof(out));
- out.code = map->IR_map[WG_IR_Y][AXIS_CODE];
- out.value = (int) (((y - 380) * map->IR_map[WG_IR_Y][AXIS_SCALE]));
- write(uinput_fd, &out, sizeof(out));
+ */
+
+ // Only use if two points have been found.
+ if (num != 0)
+ {
+ x = 1023 - x;
+ double xratio = x / 1023.0;
+ double yratio = y / 767.0;
+
+ if (currentAccelEvent2)
+ {
+ double rotation = findIRRotation((double)ir_x[0], (double)ir_x[1],
+ (double)ir_y[0], (double)ir_y[1]);
+
+ xratio = xratio - 0.5;
+ yratio = yratio - 0.5;
+
+ rotateIRPoints(&xratio, &yratio, rotation);
+
+ xratio = xratio + 0.5;
+ yratio = yratio + 0.5;
+ }
+
+ //x = (int)floor(2557.50 * xratio - 767.19);
+ //y = (int)floor(1278.33 * yratio - 255.67);
+
+ //x = (int)floor(2557.50 * xratio - 767.25); // Input: [0.3, 0.7]
+ //y = (int)floor(1534.00 * yratio - 460.20); // Input: [0.3, 0.8]
+
+ x = (int)floor(3147.69 * xratio - 944.307); // input: [0.3, 0.625]
+ y = (int)floor(1917.50 * yratio - 575.25); // Input: [0.3, 0.7]
}
- out.type = EV_SYN;
- out.code = SYN_REPORT;
- out.value = 0;
- write(uinput_fd, &out, sizeof(out));
+ if (x < 0)
+ {
+ x = 0;
+ }
+ else if (x > 1023)
+ {
+ x = 1023;
+ }
+
+ if (y < 0)
+ {
+ y = 0;
+ }
+ else if (y > 767)
+ {
+ y = 767;
+ }
+
+ lastPos.x = x;
+ lastPos.y = y;
+ lastPos.outOfRange = (num == 0);
}
+
+void handle_mp(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[])
+{
+ bool event_gen = false;
+
+ if (holdCursor && holdCursorCount >= HOLDCURSORNUMPOLL)
+ {
+ holdCursor = false;
+ }
+ else if (holdCursor)
+ {
+ holdCursorCount++;
+ }
+
+ bool moveMouse = !ratchet && !holdCursor;
+
+ if (!wmpCalibrated)
+ {
+ if (ignoreMpEventCount >= 2)
+ {
+ calibrateMpPoll(ev);
+ moveMouse = moveMouse && wmpCalibrated;
+ if (wmpCalibrated)
+ {
+ ignoreMpEventCount = 0;
+ }
+ }
+ else
+ {
+ ignoreMpEventCount += 1;
+ moveMouse = false;
+ }
+ }
+
+ if (moveMouse)
+ {
+ /*double calibrateX = -200.0;
+ double calibrateY = 750.0;
+ */
+ double calibrateX = wmpFinalCalibrateX;
+ double calibrateY = wmpFinalCalibrateY;
+
+ // Perform calibration compensation on raw coordinates.
+ int currentX = ev[0].x - calibrateX;
+ int currentY = ev[0].z - calibrateY;
+ double rotation = 0.0;
+ if (currentAccelEvent2)
+ {
+ rotation = atan2(currentAccelEvent2[0].x, currentAccelEvent2[0].z);
+ double nothingX = currentX;
+ double nothingY = currentY;
+ //printf("BEFORE: x(%d) | z(%d) | r(%f)\n", ev[0].x, ev[0].z, rotation);
+ // Transform coordinates depending on how the Wiimote is being
+ // held.
+ rotateIRPoints(&nothingX, &nothingY, -rotation);
+
+ // Temporarily disable second rotation transformation.
+ //rotateIRPoints(&nothingX, &nothingY, 0.05);
+ //printf("AFTER: x(%f) | z(%f) | r(%f)\n", nothingX, nothingY, rotation);
+ ev[0].x = nothingX;
+ ev[0].z = nothingY;
+ }
+ else
+ {
+ ev[0].x = currentX;
+ ev[0].z = currentY;
+ }
+
+ double deadzone = 225;
+ double tempdeadangle2 = atan2((ev[0].z), ev[0].x);
+ double tempdeadangle = atan2(ev[0].x, ev[0].z);
+ //double deadzoneX = deadzone * fabs(cos(rotation));
+ //double deadzoneY = deadzone * 1.0 * fabs(sin(rotation));
+ double deadzoneX = deadzone * fabs(cos(tempdeadangle2));
+ double deadzoneY = deadzone * 1.0 * fabs(sin(tempdeadangle2));
+ double deadzoneX2 = deadzone * fabs(cos(tempdeadangle2));
+ double deadzoneY2 = deadzone * 1.0 * fabs(sin(tempdeadangle2));
+ //printf("DEADS: x(%f) z(%f) r(%f)\n\n", deadzoneX, deadzoneY, rotation);
+ //printf("DEADS2: x(%f) z(%f) r(%f)\n", deadzoneX2, deadzoneY2, tempdeadangle2);
+
+ double shiftX = 0.0;
+ double shiftY = 0.0;
+
+ //printf("CHECKS: x(%f) z(%f)\n\n", abs(ev[0].x - calibrateX), abs(ev[0].z - calibrateY));
+
+ if (abs(ev[0].x) > deadzoneX)
+ {
+ double x_out = 0;
+ double signbit = ev[0].x >= 0 ? 1.0 : -1.0;
+
+ double xratio = fmin((abs(ev[0].x) - deadzoneX) / (45000.0 - (deadzoneX)), 1.0);
+ x_out = (75.0 - 0.05) * (xratio) + 0.05;
+ x_out = x_out * signbit;
+
+ //printf("INPUT X: %d | OUTPUT X: %f\n\n", ev[0].x, x_out);
+
+ if ((remainderX >= 0) == (x_out >= 0))
+ {
+ x_out += remainderX;
+ }
+
+ // Make sure relative mouse movement does not exceed 127 pixels.
+ if (fabs(x_out) > 127)
+ {
+ x_out = (x_out < 0) ? -127 : 127;
+ }
+
+ remainderX = 0.0;
+
+ if (x_out > 0.0)
+ {
+ double temp = floor(x_out);
+ remainderX = x_out - temp;
+ x_out = temp;
+ }
+ else if (x_out < 0.0)
+ {
+ double temp = ceil(x_out);
+ remainderX = x_out - temp;
+ x_out = temp;
+ }
+
+ if (x_out != 0.0)
+ {
+ struct input_event out;
+ memset(&out, 0, sizeof(out));
+ out.type = EV_REL;
+ out.code = REL_X;
+ out.value = (int)x_out;
+ write(uinput_fd, &out, sizeof(out));
+
+ event_gen = true;
+ }
+ }
+ /*else
+ {
+ printf("JITTER X?: %d\n", ev[0].x);
+ }
+ */
+
+ if (abs(ev[0].z) > deadzoneY)
+ {
+ double y_out = 0;
+ double signbit = ev[0].z >= 0 ? -1.0 : 1.0;
+
+ double yratio = fmin((abs(ev[0].z) - deadzoneY) / (45000.0 - (deadzoneY)), 1.0);
+ y_out = (75.0 - 0.05) * (yratio) + 0.05;
+ y_out = y_out * signbit;
+
+ //printf("INPUT Y: %d | OUTPUT Y: %d | DEAD Y: %f\n\n", (ev[0].z - (int)calibrateY), y_out, deadzoneY);
+
+ if ((remainderY >= 0) == (y_out >= 0))
+ {
+ y_out += remainderY;
+ }
+
+ // Make sure relative mouse movement does not exceed 127 pixels.
+ if (fabs(y_out) > 127)
+ {
+ y_out = (y_out < 0) ? -127 : 127;
+ }
+
+ remainderY = 0.0;
+
+ if (y_out > 0.0)
+ {
+ double temp = floor(y_out);
+ remainderY = y_out - temp;
+ y_out = temp;
+ }
+ else if (y_out < 0.0)
+ {
+ double temp = ceil(y_out);
+ remainderY = y_out - temp;
+ y_out = temp;
+ }
+
+ if (y_out != 0.0)
+ {
+ struct input_event out;
+ memset(&out, 0, sizeof(out));
+ out.type = EV_REL;
+ out.code = REL_Y;
+ out.value = (int)y_out;
+ write(uinput_fd, &out, sizeof(out));
+
+ event_gen = true;
+ }
+ }
+ /*else
+ {
+ printf("JITTER Y?: %d\n", ev[0].z);
+ }
+ */
+
+ if (event_gen)
+ {
+ struct input_event out;
+ memset(&out, 0, sizeof(out));
+ out.type = EV_SYN;
+ out.code = SYN_REPORT;
+ out.value = 0;
+ write(uinput_fd, &out, sizeof(out));
+ }
+ }
+ else
+ {
+ remainderX = 0.0;
+ remainderY = 0.0;
+ }
+}
+
void handle_balance(int uinput_fd, struct event_map *map, struct xwii_event_abs ev[]) {
struct input_event out;
memset(&out,0,sizeof(out));
@@ -340,4 +848,750 @@ void handle_balance(int uinput_fd, struct event_map *map, struct xwii_event_abs
}
+void initIRTesting()
+{
+ memset(&ir_stuff, 0, sizeof(ir_stuff));
+ for (int i = 0; i < 4; i++)
+ {
+ ir_stuff[i].x = 1023;
+ ir_stuff[i].y = 1023;
+ ir_stuff[i].using = false;
+ }
+
+ lastPos.x = 1023;
+ lastPos.y = 1023;
+ lastPos.outOfRange = true;
+
+ currentIREvent = 0;
+ memset(&currentAccelEvent2, 0, sizeof(currentAccelEvent2));
+ memset(&currentIREvent2, 0, sizeof(currentIREvent2));
+ memset(&smoothXBuffer, 0, sizeof(smoothXBuffer));
+ memset(&smoothYBuffer, 0, sizeof(smoothYBuffer));
+ timeInit(&deltaEasingTimeX);
+ timeInit(&deltaEasingTimeY);
+ timeInit(&outOfReachElapsed);
+ timeInit(&initialInReachElapsed);
+ timeInit(&regionEasingX);
+}
+
+void rotateIRPoints(double *x, double *y, double rotation)
+{
+ double sinAngle = sin(rotation);
+ double cosAngle = cos(rotation);
+
+ double tempx = (*x) * cosAngle - (*y) * sinAngle;
+ double tempy = (*x) * sinAngle + (*y) * cosAngle;
+ *x = tempx;
+ *y = tempy;
+}
+
+double findIRRotation(float rawirx1, float rawirx2, float rawiry1, float rawiry2)
+{
+ double result = 0.0;
+
+ int l = 0;
+ int leftPoint = 0;
+ int r = 0;
+ int orientation = 0;
+
+ double accelX = currentAccelEvent2[0].x;
+ double accelZ = currentAccelEvent2[0].z;
+
+ double absx = fabs(accelX);
+ double absz = fabs(accelZ);
+
+ float tempirx[2];
+ memset(&tempirx, 0, sizeof(tempirx));
+ tempirx[0] = rawirx1;
+ tempirx[1] = rawirx2;
+
+ float tempiry[2];
+ memset(&tempiry, 0, sizeof(tempiry));
+ tempiry[0] = rawiry1;
+ tempiry[1] = rawiry2;
+
+ if (absz >= absx)
+ {
+ if (absz > 5)
+ {
+ orientation = (accelZ > 0) ? 0 : 2;
+ }
+ }
+ else
+ {
+ if (absx > 5)
+ {
+ orientation = (accelX > 0) ? 3 : 1;
+ }
+ }
+
+ //orientation = 0;
+ //printf("ORIENTATION: %i\n", orientation);
+
+ switch (orientation)
+ {
+ case 0:
+ {
+ l = (rawirx1 < rawirx2) ? 0 : 1;
+ break;
+ }
+ case 1:
+ {
+ l = (rawiry1 > rawiry2) ? 0 : 1;
+ break;
+ }
+ case 2:
+ {
+ l = (rawirx1 > rawirx2) ? 0 : 1;
+ break;
+ }
+ case 3:
+ {
+ l = (rawiry1 < rawiry2) ? 0 : 1;
+ break;
+ }
+ }
+
+ leftPoint = l;
+ r = 1 - l;
+
+ double dx = tempirx[r] - tempirx[l];
+ double dy = tempiry[r] - tempiry[l];
+ //double temper = (dx * dx) + (dy * dy);
+ double d = sqrt((dx * dx) + (dy * dy));
+
+ dx = dx / d;
+ dy = dy / d;
+
+ result = atan2(dy, dx);
+ return result;
+}
+
+void moveVirtualMouseTwo(int uinput_fd, int x, int y, bool outOfRange)
+{
+ bool shouldMoveFPSCursor = !outOfReachStatus;
+
+ if (!outOfRange)
+ {
+ outOfReachStatus = false;
+ if (outOfReachElapsed.running)
+ {
+ timeStop(&outOfReachElapsed);
+ }
+
+ // Check if remote has moved into IR range.
+ if (initialInReachStatus)
+ {
+ if (!initialInReachElapsed.running)
+ {
+ // Start timer if not running.
+ timeRestart(&initialInReachElapsed);
+ }
+
+ if (initialInReachElapsed.running)
+ {
+ unsigned int elapsed = timeElapsedInMilliseconds(&initialInReachElapsed);
+ if (elapsed < INITIAL_INREACH_ELAPSED_TIME)
+ {
+ shouldMoveFPSCursor = false;
+ }
+ else
+ {
+ shouldMoveFPSCursor = true;
+ initialInReachStatus = false;
+ timeStop(&initialInReachElapsed);
+ }
+ }
+ }
+ else
+ {
+ shouldMoveFPSCursor = true;
+ }
+ }
+ else if (!outOfReachStatus)
+ {
+ if (!outOfReachElapsed.running)
+ {
+ timeRestart(&outOfReachElapsed);
+ }
+
+ if (outOfReachElapsed.running)
+ {
+ unsigned int elapsed = timeElapsedInMilliseconds(&outOfReachElapsed);
+ if (elapsed >= OUTOFREACH_ELAPSED_TIME)
+ {
+ outOfReachStatus = true;
+ timeStop(&outOfReachElapsed);
+ //printf("STOPPING OUT OF RANGE\n");
+ }
+ else
+ {
+ outOfReachStatus = false;
+ }
+ }
+ }
+
+ // Checks show that remote should be considered in IR range.
+ if (shouldMoveFPSCursor)
+ //if (!outOfReachStatus)
+ {
+ double xratio = x / 1023.0;
+ double yratio = y / 767.0;
+ addSmoothBufferValues(x, y);
+
+ int smoothX = 0;
+ int smoothY = 0;
+ getSmoothBufferValues(&smoothX, &smoothY);
+ xratio = smoothX / 1023.0;
+ yratio = smoothY / 767.0;
+
+ double deadzone = 0.018;
+ //double fps_mouse_speed = 25.0;
+ double fps_mouse_speed = 20.0;
+
+ double tempdeadangle = atan2(-(yratio - 0.5), xratio - 0.5);
+ double deadzoneX = deadzone * fabs(cos(tempdeadangle));
+ double deadzoneY = deadzone * 1.0 * fabs(sin(tempdeadangle));
+
+ double testAccelMulti = 4.0;
+ double testAccelMinTravel = 0.08;
+ double testAccelMaxTravel = 0.425;
+ double testAccelEasingDuration = 0.03;
+ double testRegionEasingXDuration = 0.025;
+ bool testDeltaAccel = true;
+
+ double shiftX = 0.0;
+ double shiftY = 0.0;
+
+ if (fabs(xratio - 0.5) > deadzoneX)
+ {
+ if (xratio >= 0.5)
+ {
+ shiftX = (xratio - 0.5 - deadzoneX) / (1.0 - 0.5 - deadzoneX);
+ }
+ else
+ {
+ shiftX = (xratio - (0.5 - deadzoneX)) / (1.0 - 0.5 - deadzoneX);
+ }
+ }
+
+ if (fabs(yratio - 0.5) > deadzoneY)
+ {
+ if (yratio >= 0.5)
+ {
+ shiftY = (yratio - 0.5 - deadzoneY) / (1.0 - 0.5 - deadzoneY);
+ }
+ else
+ {
+ shiftY = (yratio - (0.5 - deadzoneY)) / (1.0 - 0.5 - deadzoneY);
+ }
+ }
+
+ double signshiftX = (shiftX >= 0) ? 1.0 : -1.0;
+ double signshiftY = (shiftY >= 0) ? 1.0 : -1.0;
+
+ double absX = fabs(shiftX);
+ double absY = fabs(shiftY);
+
+ if (absX <= 0.75 && regionEasingX.running)
+ {
+ // No longer in easing region
+ timeStop(&regionEasingX);
+ }
+ else if (absX > 0.75 && regionEasingX.running &&
+ (previousPointerRatioX >= 0.5) != (xratio >= 0.5))
+ {
+ // Direction changed quickly. Restart easing timer.
+ timeRestart(&regionEasingX);
+ }
+
+ if (absX <= 0.4)
+ {
+ shiftX = 0.395 * absX;
+ }
+ else if (absX <= 0.75)
+ {
+ shiftX = 1.0 * absX - 0.242;
+ }
+ else
+ {
+ double tempAbsx = absX;
+ bool enableRegionEasing = testRegionEasingXDuration > 0.0;
+ if (enableRegionEasing)
+ {
+ double easingDuration = testRegionEasingXDuration;
+ double easingElapsed = 0.0;
+ double elapsedDiff = 1.0;
+ double regionEasingXOffset = 0.8;
+ if (regionEasingX.running)
+ {
+ easingElapsed = timeElapsedInMilliseconds(&regionEasingX);
+ }
+ else
+ {
+ timeRestart(&regionEasingX);
+ }
+
+ double adjustedEasingDuration = ((4.0 * absX) - 3.0) * easingDuration;
+ //double adjustedEasingDuration = easingDuration;
+ if (easingDuration > 0.0 && adjustedEasingDuration > 0.0 &&
+ (easingElapsed * 0.001) < adjustedEasingDuration)
+ {
+ //elapsedDiff = (easingElapsed * 0.001) / easingDuration;
+ //double minAbsRegionX = 0.75;
+ double minAbsRegionX = absX + (regionEasingXOffset * (absX - 0.75));
+ elapsedDiff = (easingElapsed * 0.001) / adjustedEasingDuration;
+ //elapsedDiff = (absX - 0.75) * elapsedDiff + 0.75;
+ elapsedDiff = (absX - minAbsRegionX) * elapsedDiff + minAbsRegionX;
+ }
+ else
+ {
+ elapsedDiff = absX;
+ }
+
+ tempAbsx = elapsedDiff;
+ }
+
+ shiftX = 1.968 * absX - 0.968;
+ }
+
+ if (absY <= 0.4)
+ {
+ shiftY = 0.395 * absY;
+ }
+ else if (absY <= 0.75)
+ {
+ shiftY = 1.0 * absY - 0.242;
+ }
+ else
+ {
+ shiftY = 1.968 * absY - 0.968;
+ }
+
+ // Add sign bit
+ shiftX = signshiftX * shiftX;
+ shiftY = signshiftY * shiftY;
+
+ // Calculate delta acceleration slope and offset.
+ double accelSlope = (testAccelMulti - 1.0) / (testAccelMaxTravel - testAccelMinTravel);
+ double accelOffset = 1.0 - (accelSlope * testAccelMinTravel);
+
+ // If deltaX >= 0.1 and displacement is increasing then
+ // use acceleration multiplier.
+ if (testDeltaAccel && fabs(previousPointerRatioX - xratio) >= testAccelMinTravel &&
+ (xratio - previousPointerRatioX >= 0.0) == (xratio >= 0.5))
+ {
+ double tempTravel = fmin(fabs(previousPointerRatioX - xratio), testAccelMaxTravel);
+ if (accelHelperX > 1.0)
+ {
+ // Already in acceleration mode. Add accel
+ // dead zone to travel.
+ tempTravel = fmin(tempTravel + testAccelMinTravel, testAccelMaxTravel);
+ }
+
+ double tempDist = fmin(tempTravel, testAccelMaxTravel);
+
+ shiftX = shiftX * (accelSlope * tempDist + accelOffset);
+ previousPointerRatioX = xratio;
+ accelHelperX = (accelSlope * tempDist + accelOffset);
+ accelTravelX = tempTravel;
+ timeRestart(&deltaEasingTimeX);
+ }
+ else if (testDeltaAccel && testAccelEasingDuration > 0.0 &&
+ accelHelperX > 0.0 &&
+ fabs(xratio - previousPointerRatioX) < testAccelMinTravel &&
+ (previousPointerRatioX >= 0.5) == (xratio >= 0.5))
+ {
+ unsigned int timeElapsed = timeElapsedInMilliseconds(&deltaEasingTimeX);
+ double elapsedDiff = 1.0;
+ double tempAccel = accelHelperX;
+ double tempTravel = accelTravelX;
+
+ if ((xratio - previousPointerRatioX >= 0.0) != (xratio >= 0.5))
+ {
+ // Travelling towards dead zone. Decrease acceleration and duration.
+ tempTravel = fmin(fabs(previousPointerRatioX - xratio), testAccelMaxTravel);
+ tempTravel = fmax(fmin((accelTravelX - tempTravel), testAccelMaxTravel), testAccelMinTravel);
+ tempAccel = (accelSlope * tempTravel + accelOffset);
+ }
+
+ double elapsedDuration = testAccelEasingDuration * (tempAccel / testAccelMulti);
+ if ((timeElapsed * 0.001) < elapsedDuration)
+ {
+ elapsedDiff = ((timeElapsed * 0.001) / elapsedDuration);
+ elapsedDiff = (1.0 - tempAccel) * (elapsedDiff * elapsedDiff * elapsedDiff) + tempAccel;
+ shiftX = elapsedDiff * shiftX;
+ }
+ else
+ {
+ // Easing time has ended. Reset values.
+ previousPointerRatioX = xratio;
+ accelHelperX = 0.0;
+ accelTravelX = 0.0;
+ timeStop(&deltaEasingTimeX);
+ }
+ }
+ else
+ {
+ // Don't apply acceleration. Reset values.
+ previousPointerRatioX = xratio;
+ accelHelperX = 0.0;
+ accelTravelX = 0.0;
+ if (deltaEasingTimeX.running)
+ {
+ timeStop(&deltaEasingTimeX);
+ }
+ }
+
+ // If deltaY >= 0.1 and displacement is increasing then
+ // use acceleration multiplier.
+ if (testDeltaAccel && fabs(previousPointerRatioY - yratio) >= testAccelMinTravel &&
+ (yratio - previousPointerRatioY >= 0.0) == (yratio >= 0.5))
+ {
+ double tempTravel = fmin(fabs(previousPointerRatioY - yratio), testAccelMaxTravel);
+ if (accelHelperY > 1.0)
+ {
+ // Already in acceleration mode. Add accel
+ // dead zone to travel.
+ tempTravel = fmin(tempTravel + testAccelMinTravel, testAccelMaxTravel);
+ }
+
+ //double tempDist = fmin(tempTravel / 0.5, 1.0);
+ double tempDist = fmin(tempTravel, testAccelMaxTravel);
+
+ shiftY = shiftY * (accelSlope * tempDist + accelOffset);
+ previousPointerRatioY = yratio;
+ accelHelperY = (accelSlope * tempDist + accelOffset);
+ accelTravelY = tempTravel;
+ timeRestart(&deltaEasingTimeY);
+
+ //double tempDist = fmin((fabs(previousPointerRatioY - yratio) - 0.1) / 0.5, 1.0);
+ //shiftY = shiftY * (9.0 * tempDist + 1.0);
+ }
+ else if (testDeltaAccel && testAccelEasingDuration > 0.0 &&
+ accelHelperY > 0.0 &&
+ fabs(yratio - previousPointerRatioY) < testAccelMinTravel &&
+ (previousPointerRatioY >= 0.5) == (yratio >= 0.5))
+ {
+ unsigned int timeElapsed = timeElapsedInMilliseconds(&deltaEasingTimeY);
+ double elapsedDiff = 1.0;
+ double tempAccel = accelHelperY;
+ double tempTravel = accelTravelY;
+
+ if ((yratio - previousPointerRatioY >= 0.0) != (yratio >= 0.5))
+ {
+ // Travelling towards dead zone. Decrease acceleration and duration.
+ tempTravel = fmin(fabs(previousPointerRatioY - yratio), testAccelMaxTravel);
+ tempTravel = fmax(fmin((accelTravelY - tempTravel), testAccelMaxTravel), testAccelMinTravel);
+ tempAccel = (accelSlope * tempTravel + accelOffset);
+ }
+
+ double elapsedDuration = testAccelEasingDuration * (tempAccel / testAccelMulti);
+ if ((timeElapsed * 0.001) < elapsedDuration)
+ {
+ elapsedDiff = ((timeElapsed * 0.001) / elapsedDuration);
+ elapsedDiff = (1.0 - tempAccel) * (elapsedDiff * elapsedDiff * elapsedDiff) + tempAccel;
+ shiftY = elapsedDiff * shiftY;
+ }
+ else
+ {
+ // Easing time has ended. Reset values.
+ previousPointerRatioY = yratio;
+ accelHelperY = 0.0;
+ accelTravelY = 0.0;
+ timeStop(&deltaEasingTimeY);
+ }
+ }
+ else
+ {
+ // Don't apply acceleration. Reset values.
+ previousPointerRatioY = yratio;
+ accelHelperY = 0.0;
+ accelTravelY = 0.0;
+ if (deltaEasingTimeY.running)
+ {
+ timeStop(&deltaEasingTimeY);
+ }
+ }
+
+ // Find initial relative mouse speed.
+ double mouseX = fps_mouse_speed * shiftX;
+ double mouseY = fps_mouse_speed * shiftY;
+
+ if ((remainderX >= 0) == (mouseX >= 0))
+ {
+ mouseX += remainderX;
+ }
+
+ if ((remainderY >= 0) == (mouseY >= 0))
+ {
+ mouseY += remainderY;
+ }
+
+ // Make sure relative mouse movement does not exceed 127 pixels.
+ if (fabs(mouseX) > 127)
+ {
+ mouseX = (mouseX < 0) ? -127 : 127;
+ }
+
+ // Make sure relative mouse movement does not exceed 127 pixels.
+ if (fabs(mouseY) > 127)
+ {
+ mouseY = (mouseY < 0) ? -127 : 127;
+ }
+
+ remainderX = 0.0;
+ remainderY = 0.0;
+
+ if (mouseX > 0.0)
+ {
+ double temp = floor(mouseX);
+ remainderX = mouseX - temp;
+ mouseX = temp;
+ }
+ else if (mouseX < 0.0)
+ {
+ double temp = ceil(mouseX);
+ remainderX = mouseX - temp;
+ mouseX = temp;
+ }
+
+ if (mouseY > 0.0)
+ {
+ double temp = floor(mouseY);
+ remainderY = mouseY - temp;
+ mouseY = temp;
+ }
+ else if (mouseY < 0.0)
+ {
+ double temp = ceil(mouseY);
+ remainderY = mouseY - temp;
+ mouseY = temp;
+ }
+
+ struct input_event out;
+ memset(&out, 0, sizeof(out));
+
+ bool mouseEvent = (mouseX != 0 || mouseY != 0);
+ if (mouseEvent)
+ {
+ //printf("MOVING: X(%f) | Y(%f)\n\n", mouseX, mouseY);
+
+ out.type = EV_REL;
+ out.code = REL_X;
+ out.value = (int)mouseX;
+ gettimeofday(&out.time, 0);
+ write(uinput_fd, &out, sizeof(out));
+
+ out.type = EV_REL;
+ out.code = REL_Y;
+ out.value = (int)mouseY;
+ gettimeofday(&out.time, 0);
+ write(uinput_fd, &out, sizeof(out));
+
+ out.type = EV_SYN;
+ out.code = SYN_REPORT;
+ out.value = 0;
+ gettimeofday(&out.time, 0);
+ write(uinput_fd, &out, sizeof(out));
+ }
+ }
+ else
+ {
+ // Consider outside of IR range. Reset some values.
+ remainderX = 0.0;
+ remainderY = 0.0;
+
+ accelHelperX = 0.0;
+ accelHelperY = 0.0;
+ accelTravelX = 0.0;
+ accelTravelY = 0.0;
+
+ if (deltaEasingTimeX.running)
+ {
+ timeStop(&deltaEasingTimeX);
+ }
+
+ if (deltaEasingTimeY.running)
+ {
+ timeStop(&deltaEasingTimeY);
+ }
+
+ initialInReachStatus = true;
+
+ if (regionEasingX.running)
+ {
+ timeStop(&regionEasingX);
+ }
+ }
+}
+
+void wiimoteglue_handle_ir_event(struct wiimoteglue_state *state)
+{
+ struct event_map *mapping = 0;
+ if (devicemapping)
+ {
+ mapping = devicemapping;
+ }
+
+ if (currentIREvent2 && mapping)
+ {
+ handle_IR(state->virtual_keyboardmouse_fd, mapping, currentIREvent2);
+
+ int x = lastPos.x;
+ int y = lastPos.y;
+ bool outOfRange = lastPos.outOfRange;
+
+ moveVirtualMouseTwo(state->virtual_keyboardmouse_fd, x, y, outOfRange);
+ }
+}
+
+void wiimoteglue_handle_mp_event(struct wiimoteglue_state *state)
+{
+ if (mpmapping && hasMpEvent)
+ {
+ handle_mp(state->virtual_keyboardmouse_fd, mpmapping, currentMpEvent);
+ hasMpEvent = false;
+ mpmapping = 0;
+ }
+ else
+ {
+ remainderX = 0.0;
+ remainderY = 0.0;
+ }
+}
+
+void addSmoothBufferValues(int xval, int yval)
+{
+ smoothXBuffer[smoothXBufferTail] = xval;
+ smoothYBuffer[smoothXBufferTail] = yval;
+
+ smoothXBufferTail++;
+ smoothXBufferTail++;
+
+ smoothXBufferTail = smoothXBufferTail % smoothXBufferLen;
+ smoothXBufferTail = smoothXBufferTail % smoothYBufferLen;
+
+ smoothXBufferCount = (int)fmin(smoothXBufferCount + 1, smoothXBufferLen);
+ smoothYBufferCount = (int)fmin(smoothYBufferCount + 1, smoothYBufferLen);
+
+ if (smoothXBufferCount > 0 && smoothXBufferTail == smoothXBufferHead)
+ {
+ smoothXBufferHead = (smoothXBufferHead + 1) % smoothXBufferLen;
+ }
+
+ if (smoothXBufferCount > 0 && smoothYBufferTail == smoothYBufferHead)
+ {
+ smoothYBufferHead = (smoothYBufferHead + 1) % smoothYBufferLen;
+ }
+}
+
+void getSmoothBufferValues(int *xval, int *yval)
+{
+ if (xval && yval && smoothXBufferCount > 0 && smoothYBufferCount > 0)
+ {
+ double tempx = 0.0;
+ double tempy = 0.0;
+ int xresult = 0;
+ int yresult = 0;
+ double currentWeight = 1.0;
+ double finalWeight = 0.0;
+
+ for (int i = smoothXBufferTail; i != smoothXBufferHead; i = (i > 0) ? i-1 : smoothXBufferLen - 1)
+ {
+ int idx = i;
+ tempx += (smoothXBuffer[idx] * currentWeight);
+ finalWeight += currentWeight;
+ currentWeight *= 0.5;
+ }
+
+ xresult = (int)(tempx / finalWeight);
+ *xval = xresult;
+
+ currentWeight = 1.0;
+ finalWeight = 0.0;
+
+ for (int i = smoothYBufferTail; i != smoothYBufferHead; i = (i > 0) ? i-1 : smoothYBufferLen - 1)
+ {
+ int idx = i;
+ tempy += (smoothYBuffer[idx] * currentWeight);
+ finalWeight += currentWeight;
+ currentWeight *= 0.5;
+ }
+
+
+ yresult = (int)(tempy / finalWeight);
+ *yval = yresult;
+ }
+}
+
+void calibrateMpPoll(struct xwii_event_abs ev[])
+{
+ if (!wmpCalibrated)
+ {
+ wmpSumCalibrateX += ev[0].x;
+ wmpSumCalibrateY += ev[0].z;
+ calibratePollCount += 1;
+
+ if (calibratePollCount >= 10)
+ {
+ wmpFinalCalibrateX = wmpSumCalibrateX / (int)calibratePollCount;
+ wmpFinalCalibrateY = wmpSumCalibrateY / (int)calibratePollCount;
+ wmpSumCalibrateX = wmpSumCalibrateY = 0;
+ wmpCalibrated = true;
+ }
+ }
+}
+
+unsigned int timeElapsedInMilliseconds(struct timeHelper *time)
+{
+ unsigned int result = 0;
+ if (time && time->running)
+ {
+ struct timeb current_time;
+ ftime(&current_time);
+ result = ((unsigned int)(current_time.time * 1000 + current_time.millitm) -
+ (unsigned int)(time->startTime.time * 1000 + time->startTime.millitm));
+
+ result = (unsigned int)fmax(result, 0);
+ }
+
+ return result;
+}
+
+void timeRestart(struct timeHelper *time)
+{
+ if (time)
+ {
+ ftime(&time->startTime);
+ time->running = true;
+ }
+}
+
+void timeStop(struct timeHelper *time)
+{
+ if (time && time->running)
+ {
+ ftime(&time->startTime);
+ time->running = false;
+ }
+}
+
+void timeStart(struct timeHelper *time)
+{
+ if (time)
+ {
+ ftime(&time->startTime);
+ time->running = true;
+ }
+}
+
+void timeInit(struct timeHelper *time)
+{
+ if (time)
+ {
+ time->running = false;
+ ftime(&time->startTime);
+ }
+}
diff --git a/src/uinput.c b/src/uinput.c
index 8a037ca..458e6ac 100644
--- a/src/uinput.c
+++ b/src/uinput.c
@@ -139,7 +139,8 @@ int open_uinput_gamepad_fd(char* uinput_path) {
int open_uinput_keyboardmouse_fd(char* uinput_path) {
static int abs[] = { ABS_X, ABS_Y};
- static int key[] = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,BTN_TOUCH,BTN_TOOL_PEN};
+ //static int key[] = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,BTN_TOUCH,BTN_TOOL_PEN};
+ static int key[] = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT};
/* BTN_TOOL_PEN seems to successfully hint to evdev that
* we are going to be outputting absolute positions,
* not relative motions.
@@ -161,14 +162,14 @@ int open_uinput_keyboardmouse_fd(char* uinput_path) {
uidev.id.product = 0x1;
uidev.id.version = 1;
- ioctl(fd, UI_SET_EVBIT, EV_ABS);
+ /*ioctl(fd, UI_SET_EVBIT, EV_ABS);
for (i = 0; i < 2; i++) {
ioctl(fd, UI_SET_ABSBIT, abs[i]);
uidev.absmin[abs[i]] = -32768;
uidev.absmax[abs[i]] = 32768;
uidev.absflat[abs[i]] = 4096;
}
-
+ */
/*Just set all possible keys that come before BTN_MISC
@@ -183,10 +184,14 @@ int open_uinput_keyboardmouse_fd(char* uinput_path) {
/*Set standard mouse buttons*/
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 3; i++) {
ioctl(fd, UI_SET_KEYBIT, key[i]);
}
+ ioctl(fd, UI_SET_EVBIT, EV_REL);
+ ioctl(fd, UI_SET_RELBIT, REL_X);
+ ioctl(fd, UI_SET_RELBIT, REL_Y);
+
write(fd, &uidev, sizeof(uidev));
if (ioctl(fd, UI_DEV_CREATE) < 0)
perror("uinput device creation");
diff --git a/src/wiimoteglue.h b/src/wiimoteglue.h
index d247024..4096b54 100644
--- a/src/wiimoteglue.h
+++ b/src/wiimoteglue.h
@@ -8,9 +8,9 @@
#define ABS_LIMIT 32767
-#define TILT_LIMIT 80
+#define TILT_LIMIT 95
#define TILT_SCALE (ABS_LIMIT/TILT_LIMIT)
-#define NUNCHUK_LIMIT 90
+#define NUNCHUK_LIMIT 92
#define NUNCHUK_SCALE (ABS_LIMIT/NUNCHUK_LIMIT)
#define CLASSIC_LIMIT 22
#define CLASSIC_SCALE (ABS_LIMIT/CLASSIC_LIMIT)
@@ -182,6 +182,27 @@ enum bal_axis {
WG_BAL_Y
};
+struct testir_info
+{
+ int x;
+ int y;
+ bool using;
+};
+
+struct testir_info ir_stuff[4];
+
+struct irpos
+{
+ int x;
+ int y;
+ bool outOfRange;
+};
+
+struct irpos lastPos;
+
+void initIRTesting();
+
+
char* try_to_find_uinput();
int wiimoteglue_uinput_close(int num_slots, struct virtual_controller slots[]);
int wiimoteglue_uinput_init(int num_slots, struct virtual_controller slots[], char* uinput_path);
@@ -200,6 +221,8 @@ int wiimoteglue_handle_input(struct wiimoteglue_state *state, int file);
int wiimoteglue_update_wiimote_ifaces(struct wii_device *dev);
int wiimoteglue_handle_wii_event(struct wiimoteglue_state *state, struct wii_device *dev);
+void wiimoteglue_handle_ir_event(struct wiimoteglue_state *state);
+void wiimoteglue_handle_mp_event(struct wiimoteglue_state *state);
struct virtual_controller* find_open_slot(struct wiimoteglue_state *state, int dev_type);
struct virtual_controller* lookup_slot(struct wiimoteglue_state* state, char* name);
@jgeumlek
Copy link

Whoa. Quite a change compared to just taking the leftmost point. It looked pretty good in the video, at least as far I can tell by just watching the gameplay.

I'm glad WiimoteGlue offered you a starting point for experimentation. I've been using it to experiment as well, but mostly on the laughably terrible control scheme spectrum (such as playing a Zelda style game with the balance board).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment