UDPWii: Broadcasting it's presence on IPv4 to 255.255.255.255 once every 1.5 seconds. 3-arg Set()-s only worked on strings and doubles :P . Added int and bool variants.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5916 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
a2b1f829cb
commit
9074df896a
|
@ -119,6 +119,22 @@ void IniFile::Section::Set(const char* key, const float newValue, const float de
|
||||||
Delete(key);
|
Delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IniFile::Section::Set(const char* key, int newValue, int defaultValue)
|
||||||
|
{
|
||||||
|
if (newValue != defaultValue)
|
||||||
|
Set(key, newValue);
|
||||||
|
else
|
||||||
|
Delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue)
|
||||||
|
{
|
||||||
|
if (newValue != defaultValue)
|
||||||
|
Set(key, newValue);
|
||||||
|
else
|
||||||
|
Delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
void IniFile::Section::Set(const char* key, const std::vector<std::string>& newValues)
|
void IniFile::Section::Set(const char* key, const std::vector<std::string>& newValues)
|
||||||
{
|
{
|
||||||
std::string temp;
|
std::string temp;
|
||||||
|
|
|
@ -56,9 +56,13 @@ public:
|
||||||
void Set(const char* key, double newValue) {
|
void Set(const char* key, double newValue) {
|
||||||
Set(key, StringFromFormat("%f", newValue).c_str());
|
Set(key, StringFromFormat("%f", newValue).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Set(const char* key, int newValue, int defaultValue);
|
||||||
void Set(const char* key, int newValue) {
|
void Set(const char* key, int newValue) {
|
||||||
Set(key, StringFromInt(newValue).c_str());
|
Set(key, StringFromInt(newValue).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Set(const char* key, bool newValue, bool defaultValue);
|
||||||
void Set(const char* key, bool newValue) {
|
void Set(const char* key, bool newValue) {
|
||||||
Set(key, StringFromBool(newValue).c_str());
|
Set(key, StringFromBool(newValue).c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -38,7 +37,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
#include "Timer.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
@ -46,8 +47,9 @@ struct UDPWiimote::_d
|
||||||
{
|
{
|
||||||
Common::Thread * thread;
|
Common::Thread * thread;
|
||||||
std::list<sock_t> sockfds;
|
std::list<sock_t> sockfds;
|
||||||
Common::CriticalSection termLock,mutex;
|
Common::CriticalSection termLock,mutex,nameMutex;
|
||||||
volatile bool exit;
|
volatile bool exit;
|
||||||
|
sock_t bipv4_fd,bipv6_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
int UDPWiimote::noinst=0;
|
int UDPWiimote::noinst=0;
|
||||||
|
@ -55,7 +57,6 @@ int UDPWiimote::noinst=0;
|
||||||
void _UDPWiiThread(void* arg)
|
void _UDPWiiThread(void* arg)
|
||||||
{
|
{
|
||||||
((UDPWiimote*)arg)->mainThread();
|
((UDPWiimote*)arg)->mainThread();
|
||||||
//NOTICE_LOG(WIIMOTE,"UDPWii thread stopped");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN UDPWiiThread(void* arg)
|
THREAD_RETURN UDPWiiThread(void* arg)
|
||||||
|
@ -64,11 +65,20 @@ THREAD_RETURN UDPWiiThread(void* arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPWiimote::UDPWiimote(const char *_port) :
|
UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
|
||||||
port(_port),
|
port(_port), displayName(name),
|
||||||
d(new _d) ,x(0),y(0),z(0),naX(0),naY(0),naZ(0),nunX(0),nunY(0),
|
d(new _d) ,x(0),y(0),z(0),naX(0),naY(0),naZ(0),nunX(0),nunY(0),
|
||||||
pointerX(-0.1),pointerY(-0.1),nunMask(0),mask(0),time(0)
|
pointerX(-0.1),pointerY(-0.1),nunMask(0),mask(0),index(_index), int_port(atoi(_port))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static bool sranded=false;
|
||||||
|
if (!sranded)
|
||||||
|
{
|
||||||
|
srand(time(0));
|
||||||
|
sranded=true;
|
||||||
|
}
|
||||||
|
bcastMagic=rand() & 0xFFFF;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
u_long iMode = 1;
|
u_long iMode = 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,13 +97,18 @@ UDPWiimote::UDPWiimote(const char *_port) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
noinst++;
|
noinst++;
|
||||||
//PanicAlert("UDPWii instantiated");
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof hints);
|
memset(&hints, 0, sizeof hints);
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
hints.ai_flags = AI_PASSIVE; // use my IP
|
hints.ai_flags = AI_PASSIVE; // use my IP
|
||||||
|
|
||||||
|
if (!int_port){
|
||||||
|
cleanup;
|
||||||
|
err=-1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((rv = getaddrinfo(NULL, _port, &hints, &servinfo)) != 0) {
|
if ((rv = getaddrinfo(NULL, _port, &hints, &servinfo)) != 0) {
|
||||||
cleanup;
|
cleanup;
|
||||||
err=-1;
|
err=-1;
|
||||||
|
@ -106,14 +121,10 @@ UDPWiimote::UDPWiimote(const char *_port) :
|
||||||
if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == BAD_SOCK) {
|
if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == BAD_SOCK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(sock, p->ai_addr, p->ai_addrlen) == -1) {
|
if (bind(sock, p->ai_addr, p->ai_addrlen) == -1) {
|
||||||
close(sock);
|
close(sock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//NOTICE_LOG(WIIMOTE,"UDPWii new listening sock");
|
|
||||||
d->sockfds.push_back(sock);
|
d->sockfds.push_back(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +137,8 @@ UDPWiimote::UDPWiimote(const char *_port) :
|
||||||
freeaddrinfo(servinfo);
|
freeaddrinfo(servinfo);
|
||||||
err=0;
|
err=0;
|
||||||
d->exit=false;
|
d->exit=false;
|
||||||
// NOTICE_LOG(WIIMOTE,"UDPWii thread starting");
|
initBroadcastIPv4();
|
||||||
|
initBroadcastIPv6();
|
||||||
d->termLock.Enter();
|
d->termLock.Enter();
|
||||||
d->thread = new Common::Thread(UDPWiiThread,this);
|
d->thread = new Common::Thread(UDPWiiThread,this);
|
||||||
d->termLock.Leave();
|
d->termLock.Leave();
|
||||||
|
@ -136,12 +148,12 @@ UDPWiimote::UDPWiimote(const char *_port) :
|
||||||
void UDPWiimote::mainThread()
|
void UDPWiimote::mainThread()
|
||||||
{
|
{
|
||||||
d->termLock.Enter();
|
d->termLock.Enter();
|
||||||
// NOTICE_LOG(WIIMOTE,"UDPWii thread started");
|
Common::Timer time;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec=1;
|
timeout.tv_sec=0;
|
||||||
timeout.tv_usec=500000;
|
timeout.tv_usec=0;
|
||||||
//Common::Thread * thisthr= d->thread;
|
time.Update();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int maxfd=0;
|
int maxfd=0;
|
||||||
|
@ -154,12 +166,28 @@ void UDPWiimote::mainThread()
|
||||||
maxfd=(*i)+1;
|
maxfd=(*i)+1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
d->termLock.Leave();
|
|
||||||
|
u64 tleft=timeout.tv_sec*1000+timeout.tv_usec/1000;
|
||||||
|
u64 telapsed=time.GetTimeDifference();
|
||||||
|
time.Update();
|
||||||
|
if (tleft<=telapsed)
|
||||||
|
{
|
||||||
|
timeout.tv_sec=1;
|
||||||
|
timeout.tv_usec=500000;
|
||||||
|
broadcastPresence();
|
||||||
|
} else {
|
||||||
|
tleft-=telapsed;
|
||||||
|
timeout.tv_sec=tleft/1000;
|
||||||
|
timeout.tv_usec=(tleft%1000)*1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->termLock.Leave(); //VERY hacky. don't like it
|
||||||
if (d->exit) return;
|
if (d->exit) return;
|
||||||
int rt=select(maxfd,&fds,NULL,NULL,&timeout);
|
int rt=select(maxfd,&fds,NULL,NULL,&timeout);
|
||||||
if (d->exit) return;
|
if (d->exit) return;
|
||||||
d->termLock.Enter();
|
d->termLock.Enter();
|
||||||
if (d->exit) return;
|
if (d->exit) return;
|
||||||
|
|
||||||
if (rt)
|
if (rt)
|
||||||
{
|
{
|
||||||
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
||||||
|
@ -171,7 +199,9 @@ void UDPWiimote::mainThread()
|
||||||
size_t addr_len;
|
size_t addr_len;
|
||||||
struct sockaddr_storage their_addr;
|
struct sockaddr_storage their_addr;
|
||||||
addr_len = sizeof their_addr;
|
addr_len = sizeof their_addr;
|
||||||
if ((size = recvfrom(fd, (dataz)bf, size , 0,(struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1)
|
if ((size = recvfrom(fd,
|
||||||
|
(dataz)bf,
|
||||||
|
size , 0,(struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1)
|
||||||
{
|
{
|
||||||
ERROR_LOG(WIIMOTE,"UDPWii Packet error");
|
ERROR_LOG(WIIMOTE,"UDPWii Packet error");
|
||||||
}
|
}
|
||||||
|
@ -187,12 +217,9 @@ void UDPWiimote::mainThread()
|
||||||
d->mutex.Leave();
|
d->mutex.Leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
broadcastPresence();
|
|
||||||
}
|
}
|
||||||
} while (!(d->exit));
|
} while (!(d->exit));
|
||||||
d->termLock.Leave();
|
d->termLock.Leave();
|
||||||
//delete thisthr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPWiimote::~UDPWiimote()
|
UDPWiimote::~UDPWiimote()
|
||||||
|
@ -203,9 +230,10 @@ UDPWiimote::~UDPWiimote()
|
||||||
d->termLock.Leave();
|
d->termLock.Leave();
|
||||||
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
||||||
close(*i);
|
close(*i);
|
||||||
|
close(d->bipv4_fd);
|
||||||
|
close(d->bipv6_fd);
|
||||||
cleanup;
|
cleanup;
|
||||||
delete d;
|
delete d;
|
||||||
//PanicAlert("UDPWii destructed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ACCEL_FLAG (1<<0)
|
#define ACCEL_FLAG (1<<0)
|
||||||
|
@ -219,11 +247,11 @@ int UDPWiimote::pharsePacket(u8 * bf, size_t size)
|
||||||
if (size<3) return -1;
|
if (size<3) return -1;
|
||||||
if (bf[0]!=0xde)
|
if (bf[0]!=0xde)
|
||||||
return -1;
|
return -1;
|
||||||
if (bf[1]==0)
|
//if (bf[1]==0)
|
||||||
time=0;
|
// time=0;
|
||||||
if (bf[1]<time)
|
//if (bf[1]<time) //NOT LONGER NEEDED TO ALLOW MULTIPLE IPHONES ON A SINGLE PORT
|
||||||
return -1;
|
// return -1;
|
||||||
time=bf[1];
|
//time=bf[1];
|
||||||
u32 *p=(u32*)(&bf[3]);
|
u32 *p=(u32*)(&bf[3]);
|
||||||
if (bf[2]&ACCEL_FLAG)
|
if (bf[2]&ACCEL_FLAG)
|
||||||
{
|
{
|
||||||
|
@ -269,9 +297,67 @@ int UDPWiimote::pharsePacket(u8 * bf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UDPWiimote::initBroadcastIPv4()
|
||||||
|
{
|
||||||
|
d->bipv4_fd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (d->bipv4_fd == BAD_SOCK)
|
||||||
|
{
|
||||||
|
WARN_LOG(WIIMOTE,"socket() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int broad=1;
|
||||||
|
if (setsockopt(d->bipv4_fd,SOL_SOCKET,SO_BROADCAST, &broad, sizeof broad) == -1)
|
||||||
|
{
|
||||||
|
WARN_LOG(WIIMOTE,"setsockopt(SO_BROADCAST) failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPWiimote::broadcastIPv4(const void * data, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct sockaddr_in their_addr;
|
||||||
|
their_addr.sin_family = AF_INET;
|
||||||
|
their_addr.sin_port = htons(4431);
|
||||||
|
their_addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
|
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
|
||||||
|
|
||||||
|
int num;
|
||||||
|
if ((num=sendto(d->bipv4_fd,(const dataz)data,size,0,(struct sockaddr *) &their_addr, sizeof their_addr)) == -1)
|
||||||
|
{
|
||||||
|
WARN_LOG(WIIMOTE,"sendto() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPWiimote::initBroadcastIPv6()
|
||||||
|
{
|
||||||
|
//TODO: IPv6 support
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPWiimote::broadcastIPv6(const void * data, size_t size)
|
||||||
|
{
|
||||||
|
//TODO: IPv6 support
|
||||||
|
}
|
||||||
|
|
||||||
void UDPWiimote::broadcastPresence()
|
void UDPWiimote::broadcastPresence()
|
||||||
{
|
{
|
||||||
// NOTICE_LOG(WIIMOTE,"UDPWii broadcasting presence");
|
size_t slen;
|
||||||
|
u8 bf[512];
|
||||||
|
bf[0]=0xdf; //magic number
|
||||||
|
*((u16*)(&(bf[1])))=htons(bcastMagic); //unique per-wiimote 16-bit ID
|
||||||
|
bf[3]=(u8)index; //wiimote index
|
||||||
|
*((u16*)(&(bf[4])))=htons(int_port); //port
|
||||||
|
d->nameMutex.Enter();
|
||||||
|
slen=displayName.size();
|
||||||
|
if (slen>=256)
|
||||||
|
slen=255;
|
||||||
|
bf[6]=(u8)slen; //display name size (max 255)
|
||||||
|
memcpy(&(bf[7]),displayName.c_str(),slen); //display name
|
||||||
|
d->nameMutex.Leave();
|
||||||
|
broadcastIPv4(bf,7+slen);
|
||||||
|
broadcastIPv6(bf,7+slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPWiimote::getAccel(float &_x, float &_y, float &_z)
|
void UDPWiimote::getAccel(float &_x, float &_y, float &_z)
|
||||||
|
@ -281,7 +367,6 @@ void UDPWiimote::getAccel(float &_x, float &_y, float &_z)
|
||||||
_y=(float)y;
|
_y=(float)y;
|
||||||
_z=(float)z;
|
_z=(float)z;
|
||||||
d->mutex.Leave();
|
d->mutex.Leave();
|
||||||
//NOTICE_LOG(WIIMOTE,"%lf %lf %lf",_x, _y, _z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 UDPWiimote::getButtons()
|
u32 UDPWiimote::getButtons()
|
||||||
|
@ -324,3 +409,11 @@ const char * UDPWiimote::getPort()
|
||||||
{
|
{
|
||||||
return port.c_str();
|
return port.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UDPWiimote::changeName(const char * name)
|
||||||
|
{
|
||||||
|
d->nameMutex.Enter();
|
||||||
|
displayName=name;
|
||||||
|
d->nameMutex.Leave();
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
class UDPWiimote
|
class UDPWiimote
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UDPWiimote(const char * port);
|
UDPWiimote(const char * port, const char * name, int index);
|
||||||
virtual ~UDPWiimote();
|
virtual ~UDPWiimote();
|
||||||
void getAccel(float &x, float &y, float &z);
|
void getAccel(float &x, float &y, float &z);
|
||||||
u32 getButtons();
|
u32 getButtons();
|
||||||
|
@ -31,8 +31,9 @@ public:
|
||||||
void getNunchuckAccel(float &x, float &y, float &z);
|
void getNunchuckAccel(float &x, float &y, float &z);
|
||||||
int getErrNo() {return err;};
|
int getErrNo() {return err;};
|
||||||
const char * getPort();
|
const char * getPort();
|
||||||
|
void changeName(const char * name);
|
||||||
private:
|
private:
|
||||||
std::string port;
|
std::string port,displayName;
|
||||||
int pharsePacket(u8 * data, size_t size);
|
int pharsePacket(u8 * data, size_t size);
|
||||||
void mainThread();
|
void mainThread();
|
||||||
struct _d; //using pimpl because Winsock2.h doesen't have include guards -_-
|
struct _d; //using pimpl because Winsock2.h doesen't have include guards -_-
|
||||||
|
@ -43,10 +44,16 @@ private:
|
||||||
double pointerX,pointerY;
|
double pointerX,pointerY;
|
||||||
u8 nunMask;
|
u8 nunMask;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
u16 bcastMagic;
|
||||||
int err;
|
int err;
|
||||||
|
int index;
|
||||||
|
int int_port;
|
||||||
static int noinst;
|
static int noinst;
|
||||||
friend void _UDPWiiThread(void* arg);
|
friend void _UDPWiiThread(void* arg);
|
||||||
void broadcastPresence();
|
void broadcastPresence();
|
||||||
u8 time;
|
void broadcastIPv4(const void * data, size_t size);
|
||||||
|
void broadcastIPv6(const void * data, size_t size);
|
||||||
|
void initBroadcastIPv4();
|
||||||
|
void initBroadcastIPv6();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,7 +69,7 @@ void UDPWrapper::Refresh()
|
||||||
if (strcmp(inst->getPort(),port.c_str()))
|
if (strcmp(inst->getPort(),port.c_str()))
|
||||||
{
|
{
|
||||||
delete inst;
|
delete inst;
|
||||||
inst= new UDPWiimote(port.c_str());
|
inst= new UDPWiimote(port.c_str(),"Dolphin-Emu",index); //TODO: Changeable display name
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ void UDPWrapper::Refresh()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
inst= new UDPWiimote(port.c_str());
|
inst= new UDPWiimote(port.c_str(),"Dolphin-Emu",index);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPWrapper::~UDPWrapper()
|
UDPWrapper::~UDPWrapper()
|
||||||
|
|
Loading…
Reference in New Issue