1 #include "UDPWiimote.h"
8 #define ERRNO WSAGetLastError()
9 #define EWOULDBLOCK WSAEWOULDBLOCK
10 #define BAD_SOCK INVALID_SOCKET
11 #define close(x) closesocket(x)
12 #define cleanup do {noinst--; if (noinst==0) WSACleanup();} while (0)
13 #define blockingoff(sock) ioctlsocket(sock, FIONBIO, &iMode)
16 #pragma comment (lib, "Ws2_32.lib")
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
33 #define cleanup noinst--
34 #define blockingoff(sock) fcntl(sock, F_SETFL, O_NONBLOCK)
47 Common::Thread
* thread
;
48 std::list
<sock_t
> sockfds
;
49 Common::CriticalSection termLock
,mutex
;
53 int UDPWiimote::noinst
=0;
55 void _UDPWiiThread(void* arg
)
57 ((UDPWiimote
*)arg
)->mainThread();
58 //NOTICE_LOG(WIIMOTE,"UDPWii thread stopped");
61 THREAD_RETURN
UDPWiiThread(void* arg
)
67 UDPWiimote::UDPWiimote(const char *_port
) :
69 d(new _d
) ,x(0),y(0),z(0),nunX(0),nunY(0),
70 pointerX(-0.1),pointerY(-0.1),nunMask(0),mask(0),time(0)
75 struct addrinfo hints
, *servinfo
, *p
;
84 sockVersion
= MAKEWORD(2, 2);
85 WSAStartup(sockVersion
, &wsaData
);
90 //PanicAlert("UDPWii instantiated");
92 memset(&hints
, 0, sizeof hints
);
93 hints
.ai_family
= AF_INET
;
94 hints
.ai_socktype
= SOCK_DGRAM
;
95 hints
.ai_flags
= AI_PASSIVE
; // use my IP
97 if ((rv
= getaddrinfo(NULL
, _port
, &hints
, &servinfo
)) != 0) {
103 // loop through all the results and bind to everything we can
104 for(p
= servinfo
; p
!= NULL
; p
= p
->ai_next
) {
106 if ((sock
= socket(p
->ai_family
, p
->ai_socktype
, p
->ai_protocol
)) == BAD_SOCK
) {
110 if (bind(sock
, p
->ai_addr
, p
->ai_addrlen
) == -1) {
116 //NOTICE_LOG(WIIMOTE,"UDPWii new listening sock");
117 d
->sockfds
.push_back(sock
);
120 if (d
->sockfds
.empty()) {
126 freeaddrinfo(servinfo
);
129 // NOTICE_LOG(WIIMOTE,"UDPWii thread starting");
131 d
->thread
= new Common::Thread(UDPWiiThread
,this);
136 void UDPWiimote::mainThread()
139 // NOTICE_LOG(WIIMOTE,"UDPWii thread started");
141 struct timeval timeout
;
143 timeout
.tv_usec
=500000;
144 //Common::Thread * thisthr= d->thread;
149 for (std::list
<sock_t
>::iterator i
=d
->sockfds
.begin(); i
!=d
->sockfds
.end(); i
++)
159 int rt
=select(maxfd
,&fds
,NULL
,NULL
,&timeout
);
165 for (std::list
<sock_t
>::iterator i
=d
->sockfds
.begin(); i
!=d
->sockfds
.end(); i
++)
166 if (FD_ISSET(*i
,&fds
))
172 struct sockaddr_storage their_addr
;
173 addr_len
= sizeof their_addr
;
174 if ((size
= recvfrom(fd
, (dataz
)bf
, size
, 0,(struct sockaddr
*)&their_addr
, (socklen_t
*)&addr_len
)) == -1)
176 ERROR_LOG(WIIMOTE
,"UDPWii Packet error");
181 if (pharsePacket(bf
,size
)==0)
183 //NOTICE_LOG(WIIMOTE,"UDPWII New pack");
185 //NOTICE_LOG(WIIMOTE,"UDPWII Wrong pack format... ignoring");
193 } while (!(d
->exit
));
198 UDPWiimote::~UDPWiimote()
201 d
->thread
->WaitForDeath();
204 for (std::list
<sock_t
>::iterator i
=d
->sockfds
.begin(); i
!=d
->sockfds
.end(); i
++)
208 //PanicAlert("UDPWii destructed");
211 #define ACCEL_FLAG (1<<0)
212 #define BUTT_FLAG (1<<1)
213 #define IR_FLAG (1<<2)
214 #define NUN_FLAG (1<<3)
216 int UDPWiimote::pharsePacket(u8
* bf
, size_t size
)
218 if (size
<3) return -1;
226 u32
*p
=(u32
*)(&bf
[3]);
227 if (bf
[2]&ACCEL_FLAG
)
229 if ((size
-(((u8
*)p
)-bf
))<12) return -1;
231 ux
=(double)((s32
)ntohl(*p
)); p
++;
232 uy
=(double)((s32
)ntohl(*p
)); p
++;
233 uz
=(double)((s32
)ntohl(*p
)); p
++;
234 x
=ux
/1048576; //packet accel data
240 if ((size
-(((u8
*)p
)-bf
))<4) return -1;
245 if ((size
-(((u8
*)p
)-bf
))<8) return -1;
246 pointerX
=((double)((s32
)ntohl(*p
)))/1048576; p
++;
247 pointerY
=((double)((s32
)ntohl(*p
)))/1048576; p
++;
251 if ((size
-(((u8
*)p
)-bf
))<9) return -1;
252 nunMask
=*((u8
*)p
); p
=(u32
*)(((u8
*)p
)+1);
253 nunX
=((double)((s32
)ntohl(*p
)))/1048576; p
++;
254 nunY
=((double)((s32
)ntohl(*p
)))/1048576; p
++;
260 void UDPWiimote::broadcastPresence()
262 // NOTICE_LOG(WIIMOTE,"UDPWii broadcasting presence");
265 void UDPWiimote::getAccel(float &_x
, float &_y
, float &_z
)
272 //NOTICE_LOG(WIIMOTE,"%lf %lf %lf",_x, _y, _z);
275 u32
UDPWiimote::getButtons()
284 void UDPWiimote::getIR(float &_x
, float &_y
)
292 void UDPWiimote::getNunchuck(float &_x
, float &_y
, u8
&_mask
)
301 const char * UDPWiimote::getPort()