Allow touch calibration to occur in any screen orientation (through the use of the GDISP_DEFAULT_ORIENTATION define).
This commit is contained in:
parent
200f7ecf6d
commit
d4c2656e60
1 changed files with 145 additions and 91 deletions
|
@ -39,12 +39,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct Calibration_t {
|
typedef struct Calibration_t {
|
||||||
float ax;
|
float ax;
|
||||||
float bx;
|
float bx;
|
||||||
float cx;
|
float cx;
|
||||||
float ay;
|
float ay;
|
||||||
float by;
|
float by;
|
||||||
float cy;
|
float cy;
|
||||||
} Calibration;
|
} Calibration;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -76,7 +76,57 @@ static struct MouseConfig_t {
|
||||||
GDisplay * display;
|
GDisplay * display;
|
||||||
} MouseConfig;
|
} 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
|
#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) {
|
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-15, pp->y, pp->x-2, pp->y, White);
|
||||||
gdispGDrawLine(MouseConfig.display, pp->x+2, pp->y, pp->x+15, 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);
|
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) {
|
static inline void _tsDo3PointCalibration(const MousePoint *cross, const MousePoint *points, GDisplay *g, Calibration *c) {
|
||||||
float dx, dx0, dx1, dx2, dy0, dy1, dy2;
|
float dx;
|
||||||
|
coord_t c0, c1, c2;
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
/* Compute all the required determinants */
|
/* Compute all the required determinants */
|
||||||
dx = ((float)(points[0].x - points[2].x)) * ((float)(points[1].y - points[2].y))
|
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));
|
- (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))
|
c->ax = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
|
||||||
- ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].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;
|
||||||
|
|
||||||
dx1 = ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].x - points[2].x))
|
#if GDISP_NEED_CONTROL
|
||||||
- ((float)(cross[0].x - cross[2].x)) * ((float)(points[1].x - points[2].x));
|
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
|
||||||
|
|
||||||
dx2 = cross[0].x * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y) -
|
c->ay = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
|
||||||
cross[1].x * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y) +
|
- (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
|
||||||
cross[2].x * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y);
|
c->by = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
|
||||||
|
- (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
|
||||||
dy0 = ((float)(cross[0].y - cross[2].y)) * ((float)(points[1].y - points[2].y))
|
c->cy = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
|
||||||
- ((float)(cross[1].y - cross[2].y)) * ((float)(points[0].y - points[2].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;
|
||||||
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));
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Now, calculate all the required coefficients */
|
|
||||||
c->ax = dx0 / dx;
|
|
||||||
c->bx = dx1 / dx;
|
|
||||||
c->cx = dx2 / dx;
|
|
||||||
|
|
||||||
c->ay = dy0 / dx;
|
|
||||||
c->by = dy1 / dx;
|
|
||||||
c->cy = dy2 / dx;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -166,56 +271,13 @@ static struct MouseConfig_t {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void get_calibrated_reading(MouseReading *pt) {
|
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);
|
get_raw_reading(pt);
|
||||||
|
|
||||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||||
_tsTransform(pt, &MouseConfig.caldata);
|
_tsTransform(pt, &MouseConfig.caldata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GINPUT_MOUSE_NEED_CALIBRATION || (GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION)
|
_tsOrientClip(pt, MouseConfig.display, !(MouseConfig.flags & FLG_CAL_RAW));
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MousePoll(void *param) {
|
static void MousePoll(void *param) {
|
||||||
|
@ -359,12 +421,7 @@ GSourceHandle ginputGetMouse(uint16_t instance) {
|
||||||
if ((MouseConfig.flags & FLG_CAL_FREE))
|
if ((MouseConfig.flags & FLG_CAL_FREE))
|
||||||
gfxFree((void *)pc);
|
gfxFree((void *)pc);
|
||||||
} else if (instance == 9999) {
|
} else if (instance == 9999) {
|
||||||
MouseConfig.caldata.ax = 1;
|
_tsSetIdentity(&MouseConfig.caldata);
|
||||||
MouseConfig.caldata.bx = 0;
|
|
||||||
MouseConfig.caldata.cx = 0;
|
|
||||||
MouseConfig.caldata.ay = 0;
|
|
||||||
MouseConfig.caldata.by = 1;
|
|
||||||
MouseConfig.caldata.cy = 0;
|
|
||||||
MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
|
MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
|
||||||
} else
|
} else
|
||||||
ginputCalibrateMouse(instance);
|
ginputCalibrateMouse(instance);
|
||||||
|
@ -461,10 +518,6 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
|
||||||
gtimerStop(&MouseTimer);
|
gtimerStop(&MouseTimer);
|
||||||
MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
|
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
|
#if GDISP_NEED_CLIP
|
||||||
gdispGSetClip(MouseConfig.display, 0, 0, width, height);
|
gdispGSetClip(MouseConfig.display, 0, 0, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
@ -511,7 +564,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply 3 point calibration algorithm */
|
/* Apply 3 point calibration algorithm */
|
||||||
_tsDo3PointCalibration(cross, points, &MouseConfig.caldata);
|
_tsDo3PointCalibration(cross, points, MouseConfig.display, &MouseConfig.caldata);
|
||||||
|
|
||||||
/* Verification of correctness of calibration (optional) :
|
/* Verification of correctness of calibration (optional) :
|
||||||
* See if the 4th point (Middle of the screen) coincides with the calibrated
|
* 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.x = points[3].x;
|
||||||
MouseConfig.t.y = points[3].y;
|
MouseConfig.t.y = points[3].y;
|
||||||
_tsTransform(&MouseConfig.t, &MouseConfig.caldata);
|
_tsTransform(&MouseConfig.t, &MouseConfig.caldata);
|
||||||
|
_tsOrientClip(&MouseConfig.t, MouseConfig.display, FALSE);
|
||||||
|
|
||||||
/* Calculate the delta */
|
/* Calculate the delta */
|
||||||
err = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +
|
err = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +
|
||||||
|
|
Loading…
Add table
Reference in a new issue