Take care of a few more compiler warnings.
[dolphin.git] / Source / Plugins / Plugin_Wiimote / Src / UDPWiimote.cpp
blobed5fb65818ae5bd4fae988bb57107f65e35e6dec
1 #include "UDPWiimote.h"
3 #ifdef _WIN32
5 #include <winsock2.h>
6 #include <ws2tcpip.h>
8 #define sock_t SOCKET
9 #define ERRNO WSAGetLastError()
10 #define EWOULDBLOCK WSAEWOULDBLOCK
11 #define BAD_SOCK INVALID_SOCKET
12 #define close(x) closesocket(x)
13 #define cleanup do {noinst--; if (noinst==0) WSACleanup();} while (0)
14 #define blockingoff(sock) ioctlsocket(sock, FIONBIO, &iMode)
15 #define dataz char*
16 #ifdef _MSC_VER
17 #pragma comment (lib, "Ws2_32.lib")
18 #endif
20 #else
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <netdb.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #define BAD_SOCK -1
33 #define ERRNO errno
34 #define cleanup noinst--
35 #define blockingoff(sock) fcntl(sock, F_SETFL, O_NONBLOCK)
36 #define dataz void*
37 #define sock_t int
39 #endif
41 #include "EmuMain.h"
42 #include <stdio.h>
43 #include <string.h>
45 struct UDPWiimote::_d
47 sock_t sockfd;
50 int UDPWiimote::noinst=0;
52 UDPWiimote::UDPWiimote(const char *port) : d(new _d) ,x(0),y(0),z(0),nunX(0),nunY(0),pointerX(-0.1),pointerY(-0.1),nunMask(0),mask(0)
54 #ifdef _WIN32
55 u_long iMode = 1;
56 #endif
57 struct addrinfo hints, *servinfo, *p;
58 int rv;
60 #ifdef _WIN32
61 if (noinst==0)
63 WORD sockVersion;
64 WSADATA wsaData;
65 sockVersion = MAKEWORD(2, 2);
66 WSAStartup(sockVersion, &wsaData);
68 #endif
70 noinst++;
72 memset(&hints, 0, sizeof hints);
73 hints.ai_family = AF_INET;
74 hints.ai_socktype = SOCK_DGRAM;
75 hints.ai_flags = AI_PASSIVE; // use my IP
77 if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
78 // fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
79 cleanup;
80 err=-1;
81 return;
84 // loop through all the results and bind to the first we can
85 for(p = servinfo; p != NULL; p = p->ai_next) {
86 if (((d->sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)),d->sockfd) == BAD_SOCK) {
87 continue;
90 if (bind(d->sockfd, p->ai_addr, p->ai_addrlen) == -1) {
91 close(d->sockfd);
92 continue;
95 break;
98 if (p == NULL) {
99 cleanup;
100 err=-2;
101 return;
104 freeaddrinfo(servinfo);
105 blockingoff(d->sockfd);
106 err=0;
107 return;
110 UDPWiimote::~UDPWiimote()
112 close(d->sockfd);
113 cleanup;
114 delete d;
117 int UDPWiimote::readPack(void * data, int *size)
119 int numbytes;
120 size_t addr_len;
121 struct sockaddr_storage their_addr;
122 addr_len = sizeof their_addr;
123 if ((numbytes = recvfrom(d->sockfd, (dataz)data, (*size) , 0,
124 (struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1) {
125 if (ERRNO==EWOULDBLOCK)
126 return -1;
127 return -2;
128 } else
129 (*size)=numbytes;
130 return 0;
133 #define ACCEL_FLAG (1<<0)
134 #define BUTT_FLAG (1<<1)
135 #define IR_FLAG (1<<2)
136 #define NUN_FLAG (1<<3)
138 void UDPWiimote::update()
140 u8 bf[64];
141 int size=60;
142 int res=0;
143 u8 time=0;
144 int nopack=0;
145 for (int i=0; (res=readPack(&bf,&size)),(i<100)&&(res!=-1); (res<-1)?i++:0)
147 if (res==0)
149 if (bf[0]==0xde)
151 if (bf[1]==0)
152 time=0;
153 if (bf[1]>=time) //packet timestamp. assures order is maintained
155 nopack++;
156 time=bf[1];
157 u32 *p=(u32*)(&bf[3]);
158 if (bf[2]&ACCEL_FLAG)
160 double ux,uy,uz;
161 ux=(double)((s32)ntohl(*p)); p++;
162 uy=(double)((s32)ntohl(*p)); p++;
163 uz=(double)((s32)ntohl(*p)); p++;
164 x=ux/1048576; //packet accel data
165 y=uy/1048576;
166 z=uz/1048576;
168 if (bf[2]&BUTT_FLAG)
170 mask=ntohl(*p); p++;
172 if (bf[2]&IR_FLAG)
174 pointerX=((double)((s32)ntohl(*p)))/1048576; p++;
175 pointerY=((double)((s32)ntohl(*p)))/1048576; p++;
177 if (bf[2]&NUN_FLAG)
179 nunMask=*((u8*)p); p=(u32*)(((u8*)p)+1);
180 nunX=((double)((s32)ntohl(*p)))/1048576; p++;
181 nunY=((double)((s32)ntohl(*p)))/1048576; p++;
186 if (res==-2)
188 ERROR_LOG(WIIMOTE,"UDPWii Packet error");
191 //NOTICE_LOG(WIIMOTE,"UDPWii update result:np:%d x:%f y:%f z:%f nx:%f ny:%f px:%f py:%f bmask:%x nmask:%x",
192 // nopack, x, y, z, nunX, nunY, pointerX, pointerY, mask, nunMask);
195 void UDPWiimote::getAccel(int &_x, int &_y, int &_z)
197 //NOTICE_LOG(WIIMOTE,"%lf %lf %lf",_x, _y, _z);
198 float xg = WiiMoteEmu::g_wm.cal_g.x;
199 float yg = WiiMoteEmu::g_wm.cal_g.y;
200 float zg = WiiMoteEmu::g_wm.cal_g.z;
201 _x = WiiMoteEmu::g_wm.cal_zero.x + (int)(xg * x);
202 _y = WiiMoteEmu::g_wm.cal_zero.y + (int)(yg * y);
203 _z = WiiMoteEmu::g_wm.cal_zero.z + (int)(zg * z);
206 u32 UDPWiimote::getButtons()
208 return mask;
211 void UDPWiimote::getIR(float &_x, float &_y)
213 _x=(float)pointerX;
214 _y=(float)pointerY;
217 void UDPWiimote::getNunchuck(float &_x, float &_y, u8 &_mask)
219 _x=(float)nunX;
220 _y=(float)nunY;
221 _mask=nunMask;