URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/services/gfx/mw/v2_0/src/contrib/GPL
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/tpcal/transform.h
0,0 → 1,37
/* |
* transform.h |
* Copyright (C) 1999 Bradley D. LaRonde <brad@ltc.com> |
* |
* This program is free software; you may redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
|
typedef struct |
{ |
MWPOINT screen, device; |
} CALIBRATION_PAIR; |
|
typedef struct |
{ |
CALIBRATION_PAIR center; |
CALIBRATION_PAIR ul; |
CALIBRATION_PAIR ur; |
CALIBRATION_PAIR lr; |
CALIBRATION_PAIR ll; |
} CALIBRATION_PAIRS; |
|
int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc); |
int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc); |
int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc); |
int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc); |
/tpcal/tpcal.c
0,0 → 1,363
/* |
* Touch-panel calibration program |
* Copyright (C) 1999 Bradley D. LaRonde <brad@ltc.com> |
* |
* This program is free software; you may redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
#include <stdio.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <time.h> |
#include <string.h> |
#include "windows.h" |
#include "mou_tp.h" |
#include "transform.h" |
|
static int xext, yext; |
static CALIBRATION_PAIRS cps; |
static CALIBRATION_PAIR* pcp = 0; |
|
void DrawAbout(HDC hdc, RECT r) |
{ |
const int ver_major = 0; |
const int ver_minor = 5; |
const char app_name[] = "Touch Panel Calibrator"; |
const char title[] = "%s, version %d.%d"; |
const char copyright[] = "(C) 1999 Bradley D. LaRonde <brad@ltc.com>"; |
const char warranty[] = "ABSOLUTELY NO WARRANTY"; |
const char license1[] = "This is free software, and you are welcome to"; |
const char license2[] = "redistribute it under certain conditions."; |
|
const int leading = 15; |
|
char s[1024]; |
|
sprintf(s, title, app_name, ver_major, ver_minor); |
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); |
DrawText(hdc, s, -1, &r, DT_CENTER); |
|
r.top += leading; |
DrawText(hdc, copyright, -1, &r, DT_CENTER); |
|
r.top += leading; |
DrawText(hdc, warranty, -1, &r, DT_CENTER); |
|
r.top += leading; |
DrawText(hdc, license1, -1, &r, DT_CENTER); |
r.top += leading; |
DrawText(hdc, license2, -1, &r, DT_CENTER); |
} |
|
void DrawDone(HDC hdc, RECT r) |
{ |
const char donemsg[] = "Calibration is done!"; |
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); |
DrawText(hdc, donemsg, -1, &r, DT_CENTER); |
} |
|
|
void DrawTarget(HDC hdc, POINT p) |
{ |
const int scale = 9; |
const int center = 3; |
|
// I never knew that Windows GDI always leaves off |
// the last point in a line, and the right and bottom side of a rectangle. |
// Why would they make use always figure +1? It isn't always obvious where |
// +1 is (i.e. a line going at a 10 degree angle). Blech. |
// I can only hope that there is some overwhelmingly compelling reason why. |
|
Rectangle(hdc, p.x - center, p.y - center, p.x + center + 1, p.y + center + 1); |
|
// scale |
MoveToEx(hdc, p.x - scale, p.y, NULL); |
LineTo(hdc, p.x + scale + 1, p.y); |
|
MoveToEx(hdc, p.x, p.y - scale, NULL); |
LineTo(hdc, p.x, p.y + scale + 1); |
} |
|
void DrawLabelAlign(HDC hdc, POINT p, LPCSTR psz, int align) |
{ |
RECT r; |
const int w = 180; |
const int h = 14; |
const int m = 15; |
|
switch(align) |
{ |
case 1: |
// right |
r.left = p.x + m; |
r.right = p.x + w + m; |
r.top = p.y - (h/2); |
r.bottom = p.y + (h/2); |
break; |
|
case 2: |
// left |
r.left = p.x - (w + m); |
r.right = p.x - m; |
r.top = p.y - (h/2); |
r.bottom = p.y + (h/2); |
break; |
|
case 3: |
// below |
r.left = p.x - (w/2); |
r.right = p.x + (w/2); |
r.top = p.y + m; |
r.bottom = p.y + m + h; |
break; |
|
default: |
// at |
r.left = p.x; |
r.right = p.x + w; |
r.top = p.y; |
r.bottom = p.y + h; |
break; |
} |
|
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); |
DrawText(hdc, psz, -1, &r, DT_LEFT); |
} |
|
void DrawLabel(HDC hdc, POINT p, LPCSTR psz) |
{ |
if ( p.x < (xext * 1 / 4) ) |
return DrawLabelAlign(hdc, p, psz, 1); |
|
if ( p.x > (xext * 3 / 4) ) |
return DrawLabelAlign(hdc, p, psz, 2); |
|
return DrawLabelAlign(hdc, p, psz, 3); |
} |
|
POINT GetTarget(int n) |
{ |
const int inset = 10; |
POINT p; |
|
switch (n) |
{ |
case 0: |
p.x = xext / 2; p.y = yext / 2; |
pcp = &cps.center; |
break; |
|
case 1: |
p.x = inset; p.y = inset; |
pcp = &cps.ul; |
break; |
|
case 2: |
p.x = xext - inset; p.y = inset; |
pcp = &cps.ur; |
break; |
|
case 3: |
p.x = xext - inset; p.y = yext - inset; |
pcp = &cps.lr; |
break; |
|
case 4: |
p.x = inset; p.y = yext - inset; |
pcp = &cps.ll; |
break; |
|
default: |
// return a random target |
p.x = random() / (RAND_MAX / xext); |
p.y = random() / (RAND_MAX / yext); |
pcp = 0; |
break; |
} |
|
return p; |
} |
|
static int total_targets = 5; |
static int current_target = 0; |
static POINT current_target_location; |
|
void DoPaint(HDC hdc) |
{ |
const char szInstructions[] = "Please touch the center of the target."; |
|
POINT p; |
int i, n; |
int old_rop; |
POINT last = current_target_location; |
HPEN hOldPen; |
|
if (current_target == total_targets) { |
RECT r = {10, yext/2, xext - 10, yext/2 + 40}; |
DrawDone(hdc, r); |
return; |
} |
|
if (current_target == 0) |
{ |
RECT r = {10, yext - 85, xext - 10, yext - 10}; |
DrawAbout(hdc, r); |
} |
|
current_target_location = GetTarget(current_target); |
|
old_rop = SetROP2(hdc, R2_XORPEN); |
hOldPen = SelectObject(hdc, GetStockObject(WHITE_PEN)); |
|
n = 20; |
for (i=0; i < n; i++) |
{ |
p.x = last.x + ((current_target_location.x - last.x) * i / n); |
p.y = last.y + ((current_target_location.y - last.y) * i / n); |
DrawTarget(hdc, p); |
Sleep(60); |
DrawTarget(hdc, p); |
} |
|
// final position |
SetROP2(hdc, R2_COPYPEN); |
SelectObject(hdc, GetStockObject(BLACK_PEN)); |
|
DrawTarget(hdc, current_target_location); |
DrawLabel(hdc, current_target_location, szInstructions); |
|
// put things back |
SetROP2(hdc, old_rop); |
SelectObject(hdc, hOldPen); |
} |
|
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) |
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) |
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) |
{ |
PAINTSTRUCT ps; |
HDC hdc; |
|
switch(msg) { |
case WM_PAINT: |
hdc = BeginPaint(hwnd, &ps); |
DoPaint(hdc); |
EndPaint(hwnd, &ps); |
break; |
|
case WM_NCHITTEST: |
return HTCLIENT; |
|
case WM_LBUTTONUP: |
if ( pcp != 0 ) |
{ |
pcp->screen.x = current_target_location.x * TRANSFORMATION_UNITS_PER_PIXEL; |
pcp->screen.y = current_target_location.y * TRANSFORMATION_UNITS_PER_PIXEL; |
pcp->device.x = GET_X_LPARAM(lp); |
pcp->device.y = GET_Y_LPARAM(lp); |
} |
|
if ( ++current_target == total_targets ) |
{ |
TRANSFORMATION_COEFFICIENTS tc; |
#if 0 |
CalcTransformationCoefficientsSimple(&cps, &tc); |
printf("%d %d %d %d %d %d %d\n", |
tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s); |
CalcTransformationCoefficientsBetter(&cps, &tc); |
printf("%d %d %d %d %d %d %d\n", |
tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s); |
CalcTransformationCoefficientsEvenBetter(&cps, &tc); |
printf("%d %d %d %d %d %d %d\n", |
tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s); |
#endif |
CalcTransformationCoefficientsBest(&cps, &tc); |
printf("%d %d %d %d %d %d %d\n", |
tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s); |
InvalidateRect(hwnd, NULL, TRUE); |
UpdateWindow(hwnd); |
PostQuitMessage(0); |
break; |
} |
InvalidateRect(hwnd, NULL, TRUE); |
UpdateWindow(hwnd); |
break; |
|
default: |
return DefWindowProc(hwnd, msg, wp, lp); |
} |
|
return 0; |
} |
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) |
{ |
WNDCLASS wc; |
RECT r; |
HWND hwnd; |
MSG msg; |
MWCOORD big; |
|
srandom(time(NULL)); |
|
/* WndButtonRegister(NULL); */ |
|
wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW; |
wc.lpfnWndProc = (WNDPROC)WndProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = 0; |
wc.hIcon = 0; |
wc.hCursor = 0; |
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName = "tpcal"; |
RegisterClass(&wc); |
|
GetWindowRect(GetDesktopWindow(), &r); |
xext = r.right; |
yext = r.bottom; |
|
hwnd = CreateWindowEx(0L, "tpcal", "Touch Panel Calibration", |
WS_VISIBLE, 0, 0, xext, yext, |
NULL, (HMENU)1, NULL, NULL); |
|
// Don't restrict mouse much in order to handle uncalibrated points. |
big = 1000000; |
GdRestrictMouse(-big, -big, big, big); |
|
// We want all mouse events - even ones outside our window. |
SetCapture(hwnd); |
|
while(GetMessage(&msg, NULL, 0, 0)) { |
TranslateMessage(&msg); |
DispatchMessage(&msg); |
} |
|
return 0; |
} |
|
int enable_pointing_coordinate_transform; |
|
int MwUserInit(int ac, char** av) |
{ |
enable_pointing_coordinate_transform = 0; |
|
if ( ac > 1 ) |
total_targets = atol(av[1]); |
|
return 0; |
} |
|
/tpcal/VERSION
0,0 → 1,363
0.5 |
/tpcal/transform.c
0,0 → 1,295
/* |
* transform.c |
* Calculate coefficients for tranformation equation |
* Copyright (C) 1999 Bradley D. LaRonde <brad@ltc.com> |
* |
* This program is free software; you may redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
#include "windows.h" |
#include "mou_tp.h" |
#include "transform.h" |
|
int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc) |
{ |
/* |
* This is my simple way of calculating some of the coefficients - |
* enough to do a simple scale and translate. |
* It ignores any dependencies between axiis (rotation and/or skew). |
*/ |
|
int min_screen_x = pcp->ul.screen.x; |
int min_screen_y = pcp->ul.screen.y; |
int max_screen_x = pcp->lr.screen.x; |
int max_screen_y = pcp->lr.screen.y; |
|
int min_device_x = pcp->ul.device.x; |
int min_device_y = pcp->ul.device.y; |
int max_device_x = pcp->lr.device.x; |
int max_device_y = pcp->lr.device.y; |
|
ptc->s = (1 << 16); |
ptc->a = ptc->s * (min_screen_x - max_screen_x) / (min_device_x - max_device_x); |
ptc->b = 0; |
ptc->c = (ptc->a * -min_device_x) + (ptc->s * min_screen_x); |
ptc->d = 0; |
ptc->e = ptc->s * (min_screen_y - max_screen_y) / (min_device_y - max_device_y); |
ptc->f = (ptc->e * -min_device_y) + (ptc->s * min_screen_y); |
|
return 0; |
} |
|
int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc) |
{ |
/* |
* Janus (the man) <janus@place.org> came up with a much better way |
* to figure the coefficients. His original algorithm was written in MOO. |
* Jay Carlson <> did the translation to C. |
* This way takes into account inter-axis dependency like rotation and skew. |
*/ |
|
double vector[3][2] = |
{ |
{pcp->ul.screen.x, pcp->ul.screen.y}, |
{pcp->ur.screen.x, pcp->ur.screen.y}, |
{pcp->lr.screen.x, pcp->lr.screen.y} |
}; |
|
double matrix[3][3] = |
{ |
{pcp->ul.device.x, pcp->ul.device.y, 1.0}, |
{pcp->ur.device.x, pcp->ur.device.y, 1.0}, |
{pcp->lr.device.x, pcp->lr.device.y, 1.0} |
}; |
|
int i, j, r, k; |
double p, q; |
|
for (i = 0; i < 3; i++) { |
p = matrix[i][i]; |
|
for (j = 0; j < 3; j++) { |
matrix[i][j] = matrix[i][j] / p; |
} |
|
for (j = 0; j < 2; j++) { |
vector[i][j] = vector[i][j] / p; |
} |
|
for (r = 0; r < 3; r++) { |
if (r != i) { |
q = matrix[r][i]; |
|
matrix[r][i] = 0.0; |
|
for (k = i + 1; k < 3; k++) { |
matrix[r][k] = matrix[r][k] - (q * matrix[i][k]); |
} |
|
for (k = 0; k < 2; k++) { |
vector[r][k] = vector[r][k] - (q * vector[i][k]); |
} |
} |
} |
} |
|
ptc->s = 1 << 16; |
ptc->a = vector[0][0] * ptc->s; |
ptc->b = vector[1][0] * ptc->s; |
ptc->c = vector[2][0] * ptc->s; |
ptc->d = vector[0][1] * ptc->s; |
ptc->e = vector[1][1] * ptc->s; |
ptc->f = vector[2][1] * ptc->s; |
|
return 0; |
} |
|
int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc) |
{ |
/* |
* Mike Klar <> added the an xy term to correct for trapezoidial distortion. |
*/ |
|
double vector[4][2] = |
{ |
{pcp->ul.screen.x, pcp->ul.screen.y}, |
{pcp->ur.screen.x, pcp->ur.screen.y}, |
{pcp->lr.screen.x, pcp->lr.screen.y}, |
{pcp->ll.screen.x, pcp->ll.screen.y} |
}; |
|
double matrix[4][4] = |
{ |
{pcp->ul.device.x, pcp->ul.device.x * pcp->ul.device.y, pcp->ul.device.y, 1.0}, |
{pcp->ur.device.x, pcp->ur.device.x * pcp->ur.device.y, pcp->ur.device.y, 1.0}, |
{pcp->lr.device.x, pcp->lr.device.x * pcp->lr.device.y, pcp->lr.device.y, 1.0}, |
{pcp->ll.device.x, pcp->ll.device.x * pcp->ll.device.y, pcp->ll.device.y, 1.0} |
}; |
|
int i, j, r, k; |
double p, q; |
|
for (i = 0; i < 4; i++) { |
p = matrix[i][i]; |
|
for (j = 0; j < 4; j++) { |
matrix[i][j] = matrix[i][j] / p; |
} |
|
for (j = 0; j < 2; j++) { |
vector[i][j] = vector[i][j] / p; |
} |
|
for (r = 0; r < 4; r++) { |
if (r != i) { |
q = matrix[r][i]; |
|
matrix[r][i] = 0.0; |
|
for (k = i + 1; k < 4; k++) { |
matrix[r][k] = matrix[r][k] - (q * matrix[i][k]); |
} |
|
for (k = 0; k < 2; k++) { |
vector[r][k] = vector[r][k] - (q * vector[i][k]); |
} |
} |
} |
} |
|
/* I just drop the xy coefficient since it is so small. */ |
ptc->s = 1 << 16; |
ptc->a = vector[0][0] * ptc->s; |
ptc->b = vector[2][0] * ptc->s; |
ptc->c = vector[3][0] * ptc->s; |
ptc->d = vector[0][1] * ptc->s; |
ptc->e = vector[2][1] * ptc->s; |
ptc->f = vector[3][1] * ptc->s; |
|
return 0; |
} |
|
int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc) |
{ |
/* |
* Mike Klar <> came up with a best-fit solution that works best. |
*/ |
|
const int first_point = 0; |
const int last_point = 4; |
int i; |
|
double Sx=0, Sy=0, Sxy=0, Sx2=0, Sy2=0, Sm=0, Sn=0, Smx=0, Smy=0, Snx=0, Sny=0, S=0; |
double t1, t2, t3, t4, t5, t6, q; |
|
/* cast the struct to an array - hacky but ok */ |
CALIBRATION_PAIR *cp = (CALIBRATION_PAIR*)pcp; |
|
/* |
* Do a best-fit calculation for as many points as we want, as |
* opposed to an exact fit, which can only be done against 3 points. |
* |
* The following calculates various sumnations of the sample data |
* coordinates. For purposes of naming convention, x and y |
* refer to device coordinates, m and n refer to screen |
* coordinates, S means sumnation. x2 and y2 are x squared and |
* y squared, S by itself is just a count of points (= sumnation |
* of 1). |
*/ |
|
for (i = first_point; i < last_point + 1; i++) { |
Sx += cp[i].device.x; |
Sy += cp[i].device.y; |
Sxy += cp[i].device.x * cp[i].device.y; |
Sx2 += cp[i].device.x * cp[i].device.x; |
Sy2 += cp[i].device.y * cp[i].device.y; |
Sm += cp[i].screen.x; |
Sn += cp[i].screen.y; |
Smx += cp[i].screen.x * cp[i].device.x; |
Smy += cp[i].screen.x * cp[i].device.y; |
Snx += cp[i].screen.y * cp[i].device.x; |
Sny += cp[i].screen.y * cp[i].device.y; |
S += 1; |
} |
|
#if 0 |
printf("%f, %f, %f, %f, " |
"%f, %f, %f, %f, " |
"%f, %f, %f, %f\n", |
Sx, Sy, Sxy, Sx2, Sy2, Sm, Sn, Smx, Smy, Snx, Sny, S); |
#endif |
|
/* |
* Next we solve the simultaneous equations (these equations minimize |
* the sum of the square of the m and n error): |
* |
* | Sx2 Sxy Sx | | a d | | Smx Snx | |
* | Sxy Sy2 Sy | * | b e | = | Smy Sny | |
* | Sx Sy S | | c f | | Sm Sn | |
* |
* We could do the matrix solution in code, but that leads to several |
* divide by 0 conditions for cases where the data is truly solvable |
* (becuase those terms cancel out of the final solution), so we just |
* give the final solution instread. t1 through t6 and q are just |
* convenience variables for terms that are used repeatedly - we could |
* calculate each of the coefficients directly at this point with a |
* nasty long equation, but that would be extremly inefficient. |
*/ |
|
t1 = Sxy * Sy - Sx * Sy2; |
t2 = Sxy * Sx - Sx2 * Sy; |
t3 = Sx2 * Sy2 - Sxy * Sxy; |
t4 = Sy2 * S - Sy * Sy; |
t5 = Sx * Sy - Sxy * S; |
t6 = Sx2 * S - Sx * Sx; |
|
q = t1 * Sx + t2 * Sy + t3 * S; |
|
/* |
* If q = 0, then the data is unsolvable. This should only happen |
* when there are not enough unique data points (less than 3 points |
* will give infinite solutions), or at least one of the |
* coefficients is infinite (which would indicate that the same |
* device point represents an infinite area of the screen, probably |
* as a result of the same device data point given for 2 different |
* screen points). The first condition should never happen, since |
* we're always feeding in at least 3 unique screen points. The |
* second condition would probably indicate bad user input or the |
* touchpanel device returning bad data. |
*/ |
|
if (q == 0) |
return -1; |
|
ptc->s = 1 << 16; |
ptc->a = ((t4 * Smx + t5 * Smy + t1 * Sm) / q + 0.5/65536) * ptc->s; |
ptc->b = ((t5 * Smx + t6 * Smy + t2 * Sm) / q + 0.5/65536) * ptc->s; |
ptc->c = ((t1 * Smx + t2 * Smy + t3 * Sm) / q + 0.5/65536) * ptc->s; |
ptc->d = ((t4 * Snx + t5 * Sny + t1 * Sn) / q + 0.5/65536) * ptc->s; |
ptc->e = ((t5 * Snx + t6 * Sny + t2 * Sn) / q + 0.5/65536) * ptc->s; |
ptc->f = ((t1 * Snx + t2 * Sny + t3 * Sn) / q + 0.5/65536) * ptc->s; |
|
/* |
* Finally, we check for overflow on the fp to integer conversion, |
* which would also probably indicate bad data. |
*/ |
|
if ( (ptc->a == 0x80000000) || (ptc->b == 0x80000000) || |
(ptc->c == 0x80000000) || (ptc->d == 0x80000000) || |
(ptc->e == 0x80000000) || (ptc->f == 0x80000000) ) |
return -1; |
|
return 0; |
} |
|
/tpcal/Makefile
0,0 → 1,13
#CC = mipsel-linux-gcc -msoft-float -s |
CC = gcc |
CFLAGS = -Wall -I../../../include -I../../../drivers -L../../../lib |
LIBS = -lmwin -lmwinlib -lmwengine -lmwdrivers -lmwfonts |
OBJECTS = tpcal.o transform.o |
|
all: tpcal |
|
tpcal: $(OBJECTS) |
$(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o tpcal |
|
clean: |
rm -f *.o tpcal |