aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ginput/mouse.c236
1 files changed, 145 insertions, 91 deletions
diff --git a/src/ginput/mouse.c b/src/ginput/mouse.c
index 8bee3499..aad6119a 100644
--- a/src/ginput/mouse.c
+++ b/src/ginput/mouse.c
@@ -39,12 +39,12 @@
#endif
typedef struct Calibration_t {
- float ax;
- float bx;
- float cx;
- float ay;
- float by;
- float cy;
+ float ax;
+ float bx;
+ float cx;
+ float ay;
+ float by;
+ float cy;
} Calibration;
#endif
@@ -76,7 +76,57 @@ static struct MouseConfig_t {
GDisplay * display;
} MouseConfig;
+void _tsOrientClip(MouseReading *pt, GDisplay *g, bool_t doClip) {
+ coord_t w, h;
+
+ w = gdispGGetWidth(g);
+ h = gdispGGetHeight(g);
+
+ #if GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION
+ switch(gdispGGetOrientation(g)) {
+ case GDISP_ROTATE_0:
+ break;
+ case GDISP_ROTATE_90:
+ {
+ coord_t t = pt->x;
+ pt->x = w - 1 - pt->y;
+ pt->y = t;
+ }
+ break;
+ case GDISP_ROTATE_180:
+ pt->x = w - 1 - pt->x;
+ pt->y = h - 1 - pt->y;
+ break;
+ case GDISP_ROTATE_270:
+ {
+ coord_t t = pt->y;
+ pt->y = h - 1 - pt->x;
+ pt->x = t;
+ }
+ break;
+ default:
+ break;
+ }
+ #endif
+
+ if (doClip) {
+ if (pt->x < 0) pt->x = 0;
+ else if (pt->x >= w) pt->x = w-1;
+ if (pt->y < 0) pt->y = 0;
+ else if (pt->y >= h) pt->y = h-1;
+ }
+}
+
#if GINPUT_MOUSE_NEED_CALIBRATION
+ static inline void _tsSetIdentity(Calibration *c) {
+ c->ax = 1;
+ c->bx = 0;
+ c->cx = 0;
+ c->ay = 0;
+ c->by = 1;
+ c->cy = 0;
+ }
+
static inline void _tsDrawCross(const MousePoint *pp) {
gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y, pp->x-2, pp->y, White);
gdispGDrawLine(MouseConfig.display, pp->x+2, pp->y, pp->x+15, pp->y, White);
@@ -105,41 +155,96 @@ static struct MouseConfig_t {
pt->y = (coord_t) (c->ay * pt->x + c->by * pt->y + c->cy);
}
- static inline void _tsDo3PointCalibration(const MousePoint *cross, const MousePoint *points, Calibration *c) {
- float dx, dx0, dx1, dx2, dy0, dy1, dy2;
+ static inline void _tsDo3PointCalibration(const MousePoint *cross, const MousePoint *points, GDisplay *g, Calibration *c) {
+ float dx;
+ coord_t c0, c1, c2;
- /* Compute all the required determinants */
- dx = ((float)(points[0].x - points[2].x)) * ((float)(points[1].y - points[2].y))
- - ((float)(points[1].x - points[2].x)) * ((float)(points[0].y - points[2].y));
-
- dx0 = ((float)(cross[0].x - cross[2].x)) * ((float)(points[1].y - points[2].y))
- - ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].y - points[2].y));
-
- dx1 = ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].x - points[2].x))
- - ((float)(cross[0].x - cross[2].x)) * ((float)(points[1].x - points[2].x));
-
- dx2 = cross[0].x * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y) -
- cross[1].x * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y) +
- cross[2].x * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y);
-
- dy0 = ((float)(cross[0].y - cross[2].y)) * ((float)(points[1].y - points[2].y))
- - ((float)(cross[1].y - cross[2].y)) * ((float)(points[0].y - points[2].y));
+ #if GDISP_NEED_CONTROL
+ /* Convert all cross points back to GDISP_ROTATE_0 convention
+ * before calculating the calibration matrix.
+ */
+ switch(gdispGGetOrientation(g)) {
+ case GDISP_ROTATE_90:
+ c0 = cross[0].y;
+ c1 = cross[1].y;
+ c2 = cross[2].y;
+ break;
+ case GDISP_ROTATE_180:
+ c0 = c1 = c2 = gdispGGetWidth(g) - 1;
+ c0 -= cross[0].x;
+ c1 -= cross[1].x;
+ c2 -= cross[2].x;
+ break;
+ case GDISP_ROTATE_270:
+ c0 = c1 = c2 = gdispGGetHeight(g) - 1;
+ c0 -= cross[0].y;
+ c1 -= cross[1].y;
+ c2 -= cross[2].y;
+ break;
+ case GDISP_ROTATE_0:
+ default:
+ c0 = cross[0].x;
+ c1 = cross[1].x;
+ c2 = cross[2].x;
+ break;
+ }
+ #else
+ c0 = cross[0].x;
+ c1 = cross[1].x;
+ c2 = cross[2].x;
+ #endif
- dy1 = ((float)(cross[1].y - cross[2].y)) * ((float)(points[0].x - points[2].x))
- - ((float)(cross[0].y - cross[2].y)) * ((float)(points[1].x - points[2].x));
+ /* Compute all the required determinants */
+ dx = (float)(points[0].x - points[2].x) * (float)(points[1].y - points[2].y)
+ - (float)(points[1].x - points[2].x) * (float)(points[0].y - points[2].y);
- dy2 = cross[0].y * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y) -
- cross[1].y * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y) +
- cross[2].y * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y);
+ c->ax = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
+ - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
+ c->bx = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
+ - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
+ c->cx = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
+ - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
+ + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
- /* Now, calculate all the required coefficients */
- c->ax = dx0 / dx;
- c->bx = dx1 / dx;
- c->cx = dx2 / dx;
+ #if GDISP_NEED_CONTROL
+ switch(gdispGGetOrientation(g)) {
+ case GDISP_ROTATE_90:
+ c0 = c1 = c2 = gdispGGetWidth(g) - 1;
+ c0 -= cross[0].x;
+ c1 -= cross[1].x;
+ c2 -= cross[2].x;
+ break;
+ case GDISP_ROTATE_180:
+ c0 = c1 = c2 = gdispGGetHeight(g) - 1;
+ c0 -= cross[0].y;
+ c1 -= cross[1].y;
+ c2 -= cross[2].y;
+ break;
+ case GDISP_ROTATE_270:
+ c0 = cross[0].x;
+ c1 = cross[1].x;
+ c2 = cross[2].x;
+ break;
+ case GDISP_ROTATE_0:
+ default:
+ c0 = cross[0].y;
+ c1 = cross[1].y;
+ c2 = cross[2].y;
+ break;
+ }
+ #else
+ c0 = cross[0].y;
+ c1 = cross[1].y;
+ c2 = cross[2].y;
+ #endif
- c->ay = dy0 / dx;
- c->by = dy1 / dx;
- c->cy = dy2 / dx;
+ c->ay = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
+ - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
+ c->by = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
+ - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
+ c->cy = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
+ - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
+ + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
}
#endif
@@ -166,56 +271,13 @@ static struct MouseConfig_t {
#endif
static void get_calibrated_reading(MouseReading *pt) {
- #if GINPUT_MOUSE_NEED_CALIBRATION || (GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION)
- coord_t w, h;
- #endif
-
get_raw_reading(pt);
#if GINPUT_MOUSE_NEED_CALIBRATION
_tsTransform(pt, &MouseConfig.caldata);
#endif
- #if GINPUT_MOUSE_NEED_CALIBRATION || (GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION)
- w = gdispGGetWidth(MouseConfig.display);
- h = gdispGGetHeight(MouseConfig.display);
- #endif
-
- #if GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION
- switch(gdispGGetOrientation(MouseConfig.display)) {
- case GDISP_ROTATE_0:
- break;
- case GDISP_ROTATE_90:
- {
- coord_t t = pt->x;
- pt->x = w - 1 - pt->y;
- pt->y = t;
- }
- break;
- case GDISP_ROTATE_180:
- pt->x = w - 1 - pt->x;
- pt->y = h - 1 - pt->y;
- break;
- case GDISP_ROTATE_270:
- {
- coord_t t = pt->y;
- pt->y = h - 1 - pt->x;
- pt->x = t;
- }
- break;
- default:
- break;
- }
- #endif
-
- #if GINPUT_MOUSE_NEED_CALIBRATION
- if (!(MouseConfig.flags & FLG_CAL_RAW)) {
- if (pt->x < 0) pt->x = 0;
- else if (pt->x >= w) pt->x = w-1;
- if (pt->y < 0) pt->y = 0;
- else if (pt->y >= h) pt->y = h-1;
- }
- #endif
+ _tsOrientClip(pt, MouseConfig.display, !(MouseConfig.flags & FLG_CAL_RAW));
}
static void MousePoll(void *param) {
@@ -359,12 +421,7 @@ GSourceHandle ginputGetMouse(uint16_t instance) {
if ((MouseConfig.flags & FLG_CAL_FREE))
gfxFree((void *)pc);
} else if (instance == 9999) {
- MouseConfig.caldata.ax = 1;
- MouseConfig.caldata.bx = 0;
- MouseConfig.caldata.cx = 0;
- MouseConfig.caldata.ay = 0;
- MouseConfig.caldata.by = 1;
- MouseConfig.caldata.cy = 0;
+ _tsSetIdentity(&MouseConfig.caldata);
MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
} else
ginputCalibrateMouse(instance);
@@ -461,10 +518,6 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
gtimerStop(&MouseTimer);
MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
- #if GDISP_NEED_CONTROL
- gdispGSetOrientation(MouseConfig.display, GDISP_ROTATE_0);
- #endif
-
#if GDISP_NEED_CLIP
gdispGSetClip(MouseConfig.display, 0, 0, width, height);
#endif
@@ -511,7 +564,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
}
/* Apply 3 point calibration algorithm */
- _tsDo3PointCalibration(cross, points, &MouseConfig.caldata);
+ _tsDo3PointCalibration(cross, points, MouseConfig.display, &MouseConfig.caldata);
/* Verification of correctness of calibration (optional) :
* See if the 4th point (Middle of the screen) coincides with the calibrated
@@ -523,6 +576,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
MouseConfig.t.x = points[3].x;
MouseConfig.t.y = points[3].y;
_tsTransform(&MouseConfig.t, &MouseConfig.caldata);
+ _tsOrientClip(&MouseConfig.t, MouseConfig.display, FALSE);
/* Calculate the delta */
err = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +