tagging release
[dasher.git] / Src / Tools / ToshTilt / toshtilt.cpp
blob5338f7f0151f9e714272dd5fe0983223d0d8bd71
1 // toshtilt.cpp
2 //
3 // Reads from the accelerometers in the Toshiba Portege m200 tablet PC,
4 // and emits UDP packets intended to driver Dasher's socket input.
5 //
6 // Seb Wills, November 2005. <saw27@mrao.cam.ac.uk>
7 // Hereby placed in the public domain.
8 //
9 // Many thanks to Larry O'Brien for reverse-engineering how to read from the
10 // accelerometers, documented at http://www.devx.com/TabletPC/Article/28483
12 // A Visual Studio 7 "solution" file is included with this file, but
13 // if you can't get it to load, the project setup was quite simple. I
14 // selected a Win32 Console application using the wizard. This file is
15 // the only one I modified. I also had to add ws2_32.lib to the linker
16 // dependencies (in the Project properties pages).
18 #include "../Common/Common.h"
20 #include "stdafx.h"
21 #include "windows.h"
22 #include "winsock.h"
23 #include "math.h"
25 int getTilt(int *x, int *y);
27 // global:
28 typedef INT (CALLBACK* LPFNDLLFUNC1)(INT*,INT*);
29 LPFNDLLFUNC1 lpfnGetImmediate; // Function pointer
32 int _tmain(int argc, _TCHAR* argv[])
36 HINSTANCE hDLL; // Handle to DLL
37 INT irawx, irawy;
39 // Set up UDP socket for writing to Dasher...
41 WORD wVersionRequested = MAKEWORD(1,1);
42 WSADATA wsaData;
43 int nRet;
44 unsigned short int nPort=20320;
45 SOCKET sock;
47 nRet = WSAStartup(wVersionRequested, &wsaData);
48 if(wsaData.wVersion != wVersionRequested) {
49 fprintf(stderr, "Wrong winsock version\n");
50 return(1);
53 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
54 if(sock == INVALID_SOCKET) {
55 perror("socket()");
56 return(1);
59 SOCKADDR_IN saRemote;
61 /* This is how you would do it if Dasher on a different machine:
62 LPHOSTENT lpHostEntry;
63 lpHostEntry = gethostbyname("localhost");
64 if(lpHostEntry == NULL) {
65 perror("gethostbyname()");
66 return(1);
70 saRemote.sin_family = AF_INET;
71 /* If you used gethostbyname section above:
72 //saRemote.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
74 //otherwise:
75 saRemote.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
76 saRemote.sin_port = htons(nPort);
79 // Explicitly link to the Toshiba DLL...
81 hDLL = LoadLibrary("C:\\Program Files\\Toshiba\\Acceleration Utilities\\TAcelMgr\\TAcelMgr.dll");
82 if (hDLL == NULL) {
83 printf("Failed to load Tosbiba Acceleration Utilities DLL, TAcelMgr.dll\n");
84 return -1;
86 lpfnGetImmediate = (LPFNDLLFUNC1)GetProcAddress(hDLL,
87 "GetImmediate");
88 if (!lpfnGetImmediate)
90 // handle the error
91 FreeLibrary(hDLL);
92 printf("Failed to get pointer to function in DLL\n");
93 return -2;
97 /***** CALIBRATE *******/
99 INT minx,maxx,miny,maxy,mindummy,maxdummy;
100 printf("Please tilt tablet LEFT...\n");
101 Sleep(2500);
102 getTilt(&minx,&mindummy);
103 printf("Please tilt tablet RIGHT...\n");
104 Sleep(1500);
105 getTilt(&maxx,&maxdummy);
106 bool rotated=false;
107 if(fabs(((double)maxx-(double)minx)) < fabs(((double)maxdummy-(double)mindummy))) {
108 printf("(ok, device is rotated!)\n");
109 minx=mindummy;
110 maxx=maxdummy;
111 rotated=true;
113 printf("Please tilt tablet UP...\n");
114 Sleep(1500);
115 getTilt(&mindummy,&miny);
116 printf("Please tilt table DOWN...\n");
117 Sleep(1500);
118 getTilt(&maxdummy,&maxy);
119 if(rotated) {
120 miny=mindummy;
121 maxy=maxdummy;
124 printf("\nThank you.\n x range %d to %d\n y range %d to %d\n\n", minx, maxx, miny, maxy);
126 printf("\nStandby...\n");
127 Sleep(2000);
129 double centrex = ((double)maxx+(double)minx)/2.0;
130 double centrey = ((double)maxy+(double)miny)/2.0;
131 double halfrangex = (((double)maxx-(double)minx))/2.0;
132 double halfrangey = (((double)maxy-(double)miny))/2.0;
134 char buffer[256];
135 while(1) {
136 // call the function
137 getTilt(&irawx, &irawy);
138 if(rotated) {
139 INT temp=irawy;
140 irawy=irawx;
141 irawx=temp;
143 //ix=irawx-3435921935; // these values seem to be for horizontal
144 //iy=irawy-3435921929;
145 double dx, dy; // "d" here means "double", not differentiation!
146 //dx=((double)irawx- ((double)minx + halfrangex))/halfrangex;
147 //dy=((double)irawy- ((double)miny + halfrangey))/halfrangey;
148 dx=((double)irawx- centrex)/halfrangex;
149 dy=((double)irawy- centrey)/halfrangey;
151 //printf("x=%lu -> %ld, y=%lu -> %ld\n", irawx, ix, irawy, iy);
152 printf("x=%d -> %lf, y=%d -> %lf\n", irawx, dx, irawy, dy);
153 // Send datagram to Dasher:
154 sprintf(buffer, "x %lf\ny %lf\n", dx, dy);
155 nRet = sendto(sock, buffer, strlen(buffer), 0, (LPSOCKADDR)&saRemote, sizeof(struct sockaddr));
156 if(nRet == SOCKET_ERROR) {
157 perror("sendto()");
158 WSAGetLastError();
160 Sleep(50);
163 return 0;
166 int getTilt(INT *x, INT *y) {
167 int res;
168 res=lpfnGetImmediate(x,y);
169 // only lower 16 bits seem to be meaningful
170 // (the upper two bytes did strange things for me: consistantly 0xcccc in the Debug build, but flipping around between various things in Release build)
171 *x &= 0xffff;
172 *y &= 0xffff;
173 return res;