Index: code/branches/wiimote/src/external/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/CMakeLists.txt	(revision 9689)
+++ code/branches/wiimote/src/external/CMakeLists.txt	(revision 9780)
@@ -32,2 +32,5 @@
 ADD_SUBDIRECTORY(ois)
 ADD_SUBDIRECTORY(tinyxml)
+IF(LINUX)
+ADD_SUBDIRECTORY(wiicpp)
+ENDIF(LINUX)
Index: code/branches/wiimote/src/external/wiicpp/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/CMakeLists.txt	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/CMakeLists.txt	(revision 9780)
@@ -0,0 +1,41 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(WiiC)
+
+# Preliminary stuff
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	SET(LINUX 1)
+	ADD_DEFINITIONS(-DLINUX)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+#SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/")
+SET(CMAKE_CXX_FLAGS "-g -Wall")
+
+# Third-party libraries
+#FIND_PACKAGE(Bluetooth REQUIRED)
+
+FIND_PACKAGE(OpenCV QUIET)
+IF(OpenCV_FOUND)
+	MESSAGE(STATUS "Found OpenCV:")
+	MESSAGE(STATUS "   - Include Dir: ${OpenCV_INCLUDE_DIRS}")
+	MESSAGE(STATUS "   - Libs: ${OpenCV_LIBS}")
+	MESSAGE(STATUS "   - Version: ${OpenCV_VERSION}")
+	IF("${OpenCV_VERSION}" STRLESS "2.2.0")
+		ADD_DEFINITIONS(-DCV_OLD)
+	ENDIF("${OpenCV_VERSION}" STRLESS "2.2.0")
+ELSE(OpenCV_FOUND)
+	MESSAGE(STATUS "OpenCV not found but not required. WiiC-ML will not be compiled.")
+ENDIF(OpenCV_FOUND)
+
+# Source code
+ADD_SUBDIRECTORY(wiic)
+ADD_SUBDIRECTORY(wiicpp)
+#ADD_SUBDIRECTORY(ml)
+#ADD_SUBDIRECTORY(bin)
+
+# Config dir
+#MAKE_DIRECTORY($ENV{HOME}/.wiic)
+
+# Documentation
+#SET(DOXYFILE_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/../doc")
+#include(UseDoxygen)
+
Index: code/branches/wiimote/src/external/wiicpp/log/accsample.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/accsample.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/accsample.cpp	(revision 9780)
@@ -0,0 +1,25 @@
+#include "accsample.h"
+
+using namespace std;
+
+AccSample::AccSample(float x, float y, float z)
+	: Sample() 
+{ 
+	ax = x; 
+	ay = y; 
+	az = z; 
+	logType = WIIC_LOG_ACC;
+}
+
+AccSample::AccSample(const string& line)
+	: Sample()
+{
+	istringstream inLine(line);
+	inLine >> relTimestamp >> ax >> ay >> az; 
+	logType = WIIC_LOG_ACC;
+}
+
+void AccSample::save(ofstream& out)
+{
+	out << "ACC " << getTimestampFromGestureStart() << " " << ax << " " << ay << " " << az << endl;
+}
Index: code/branches/wiimote/src/external/wiicpp/log/accsample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/accsample.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/accsample.h	(revision 9780)
@@ -0,0 +1,25 @@
+#ifndef ACC_SAMPLE_H
+#define ACC_SAMPLE_H
+
+#include "sample.h"
+
+class AccSample : public Sample
+{
+public:
+	AccSample(float x, float y, float z);
+	AccSample(const string& line);
+	~AccSample() {}
+	inline float x() const { return ax;	}
+	inline float y() const { return ay;	}
+	inline float z() const { return az;	}
+	
+	virtual void save(ofstream& out);
+
+private:
+	float ax;
+	float ay;
+	float az;
+};
+
+#endif
+
Index: code/branches/wiimote/src/external/wiicpp/log/dataset.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/dataset.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/dataset.cpp	(revision 9780)
@@ -0,0 +1,150 @@
+#include "dataset.h"
+#include "wiic_internal.h"
+
+/** 
+ * Dataset destructor, which calls clear.
+ */
+Dataset::~Dataset()
+{
+	clear();
+}
+
+/** 
+ * Add a new training to the dataset.
+ * 
+ * @param training Add a training to the dataset.
+ */
+void Dataset::addTraining(Training* t)
+{
+	if(t)
+		trainings.push_back(t);
+		
+	loaded = true;
+}
+
+/**
+ * Load a dataset stored in a file.
+ *
+ * @param filename Dataset filename
+ */
+bool Dataset::loadDataset(const string& nomefile)
+{
+	int version; 
+	string line, dummy;
+	ifstream infile(nomefile.c_str());
+
+	if(!infile.is_open()) {
+		cout << "[Error] Unable to open the dataset file" << endl;
+		return false;
+	}
+	else {
+		trainings.clear();
+		
+		// Version
+		getline(infile,line); // First line is WiiC log version
+		if(line.find("WiiC") == string::npos) {
+			cout << "[Error] Bad log format." << endl;
+			return false;
+		}
+		istringstream iline(line);
+		iline >> dummy >> version;
+		if(version > WIIC_LOG_VERSION) {
+			cout << "[Error] Unsupported WiiC log version." << endl;
+			return false;
+		}
+		getline(infile,line); // Date (we should load this as well...)
+		
+		// For each training
+		int counter = 0;
+		while(!infile.eof()) {
+			getline(infile,line);
+			istringstream iline(line);
+			string cmd; 
+			unsigned long ts;
+			iline >> cmd >> ts;
+			if(cmd == "START") {
+				// Each training is inserted in the training vector	
+				trainings.push_back(new Training());
+				trainings[counter]->setTimestampFromMidnight(ts);
+				if(!(trainings[counter++]->loadTraining(infile))) {
+					cout << "[Error] Unable to load a training in the dataset" << endl ;
+					return false;
+				}
+			}
+		}
+	}
+	infile.close();
+	loaded = true;
+	
+	return loaded;
+}
+
+/**
+ * Delete all trainings and clear the buffer. This method will take 
+ * care of freeing the memory of each training in the dataset, 
+ * hence you don't need to free them in your code.
+ */
+void Dataset::clear()
+{
+	for(unsigned int i = 0 ; i < trainings.size() ; i++) {
+		if(trainings[i]) {
+			delete trainings[i];
+			trainings[i] = 0;
+		}
+	}
+	trainings.clear();
+	loaded = false;
+}
+
+/**
+ * Save the dataset into a file for training and recognition.
+ *
+ * @param filename Pathname of the destination file
+ * @param addr Wii device mac address
+ */
+bool Dataset::save(const char* file, const char* addr) const
+{
+	// Open file
+	ofstream out(file, ios::trunc);
+	if(!out.is_open()) { // File does not exist, hence I create it
+		cout << "[Error] Unable to open " << file << endl;
+		return false;
+	}
+	
+	// Save header
+	saveHeader(out, addr);
+	
+	// For each training
+	for(int i = 0 ; i < size() ; i++)	{
+		const Training* training = trainingAt(i);
+		if(training)
+			training->save(out);
+	}
+	
+	out.close();
+
+	return true;
+}
+
+/**
+ * Save the dataset header into a file.
+ *
+ * @param out Output file stream
+ * @param addr Wii device MAC address
+ */	
+void Dataset::saveHeader(ofstream& out, const char* addr) const
+{
+	// Log Version
+	out << "WiiC " << WIIC_LOG_VERSION << endl;
+
+	// Date
+    time_t tim=time(NULL);
+    char *s=ctime(&tim);
+    s[strlen(s)-1]=0;        // remove \n
+	out << s << endl;
+	
+	// Mac Address
+	out << addr << endl;
+}
+
+
Index: code/branches/wiimote/src/external/wiicpp/log/dataset.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/dataset.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/dataset.h	(revision 9780)
@@ -0,0 +1,120 @@
+/** \file dataset.h
+ * Header file of the class Dataset.
+ */
+#ifndef DATASET_H
+#define DATASET_H
+
+#include "training.h"
+
+/** 
+ * \class Dataset 
+ *
+ * A Dataset is a collection of trainings, which can represent multiple gestures 
+ * acquired over time, with different lenghts, and with different approaches.
+ */
+class Dataset
+{
+public:
+	/** 
+	 * Default constructor.
+	 */
+	Dataset() : loaded(false) { }
+	
+	/** 
+	 * Creates a Dataset object from a log file.
+	 * 
+	 * @param filename Pathname of the dataset to load
+	 */
+	Dataset(const string& filename) : loaded(false) { loadDataset(filename); }
+	~Dataset();
+
+	/** 
+	 * Retrieves the dataset's size. 
+	 *
+	 * \return the number of trainings collected in the current dataset
+	 */
+	inline unsigned int size() const { return trainings.size(); }
+
+	/** 
+	 * Returns a training in the dataset as a constant pointer. 
+	 * 
+	 * @param[in] i The training index in the dataset
+	 *
+	 * \return A constant pointer to the Training object corresponding to the i-th element in the dataset
+	 */
+	inline const Training* trainingAt(const unsigned int i) const { 
+		if(i < trainings.size())
+			return trainings[i]; 
+		else {
+			cout << "[Error]: requested out of array bound index in dataset." << endl;
+			return 0;
+		}
+	}
+
+	/** 
+	 * Returns a training in the dataset as a pointer. 
+	 * 
+	 * @param[in] i The training index in the dataset
+	 *
+	 * \return A pointer to the Training object corresponding to the i-th element in the dataset
+	 */
+	inline Training* trainingAt(const unsigned int i) { 
+		if(i < trainings.size())
+			return trainings[i]; 
+		else {
+			cout << "[Error]: requested out of array bound index in dataset." << endl;
+			return 0;
+		}
+	}
+
+	/** 
+	 * Adds a training to the dataset. The new element will be indexed as the last element and
+	 * will not be copied. It will be responsability of the destructor of the class 
+	 * Dataset to deallocate this element.
+	 * 
+	 * @param[in] training The training to add
+	 */
+	void addTraining(Training* training);
+
+	/** 
+	 * Loads a new dataset from file, erasing the current one (if not saved on file). 
+	 * 
+	 * @param[in] filename Filename of the dataset to load
+	 */
+	bool loadDataset(const string& filename);
+	
+	/** 
+	 * Saves the current dataset in a file. 
+	 * 
+	 * @param[in] filename Desired filename of the saved dataset
+	 * @param[in] addr MAC address of the source device for the dataset
+	 */
+	bool save(const char* filename, const char* addr) const;
+	
+	/** 
+	 * Deallocates and deletes all the current trainings in the dataset.
+	 */
+	void clear() ;
+
+	/**
+	 * Checks if the instance has a valid dataset loaded.
+	 *
+	 * \return TRUE if a dataset is correctly loaded, FALSE otherwise
+	 */
+	inline bool isValid() const { return loaded; }
+
+protected:
+	/**
+	 * Saves the initial header of WiiC's log files.
+	 *
+	 * @param[in] out The output stream of the log file
+	 * @param[in] addr MAC address of the source device for the dataset
+	 */
+	void saveHeader(ofstream& out, const char* addr) const;
+
+private:
+	vector<Training*> trainings;
+	bool loaded;
+};
+
+#endif
Index: code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp	(revision 9780)
@@ -0,0 +1,25 @@
+#include "gyrosample.h"
+
+using namespace std;
+
+GyroSample::GyroSample(float r, float p, float y) 
+	: Sample()
+{ 
+	roll_ = r; 
+	pitch_ = p; 
+	yaw_ = y;
+	logType = WIIC_LOG_GYRO; 
+}
+
+GyroSample::GyroSample(const string& line)
+	: Sample()
+{
+	istringstream inLine(line);
+	inLine >> relTimestamp >> roll_ >> pitch_ >> yaw_; 
+	logType = WIIC_LOG_GYRO; 
+}
+
+void GyroSample::save(ofstream& out)
+{
+	out << "GYRO " << getTimestampFromGestureStart() << " " << roll_ << " " << pitch_ << " " << yaw_ << endl;
+}
Index: code/branches/wiimote/src/external/wiicpp/log/gyrosample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/gyrosample.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/gyrosample.h	(revision 9780)
@@ -0,0 +1,24 @@
+#ifndef GYRO_SAMPLE_H
+#define GYRO_SAMPLE_H
+
+#include "sample.h"
+
+class GyroSample : public Sample
+{
+public:
+	GyroSample(float r, float p, float y);
+	GyroSample(const string& line);
+	~GyroSample() {}
+	inline float roll() const { return roll_; }
+	inline float pitch() const { return pitch_; }
+	inline float yaw() const { return yaw_; }
+	
+	virtual void save(ofstream& out);
+
+private:
+	float roll_;
+	float pitch_;
+	float yaw_;
+};
+
+#endif
Index: code/branches/wiimote/src/external/wiicpp/log/logger.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/logger.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/logger.cpp	(revision 9780)
@@ -0,0 +1,124 @@
+#include "logger.h"
+#include "wiicpp.h"
+#include "wiic_internal.h"
+
+void Logger::SetLogLevel(LogStatus status, int type, const string& file)
+{		
+	// Avoid repetitions
+	if(status == logStatus && type == logType && file == logFile)
+		return;
+		
+	if(status == WIIC_LOG_START) {
+		ResetTimestamp();	
+	
+		if((file == "" && logFile != "") || (file == logFile)) { // Same file
+			if(logEnabled) 
+				out << "END" << endl;
+				
+			// New training
+			unsigned long trainingTs = (startTs.tv_sec % 86400) * 1000 + startTs.tv_usec / 1000;
+			out << "START " << trainingTs << endl;
+		}
+		else if(file != "") { // Open a new log file
+			if(out.is_open()) { // In case a previous log file is still open
+				if(logEnabled)
+					out << "END" << endl;
+				out.close();
+			}
+						
+			logFile = file;
+			
+			// Check if the file already exists, and whether it is a WiiC logfile
+			bool resume = CheckLogFile();
+			
+			out.open(logFile.c_str(),ios::app);
+			if(!out.is_open()) 
+				return;
+		
+			// Sometimes we want to modify a log file, not to create a new one
+			if(!resume)
+				SaveLogHeader();
+
+			// New training				
+			unsigned long trainingTs = (startTs.tv_sec % 86400) * 1000 + startTs.tv_usec / 1000;
+			out << "START " << trainingTs << endl;
+		}
+		else // How can I log if you don't provide me with a file???
+			return;
+				
+		// Status init
+		logType = type;
+		logStatus = WIIC_LOG_START;
+		logEnabled = true;
+	}
+	else if(status == WIIC_LOG_STOP) {
+		out << "END" << endl;
+		if(out.is_open())
+			out.close();
+			
+		// Status reset
+		logStatus = WIIC_LOG_STOP;
+		logType = WIIC_LOG_NONE;
+		logEnabled = false;
+		logFile = "";
+	}
+	else {
+		return;
+	}	
+}
+
+bool Logger::CheckLogFile()
+{
+	ifstream in(logFile.c_str());
+	if(!in.is_open())
+		return false;
+		
+	string wiicToken;
+	int logVersion;
+	in >> wiicToken >> logVersion;
+	in.close();
+	
+	if(wiicToken == "WiiC" && logVersion <= WIIC_LOG_VERSION)
+		return true;
+		
+	return false;
+}
+
+/**
+ * Save the dataset header into a file.
+ *
+ * @param out Output file stream
+ * @param addr Wii device MAC address
+ */	
+void Logger::SaveLogHeader()
+{
+	// Log Version
+	out << "WiiC " << WIIC_LOG_VERSION << endl;
+
+	// Date
+    time_t tim=time(NULL);
+    char *s=ctime(&tim);
+    s[strlen(s)-1]=0;        // remove \n
+	out << s << endl;
+
+	// Mac Address
+	out << deviceAddr << endl;
+}
+
+void Logger::InitLog()
+{
+	// Compute the relative timestamp
+	struct timeval t;
+	gettimeofday(&t,0);
+	relativeTs = ((t.tv_sec*1000000.0 + t.tv_usec) - (startTs.tv_sec*1000000.0 + startTs.tv_usec))/1000.0;
+}
+
+void Logger::LogAcc(float x, float y, float z)
+{
+	out << "ACC " << relativeTs << " " << x << " " << y << " " << z << endl;	
+}
+
+void Logger::LogGyro(float roll, float pitch, float yaw)
+{
+	out << "GYRO " << relativeTs << " " << roll << " " << pitch << " " << yaw << endl;
+}
Index: code/branches/wiimote/src/external/wiicpp/log/logger.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/logger.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/logger.h	(revision 9780)
@@ -0,0 +1,85 @@
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <iostream>
+#include <fstream>
+#include "dataset.h"
+
+namespace WiiC {
+	/*
+	 * LOG_START: open a dataset
+	 * LOG_STOP: close the dataset
+	 */
+	enum LogStatus {
+		WIIC_LOG_START = 0x0,
+		WIIC_LOG_STOP = 0x1
+	};
+}
+
+using namespace std;
+using namespace WiiC;
+
+class Logger {
+public:
+	Logger() : deviceAddr(""), logFile(""), relativeTs(0.0), logEnabled(false), 
+		logType(WIIC_LOG_NONE), logStatus(WIIC_LOG_STOP) { }
+	Logger(const Logger& logger) : deviceAddr(logger.deviceAddr), logFile(logger.logFile), 
+			startTs(logger.startTs), relativeTs(logger.relativeTs), logEnabled(logger.logEnabled), 
+			logType(logger.logType), logStatus(logger.logStatus) { 
+		if(out.is_open()) out.close();
+		if(logger.out.is_open()) out.open(logFile.c_str(),ios::app); 
+	}
+	
+	~Logger() { 
+		if(out.is_open()) out.close(); 
+	}
+	
+	Logger& operator=(const Logger& logger) {
+		deviceAddr = logger.deviceAddr;
+		logFile = logger.logFile;
+		logType = logger.logType;
+		logStatus = logger.logStatus;
+		logEnabled = logger.logEnabled;
+		startTs = logger.startTs;
+		relativeTs = logger.relativeTs;
+		if(out.is_open()) out.close();
+		if(logger.out.is_open()) out.open(logFile.c_str(),ios::app); 
+		
+		return *this;
+	}
+		
+	void InitLog();
+	void LogAcc(float x, float y, float z);
+	void LogGyro(float x, float y, float z);
+	void SaveLogHeader();
+
+	void SetLogLevel(LogStatus status, int type =WIIC_LOG_NONE, const string& file ="");	
+	inline int GetLogType() const { return logType; }
+	inline string GetLogFilename() const { return logFile; }
+	inline void SetLogStatus(const LogStatus status) { logStatus = status; }
+	inline bool isLogEnabled() { return logEnabled; }
+	
+	inline void ResetTimestamp() { gettimeofday(&startTs,0); }
+	inline void SetDeviceAddress(const string& addr) { deviceAddr = addr;}
+
+protected:
+	bool CheckLogFile();
+	
+private:
+	string deviceAddr;
+	
+	// Log file info
+	string logFile;
+	ofstream out;
+	
+	// Timestamp info
+	struct timeval startTs;
+	double relativeTs;
+	
+	// Logging info
+	bool logEnabled;
+	int logType;
+	LogStatus logStatus;
+};
+
+#endif
Index: code/branches/wiimote/src/external/wiicpp/log/sample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/sample.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/sample.h	(revision 9780)
@@ -0,0 +1,34 @@
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+#include <sys/time.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#define WIIC_LOG_NONE	0x0
+#define WIIC_LOG_ACC	0x1
+#define WIIC_LOG_GYRO	0x2
+
+using namespace std;
+
+class Sample
+{
+public:
+	Sample() : relTimestamp(0) { }
+	~Sample() {}
+	virtual void save(ofstream& out) =0;
+	
+	inline void setLogType(int l) { logType = l; }
+	inline int getLogType() const { return logType; }
+	inline void setTimestampFromGestureStart(unsigned long t) { relTimestamp = t; }
+	inline unsigned long getTimestampFromGestureStart() const { return relTimestamp; }
+	
+protected:	
+
+	unsigned long relTimestamp; // msec (from the beginning of the gesture)
+	int logType;
+};
+
+#endif
+
Index: code/branches/wiimote/src/external/wiicpp/log/training.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/training.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/training.cpp	(revision 9780)
@@ -0,0 +1,97 @@
+#include "training.h"
+
+/** 
+ * Dataset destructor, which calls clear.
+ */
+Training::~Training()
+{
+	clear();
+}
+
+/**
+ * Load a training stored in a file.
+ *
+ * @param training File stream of the contained training
+ */
+bool Training::loadTraining(ifstream& training)
+{
+	string sample, cmd;
+	
+	// Get a sample	
+	getline(training, sample);
+	
+	// Parse every sample to get the log type
+	istringstream sStr(sample);
+	sStr >> cmd;
+	
+	while(!training.eof() && cmd != "END" && cmd != "") {	
+		if(cmd == "ACC") 
+			addSample(new AccSample(sStr.str()));
+		else if(cmd == "GYRO") 
+			addSample(new GyroSample(sStr.str()));
+		else {
+			cout << "[Error] Bad log type." << endl;	
+			return false;	
+		}
+		
+		getline(training, sample);
+		sStr.str(sample);
+		sStr >> cmd;
+	}		
+	
+	return true;
+}
+
+/**
+ * Save the training into a file for training and recognition.
+ *
+ * @param out Stream of the destination file
+ */
+void Training::save(ofstream& out) const
+{	
+	// Training Header
+	out << "START " << timestamp << endl;
+	
+	// Samples
+	for(unsigned int i = 0 ; i < samples.size() ; i++)
+		samples[i]->save(out);
+		
+	out << "END" << endl;
+}
+
+/** 
+ * Add a new training to the dataset.
+ * 
+ * @param sample Add a sample to the training set.
+ */
+void Training::addSample(Sample* sample)
+{
+	// We retrieve the overall gesture timestamp
+	struct timeval t;
+	gettimeofday(&t,0);
+	unsigned long sampleTs = (t.tv_sec % 86400) * 1000 + t.tv_usec / 1000;
+		
+	// We compute the relative timestamp in msec
+	unsigned long deltaT = sampleTs - timestamp;
+	
+	if(sample) {
+		sample->setTimestampFromGestureStart(deltaT);
+		samples.push_back(sample);
+	}
+}
+
+/**
+ * Delete all samples and clear the buffer. This method will take 
+ * care of freeing the memory of each sample in the training set, 
+ * hence you don't need to free them in your code.
+ */
+void Training::clear()
+{
+	for(unsigned int i = 0 ; i < samples.size() ; i++) {
+		if(samples[i]) {
+			delete samples[i];
+			samples[i] = 0;
+		}
+	}
+	samples.clear();
+}
Index: code/branches/wiimote/src/external/wiicpp/log/training.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/training.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/log/training.h	(revision 9780)
@@ -0,0 +1,71 @@
+#ifndef TRAINING_H
+#define TRAINING_H
+
+#include <fstream>
+#include <iostream>
+#include <vector>
+#include <sstream>
+#include "sample.h"
+#include "accsample.h"
+#include "gyrosample.h"
+
+using namespace std;
+
+/**
+ * Class Training to save the individual training of a gesture  
+ */
+class Training
+{
+public:
+	/**
+	 * Default constructor.
+	 */
+	Training() { }
+	~Training();
+
+	bool loadTraining(ifstream&);
+	void save(ofstream&) const;
+	void addSample(Sample*);
+	void clear();
+
+	/** 
+	 * Returns the i-th sample of the training as a constant pointer. 
+	 * 
+	 * @param i Sample index in the training set
+	 */
+	inline const Sample* sampleAt(unsigned int i) const { 
+		if(i < samples.size())
+			return samples[i]; 
+		else {
+			cout << "[Error]: requested out of array bound index in training." << endl;
+			return 0;
+		}
+	}
+
+	/** 
+	 * Returns the i-th sample of the training as a pointer. 
+	 * 
+	 * @param i Sample index in the training set
+	 */
+	inline Sample* sampleAt(unsigned int i) { 
+		if(i < samples.size())
+			return samples[i]; 
+		else {
+			cout << "[Error]: requested out of array bound index in training." << endl;
+			return 0;
+		}
+	}
+	
+	/** 
+	 * Number of samples in the current training. 
+	 */
+	inline unsigned int size() const { return samples.size(); }
+	
+	inline void setTimestampFromMidnight(unsigned long ts) { timestamp = ts; }
+
+private:
+	vector<Sample*> samples;
+	unsigned long timestamp; // Training timestamp (beginning of the gesture)
+};
+
+#endif
Index: code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt	(revision 9780)
@@ -0,0 +1,38 @@
+FILE(GLOB WIIC_SOURCES "*.c")
+
+IF(APPLE)
+	FOREACH(WIIC_SOURCE ${WIIC_SOURCES})
+		STRING(REGEX REPLACE ".io_nix.c" "" WIIC_SOURCE ${WIIC_SOURCE})
+		SET(WIIC_MAC_SOURCES ${WIIC_MAC_SOURCES} "${WIIC_SOURCE}")
+	ENDFOREACH(WIIC_SOURCE)
+	SET(WIIC_MAC_SOURCES ${WIIC_MAC_SOURCES} "io_mac.m")
+	SET(WIIC_SOURCES ${WIIC_MAC_SOURCES})
+ENDIF(APPLE)
+
+#ADD_LIBRARY(wiic SHARED ${WIIC_SOURCES})
+#IF(LINUX)
+#	TARGET_LINK_LIBRARIES(wiic ${BLUETOOTH_LIBRARY} m pthread)
+#ENDIF(LINUX)
+#IF(APPLE)
+#	TARGET_LINK_LIBRARIES(wiic "-framework IOBluetooth -framework Foundation -framework CoreFoundation")
+#ENDIF(APPLE)
+
+ORXONOX_ADD_LIBRARY(wiic_orxonox
+  ORXONOX_EXTERNAL
+  NO_DLL_INTERFACE
+  VERSION
+    1.1
+  LINK_LIBRARIES
+    ${BLUETOOTH_LIBRARY}
+    m
+  SOURCE_FILES
+    ${WIIC_SOURCES}
+	
+)
+
+
+#INSTALL(TARGETS	wiic DESTINATION /usr/local/lib)
+INSTALL(FILES wiic.h DESTINATION /usr/local/include/wiic)
+INSTALL(FILES wiic_functions.h DESTINATION /usr/local/include/wiic)
+INSTALL(FILES wiic_macros.h DESTINATION /usr/local/include/wiic)
+INSTALL(FILES wiic_structs.h DESTINATION /usr/local/include/wiic)
Index: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c	(revision 9780)
@@ -0,0 +1,172 @@
+/*
+ *	balanceboard.c
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+#include "balanceboard.h"
+#include "events.h"
+
+/**
+ *	@brief Handle the handshake data from the balance board.
+ *
+ *	@param bb		A pointer to a balance_board_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	@return	Returns 1 if handshake was successful, 0 if not.
+ */
+int balance_board_handshake(struct wiimote_t* wm, struct balance_board_t* bb, byte* data, unsigned short len) 
+{
+	int offset = 4;
+	
+	bb->cal_low_weight.top_left = 0;
+	bb->cal_low_weight.top_right = 0;	
+	bb->cal_low_weight.bottom_left = 0;
+	bb->cal_low_weight.bottom_right = 0;
+	bb->cal_medium_weight.top_left = 0;
+	bb->cal_medium_weight.top_right = 0;	
+	bb->cal_medium_weight.bottom_left = 0;
+	bb->cal_medium_weight.bottom_right = 0;
+	bb->cal_high_weight.top_left = 0;
+	bb->cal_high_weight.top_right = 0;	
+	bb->cal_high_weight.bottom_left = 0;
+	bb->cal_high_weight.bottom_right = 0;
+	bb->pressure_raw_data.top_left = 0;
+	bb->pressure_raw_data.top_right = 0;	
+	bb->pressure_raw_data.bottom_left = 0;
+	bb->pressure_raw_data.bottom_right = 0;	
+	bb->pressure_weight.top_left = 0.0;
+	bb->pressure_weight.top_right = 0.0;	
+	bb->pressure_weight.bottom_left = 0.0;
+	bb->pressure_weight.bottom_right = 0.0;	
+	bb->pressure_weight.weight = 0.0;
+	
+	/*
+	 *	Sometimes the data returned here is not correct (all bytes are 0xFF).
+	 *	This might happen because the wiimote is lagging
+	 *	behind our initialization sequence.
+	 *	To fix this just request the handshake again.	 
+	 */
+	if (data[offset+offset] == 0xFF && data[offset+offset+16] == 0xFF) {
+		/* get the calibration data */
+		byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+		WIIC_DEBUG("Balance board handshake appears invalid, trying again.");
+		wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+		return 0;
+	}
+	
+	bb->cal_low_weight.top_right = (data[offset+0] << 8) | data[offset+1] ;
+	bb->cal_low_weight.bottom_right = (data[offset+2] << 8) | data[offset+3] ;
+	bb->cal_low_weight.top_left = (data[offset+4] << 8) | data[offset+5] ;
+	bb->cal_low_weight.bottom_left = (data[offset+6] << 8) | data[offset+7] ;
+	bb->cal_medium_weight.top_right = (data[offset+8] << 8) | data[offset+9] ;
+	bb->cal_medium_weight.bottom_right = (data[offset+10] << 8) | data[offset+11] ;
+	bb->cal_medium_weight.top_left = (data[offset+12] << 8) | data[offset+13] ;
+	bb->cal_medium_weight.bottom_left = (data[offset+14] << 8) | data[offset+15] ;
+	bb->cal_high_weight.top_right = (data[offset+16] << 8) | data[offset+17] ;
+	bb->cal_high_weight.bottom_right = (data[offset+18] << 8) | data[offset+19] ;
+	bb->cal_high_weight.top_left = (data[offset+20] << 8) | data[offset+21] ;
+	bb->cal_high_weight.bottom_left = (data[offset+22] << 8) | data[offset+23] ;
+
+	/* handshake done */
+	wm->exp.type = EXP_BALANCE_BOARD;
+
+	return 1;
+}
+
+/**
+ *	@brief Handle balance board event.
+ *
+ *	@param bb		A pointer to a balance_board_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void balance_board_event(struct balance_board_t* bb, byte* msg) 
+{
+	// Raw data
+	bb->pressure_raw_data.top_right = (msg[0] << 8) | msg[1];
+	bb->pressure_raw_data.bottom_right = (msg[2] << 8) | msg[3];
+	bb->pressure_raw_data.top_left = (msg[4] << 8) | msg[5];
+	bb->pressure_raw_data.bottom_left = (msg[6] << 8) | msg[7];
+	
+	/* Weight in kg (we must interpole here) */
+
+	// Top Right
+	if(bb->pressure_raw_data.top_right <= bb->cal_medium_weight.top_right) {
+		bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_low_weight.top_right) / (float)(bb->cal_medium_weight.top_right - bb->cal_low_weight.top_right);
+	}
+	else if(bb->pressure_raw_data.top_right <= bb->cal_high_weight.top_right) {
+		bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_medium_weight.top_right) / (float)(bb->cal_high_weight.top_right - bb->cal_medium_weight.top_right) + 17.0;	
+	}
+	else {
+		bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_high_weight.top_right) / (float)(bb->cal_high_weight.top_right - bb->cal_medium_weight.top_right) + 34.0;			
+	}
+	
+	// Bottom Right
+	if(bb->pressure_raw_data.bottom_right <= bb->cal_medium_weight.bottom_right) {
+		bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_low_weight.bottom_right) / (float)(bb->cal_medium_weight.bottom_right - bb->cal_low_weight.bottom_right);
+	}
+	else if(bb->pressure_raw_data.bottom_right <= bb->cal_high_weight.bottom_right) {
+		bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_medium_weight.bottom_right) / (float)(bb->cal_high_weight.bottom_right - bb->cal_medium_weight.bottom_right) + 17.0;	
+	}
+	else {
+		bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_high_weight.bottom_right) / (float)(bb->cal_high_weight.bottom_right - bb->cal_medium_weight.bottom_right) + 34.0;			
+	}
+	
+	// Top Left
+	if(bb->pressure_raw_data.top_left <= bb->cal_medium_weight.top_left) {
+		bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_low_weight.top_left) / (float)(bb->cal_medium_weight.top_left - bb->cal_low_weight.top_left);
+	}
+	else if(bb->pressure_raw_data.top_left <= bb->cal_high_weight.top_left) {
+		bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_medium_weight.top_left) / (float)(bb->cal_high_weight.top_left - bb->cal_medium_weight.top_left) + 17.0;	
+	}
+	else {
+		bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_high_weight.top_left) / (float)(bb->cal_high_weight.top_left - bb->cal_medium_weight.top_left) + 34.0;			
+	}
+	
+	// Botton Left
+	if(bb->pressure_raw_data.bottom_left <= bb->cal_medium_weight.bottom_left) {
+		bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_low_weight.bottom_left) / (float)(bb->cal_medium_weight.bottom_left - bb->cal_low_weight.bottom_left);
+	}
+	else if(bb->pressure_raw_data.bottom_left <= bb->cal_high_weight.bottom_left) {
+		bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_medium_weight.bottom_left) / (float)(bb->cal_high_weight.bottom_left - bb->cal_medium_weight.bottom_left) + 17.0;	
+	}
+	else {
+		bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_high_weight.bottom_left) / (float)(bb->cal_high_weight.bottom_left - bb->cal_medium_weight.bottom_left) + 34.0;			
+	}
+	
+	bb->pressure_weight.weight = bb->pressure_weight.top_right + bb->pressure_weight.top_left + bb->pressure_weight.bottom_right + bb->pressure_weight.bottom_left;
+}
+
+/**
+ *	@brief The balance board disconnected.
+ *
+ *	@param bb		A pointer to a balance_board_t structure.
+ */
+void balance_board_disconnected(struct balance_board_t* bb)
+{
+	memset(bb, 0, sizeof(struct balance_board_t));
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h	(revision 9780)
@@ -0,0 +1,52 @@
+/*
+ *	balanceboard.h
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Balance Board expansion device
+ */
+#ifndef BALANCEBOARD_H_INCLUDED
+#define BALANCEBOARD_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int balance_board_handshake(struct wiimote_t* wm, struct balance_board_t* bb, byte* data, unsigned short len);
+
+void balance_board_disconnected(struct balance_board_t* bb);
+
+void balance_board_event(struct balance_board_t* bb, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BALANCEBOARD_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/classic.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/classic.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/classic.c	(revision 9780)
@@ -0,0 +1,185 @@
+/*
+ *    classic.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Classic controller expansion device.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "classic.h"
+
+static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now);
+
+/**
+ *	@brief Handle the handshake data from the classic controller.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	@return	Returns 1 if handshake was successful, 0 if not.
+ */
+int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) {
+	int i;
+	int offset = 0;
+
+	cc->btns = 0;
+	cc->btns_held = 0;
+	cc->btns_released = 0;
+	cc->r_shoulder = 0;
+	cc->l_shoulder = 0;
+
+	/* decrypt data */
+	for (i = 0; i < len; ++i)
+		data[i] = (data[i] ^ 0x17) + 0x17;
+
+	if (data[offset] == 0xFF) {
+		/*
+		 *	Sometimes the data returned here is not correct.
+		 *	This might happen because the wiimote is lagging
+		 *	behind our initialization sequence.
+		 *	To fix this just request the handshake again.
+		 *
+		 *	Other times it's just the first 16 bytes are 0xFF,
+		 *	but since the next 16 bytes are the same, just use
+		 *	those.
+		 */
+		if (data[offset + 16] == 0xFF) {
+			/* get the calibration data */
+			byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+			WIIC_DEBUG("Classic controller handshake appears invalid, trying again.");
+			wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+			return 0;
+		} else
+			offset += 16;
+	}
+
+
+	/* joystick stuff */
+	cc->ljs.max.x = data[0 + offset] / 4;
+	cc->ljs.min.x = data[1 + offset] / 4;
+	cc->ljs.center.x = data[2 + offset] / 4;
+	cc->ljs.max.y = data[3 + offset] / 4;
+	cc->ljs.min.y = data[4 + offset] / 4;
+	cc->ljs.center.y = data[5 + offset] / 4;
+
+	cc->rjs.max.x = data[6 + offset] / 8;
+	cc->rjs.min.x = data[7 + offset] / 8;
+	cc->rjs.center.x = data[8 + offset] / 8;
+	cc->rjs.max.y = data[9 + offset] / 8;
+	cc->rjs.min.y = data[10 + offset] / 8;
+	cc->rjs.center.y = data[11 + offset] / 8;
+
+	/* handshake done */
+	wm->exp.type = EXP_CLASSIC;
+
+	return 1;
+}
+
+
+/**
+ *	@brief The classic controller disconnected.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ */
+void classic_ctrl_disconnected(struct classic_ctrl_t* cc) {
+	memset(cc, 0, sizeof(struct classic_ctrl_t));
+}
+
+
+
+/**
+ *	@brief Handle classic controller event.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) {
+	int i, lx, ly, rx, ry;
+	byte l, r;
+
+	/* decrypt data */
+	for (i = 0; i < 6; ++i)
+		msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+	classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+
+	/* left/right buttons */
+	l = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5));
+	r = (msg[3] & 0x1F);
+
+	/*
+	 *	TODO - LR range hardcoded from 0x00 to 0x1F.
+	 *	This is probably in the calibration somewhere.
+	 */
+	cc->r_shoulder = ((float)r / 0x1F);
+	cc->l_shoulder = ((float)l / 0x1F);
+
+	/* calculate joystick orientation */
+	lx = (msg[0] & 0x3F);
+	ly = (msg[1] & 0x3F);
+	rx = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7);
+	ry = (msg[2] & 0x1F);
+
+	calc_joystick_state(&cc->ljs, lx, ly);
+	calc_joystick_state(&cc->rjs, rx, ry);
+}
+
+
+/**
+ *	@brief Find what buttons are pressed.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param msg		The message byte specified in the event packet.
+ */
+static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) {
+	/* message is inverted (0 is active, 1 is inactive) */
+	now = ~now & CLASSIC_CTRL_BUTTON_ALL;
+
+	/* pressed now & were pressed, then held */
+	cc->btns_held = (now & cc->btns);
+
+	/* were pressed or were held & not pressed now, then released */
+	cc->btns_released = ((cc->btns | cc->btns_held) & ~now);
+
+	/* buttons pressed now */
+	cc->btns = now;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/classic.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/classic.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/classic.h	(revision 9780)
@@ -0,0 +1,56 @@
+/*
+ *    classic.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Classic controller expansion device.
+ */
+
+#ifndef CLASSIC_H_INCLUDED
+#define CLASSIC_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len);
+
+void classic_ctrl_disconnected(struct classic_ctrl_t* cc);
+
+void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CLASSIC_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/definitions.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/definitions.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/definitions.h	(revision 9780)
@@ -0,0 +1,70 @@
+/*
+ *    definitions.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief General definitions.
+ */
+
+#ifndef DEFINITIONS_H_INCLUDED
+#define DEFINITIONS_H_INCLUDED
+
+/* this is WiiC - used to distinguish from third party programs using wiic.h */
+
+#define WIIMOTE_PI			3.14159265f
+
+/* Error output macros */
+#define WIIC_ERROR(fmt, ...)		fprintf(stderr, "[ERROR] " fmt "\n", ##__VA_ARGS__)
+
+/* Warning output macros */
+#define WIIC_WARNING(fmt, ...)	fprintf(stderr, "[WARNING] " fmt "\n",	##__VA_ARGS__)
+
+/* Information output macros */
+#define WIIC_INFO(fmt, ...)		fprintf(stderr, "[INFO] " fmt "\n", ##__VA_ARGS__)
+
+#ifdef WITH_WIIC_DEBUG
+	#define WIIC_DEBUG(fmt, ...)	fprintf(stderr, "[DEBUG] " __FILE__ ":%i: " fmt "\n", __LINE__, ##__VA_ARGS__)
+#else
+	#define WIIC_DEBUG(fmt, ...)
+#endif
+
+/* Convert between radians and degrees */
+#define RAD_TO_DEGREE(r)	((r * 180.0f) / WIIMOTE_PI)
+#define DEGREE_TO_RAD(d)	(d * (WIIMOTE_PI / 180.0f))
+
+/* Convert to big endian */
+#define BIG_ENDIAN_LONG(i)				(htonl(i))
+#define BIG_ENDIAN_SHORT(i)				(htons(i))
+
+#define absf(x)						((x >= 0) ? (x) : (x * -1.0f))
+#define diff_f(x, y)				((x >= y) ? (absf(x - y)) : (absf(y - x)))
+
+#endif // DEFINITIONS_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c	(revision 9780)
@@ -0,0 +1,197 @@
+/*
+ *    dynamics.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles the dynamics of the wiimote.
+ *
+ *	The file includes functions that handle the dynamics
+ *	of the wiimote.  Such dynamics include orientation and
+ *	motion sensing.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "ir.h"
+#include "dynamics.h"
+
+/**
+ *	@brief Calculate the roll, pitch, yaw.
+ *
+ *	@param ac			An accelerometer (accel_t) structure.
+ *	@param accel		[in] Pointer to a vec3b_t structure that holds the raw acceleration data.
+ *	@param orient		[out] Pointer to a orient_t structure that will hold the orientation data.
+ *	@param rorient		[out] Pointer to a orient_t structure that will hold the non-smoothed orientation data.
+ *	@param smooth		If smoothing should be performed on the angles calculated. 1 to enable, 0 to disable.
+ *
+ *	Given the raw acceleration data from the accelerometer struct, calculate
+ *	the orientation of the device and set it in the \a orient parameter.
+ */
+void calculate_orientation(struct vec3f_t* in, struct ang3f_t* out) {
+	float x, y, z;
+
+	/*
+	 *	roll	- use atan(z / x)		[ ranges from -180 to 180 ]
+	 *	pitch	- use atan(z / y)		[ ranges from -180 to 180 ]
+	 *	yaw		- impossible to tell without IR
+	 */
+
+	/* yaw - set to 0, IR will take care of it if it's enabled */
+	out->yaw = 0.0f;
+
+	/* find out how much it actually moved and normalize to +/- 1g */
+	x = in->x;
+	y = in->y;
+	z = in->z;
+
+	/* make sure x,y,z are between -1 and 1 for the tan functions */
+	if (x < -1.0f)			x = -1.0f;
+	else if (x > 1.0f)		x = 1.0f;
+	if (y < -1.0f)			y = -1.0f;
+	else if (y > 1.0f)		y = 1.0f;
+	if (z < -1.0f)			z = -1.0f;
+	else if (z > 1.0f)		z = 1.0f;
+
+	/* if it is over 1g then it is probably accelerating and the gravity vector cannot be identified */
+	if (abs(in->x) <= 1.0) {
+		/* roll */
+		x = -RAD_TO_DEGREE(atan2f(x, z));
+
+		out->roll = x;
+	}
+
+	if (abs(in->y) <= 1.0) {
+		/* pitch */
+		y = RAD_TO_DEGREE(atan2f(y, z));
+
+		out->pitch = y;
+	}
+}
+
+
+/**
+ *	@brief Calculate the gravity forces on each axis.
+ *
+ *	@param ac			An accelerometer (accel_t) structure.
+ *	@param accel		[in] Pointer to a vec3b_t structure that holds the raw acceleration data.
+ *	@param gforce		[out] Pointer to a gforce_t structure that will hold the gravity force data.
+ */
+void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce, int smooth) {
+	float xg, yg, zg;
+
+	/* find out how much it has to move to be 1g */
+	xg = (int)ac->cal_g.x;
+	yg = (int)ac->cal_g.y;
+	zg = (int)ac->cal_g.z;
+
+	/* find out how much it actually moved and normalize to +/- 1g */
+	gforce->a_vec.x = ((int)accel->x - (int)ac->cal_zero.x) / xg;
+	gforce->a_vec.y = ((int)accel->y - (int)ac->cal_zero.y) / yg;
+	gforce->a_vec.z = ((int)accel->z - (int)ac->cal_zero.z) / zg;
+	
+	if(smooth) {
+		apply_smoothing(gforce, ac->st_alpha);
+	}
+	else {
+		gforce->vec.x = gforce->a_vec.x;
+		gforce->vec.y = gforce->a_vec.y;
+		gforce->vec.z = gforce->a_vec.z;		
+	}
+}
+
+
+/**
+ *	@brief Calculate the angle and magnitude of a joystick.
+ *
+ *	@param js	[out] Pointer to a joystick_t structure.
+ *	@param x	The raw x-axis value.
+ *	@param y	The raw y-axis value.
+ */
+void calc_joystick_state(struct joystick_t* js, float x, float y) {
+	float rx, ry, ang;
+
+	/*
+	 *	Since the joystick center may not be exactly:
+	 *		(min + max) / 2
+	 *	Then the range from the min to the center and the center to the max
+	 *	may be different.
+	 *	Because of this, depending on if the current x or y value is greater
+	 *	or less than the assoicated axis center value, it needs to be interpolated
+	 *	between the center and the minimum or maxmimum rather than between
+	 *	the minimum and maximum.
+	 *
+	 *	So we have something like this:
+	 *		(x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max)
+	 *	Where the * is the current x value.
+	 *	The range is therefore -1 to 1, 0 being the exact center rather than
+	 *	the middle of min and max.
+	 */
+	if (x == js->center.x)
+		rx = 0;
+	else if (x >= js->center.x)
+		rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x));
+	else
+		rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f;
+
+	if (y == js->center.y)
+		ry = 0;
+	else if (y >= js->center.y)
+		ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y));
+	else
+		ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f;
+
+	/* calculate the joystick angle and magnitude */
+	ang = RAD_TO_DEGREE(atanf(ry / rx));
+	ang -= 90.0f;
+	if (rx < 0.0f)
+		ang -= 180.0f;
+	js->ang = absf(ang);
+	js->mag = (float) sqrt((rx * rx) + (ry * ry));
+}
+
+/**
+ *
+ * @brief Apply a smooth factor to accelerometer angles.
+ *
+ * @param accel		Last acceleration measured and normalized to +/-g.
+ * @param gforce	[out] gravity vector after smoothing
+ */
+void apply_smoothing(struct gforce_t* gforce, float alpha) {
+	
+	gforce->vec.x = alpha*gforce->vec.x + (1.0-alpha)*gforce->a_vec.x;
+	gforce->vec.y = alpha*gforce->vec.y + (1.0-alpha)*gforce->a_vec.y;
+	gforce->vec.z = alpha*gforce->vec.z + (1.0-alpha)*gforce->a_vec.z;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h	(revision 9780)
@@ -0,0 +1,59 @@
+/*
+ *    dynamics.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles the dynamics of the wiimote.
+ *
+ *	The file includes functions that handle the dynamics
+ *	of the wiimote.  Such dynamics include orientation and
+ *	motion sensing.
+ */
+
+#ifndef DYNAMICS_H_INCLUDED
+#define DYNAMICS_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void calculate_orientation(struct vec3f_t* in, struct ang3f_t* out);
+void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce, int smooth);
+void calc_joystick_state(struct joystick_t* js, float x, float y);
+void apply_smoothing(struct gforce_t* gforce, float alpha);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DYNAMICS_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/events.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/events.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/events.c	(revision 9780)
@@ -0,0 +1,941 @@
+/*
+ *    events.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles wiimote events.
+ *
+ *	The file includes functions that handle the events
+ *	that are sent from the wiimote to us.
+ */
+
+#include <stdio.h>
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "definitions.h"
+#include "io.h"
+#include "wiic_internal.h"
+#include "dynamics.h"
+#include "ir.h"
+#include "nunchuk.h"
+#include "classic.h"
+#include "guitar_hero_3.h"
+#include "events.h"
+
+static void idle_cycle(struct wiimote_t* wm);
+void clear_dirty_reads(struct wiimote_t* wm);
+void propagate_event(struct wiimote_t* wm, byte event, byte* msg);
+static void event_data_read(struct wiimote_t* wm, byte* msg);
+static void event_status(struct wiimote_t* wm, byte* msg);
+static void handle_expansion(struct wiimote_t* wm, byte* msg);
+
+static void save_state(struct wiimote_t* wm);
+static int state_changed(struct wiimote_t* wm);
+
+/**
+ *	@brief Poll the wiimotes for any events.
+ *
+ *	@param wm		An array of pointers to wiimote_t structures.
+ *	@param wiimotes	The number of wiimote_t structures in the \a wm array.
+ *
+ *	@return Returns number of wiimotes that an event has occured on.
+ *
+ *	It is necessary to poll the wiimote devices for events
+ *	that occur.  If an event occurs on a particular wiimote,
+ *	the event variable will be set.
+ */
+int wiic_poll(struct wiimote_t** wm, int wiimotes) {
+	int evnt = 0;
+
+	#if __APPLE__
+		/*
+		 *	MACOSX
+		 */
+		int i;
+		
+		if (!wm) return 0;
+
+		for (i = 0; i < wiimotes; ++i) {
+			wm[i]->event = WIIC_NONE;
+			if (wiic_io_read(wm[i])) {
+				/* propagate the event */
+				propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2); 
+				evnt += (wm[i]->event != WIIC_NONE);
+
+				/* clear out the event buffer */
+				memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf));
+			} else {
+				idle_cycle(wm[i]);
+			}	
+		}
+	#else
+		/*
+		 *	*nix
+		 */
+		struct timeval tv;
+		fd_set fds;
+		int r;
+		int i;
+		int highest_fd = -1;
+
+		if (!wm) return 0;
+
+		/* block select() for 1/2000th of a second */
+		tv.tv_sec = 0;
+		tv.tv_usec = 500;
+
+		FD_ZERO(&fds);
+
+		for (i = 0; i < wiimotes; ++i) {
+			/* only poll it if it is connected */
+			if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) {
+				FD_SET(wm[i]->in_sock, &fds);
+
+				/* find the highest fd of the connected wiimotes */
+				if (wm[i]->in_sock > highest_fd)
+					highest_fd = wm[i]->in_sock;
+			}
+
+			wm[i]->event = WIIC_NONE;
+		}
+
+		if (highest_fd == -1)
+			/* nothing to poll */
+			return 0;
+
+		if (select(highest_fd + 1, &fds, NULL, NULL, &tv) == -1) {
+			WIIC_ERROR("Unable to select() the wiimote interrupt socket(s).");
+			perror("Error Details");
+			return 0;
+		}
+
+		/* check each socket for an event */
+		for (i = 0; i < wiimotes; ++i) {
+			/* if this wiimote is not connected, skip it */
+			if (!WIIMOTE_IS_CONNECTED(wm[i]))
+				continue;
+
+			if (FD_ISSET(wm[i]->in_sock, &fds)) {
+				/* clear out the event buffer */
+				memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf));
+
+				/* clear out any old read requests */
+				clear_dirty_reads(wm[i]);
+
+				/* read the pending message into the buffer */
+				r = read(wm[i]->in_sock, wm[i]->event_buf, sizeof(wm[i]->event_buf));
+				if (r == -1) {
+					/* error reading data */
+					WIIC_ERROR("Receiving wiimote data (id %i).", wm[i]->unid);
+					perror("Error Details");
+
+					if (errno == ENOTCONN) {
+						/* this can happen if the bluetooth dongle is disconnected */
+						WIIC_ERROR("Bluetooth appears to be disconnected.  Wiimote unid %i will be disconnected.", wm[i]->unid);
+						wiic_disconnect(wm[i]);
+						wm[i]->event = WIIC_UNEXPECTED_DISCONNECT;
+					}
+
+					continue;
+				}
+				if (!r) {
+					/* remote disconnect */
+					wiic_disconnected(wm[i]);
+					evnt = 1;
+					continue;
+				}
+
+				/* propagate the event */
+				propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2);
+				evnt += (wm[i]->event != WIIC_NONE);
+			} else {
+				idle_cycle(wm[i]);
+			}
+		}
+	#endif
+
+	return evnt;
+}
+
+
+/**
+ *	@brief Called on a cycle where no significant change occurs.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ */
+static void idle_cycle(struct wiimote_t* wm) {
+	/*
+	 *	Smooth the angles.
+	 *
+	 *	This is done to make sure that on every cycle the orientation
+	 *	angles are smoothed.  Normally when an event occurs the angles
+	 *	are updated and smoothed, but if no packet comes in then the
+	 *	angles remain the same.  This means the angle WiiC reports
+	 *	is still an old value.  Smoothing needs to be applied in this
+	 *	case in order for the angle it reports to converge to the true
+	 *	angle of the device.
+	 */
+	if (WIIC_USING_ACC(wm) && WIIMOTE_IS_FLAG_SET(wm, WIIC_SMOOTHING)) {
+		apply_smoothing(&wm->gforce, wm->accel_calib.st_alpha);
+	}
+
+	/* clear out any old read requests */
+	clear_dirty_reads(wm);
+}
+
+
+/**
+ *	@brief Clear out all old 'dirty' read requests.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ */
+void clear_dirty_reads(struct wiimote_t* wm) {
+	struct read_req_t* req = wm->read_req;
+
+	while (req && req->dirty) {
+		WIIC_DEBUG("Cleared old read request for address: %x", req->addr);
+
+		wm->read_req = req->next;
+		free(req);
+		req = wm->read_req;
+	}
+}
+
+
+/**
+ *	@brief Analyze the event that occured on a wiimote.
+ *
+ *	@param wm		An array of pointers to wiimote_t structures.
+ *	@param event	The event that occured.
+ *	@param msg		The message specified in the event packet.
+ *
+ *	Pass the event to the registered event callback.
+ */
+void propagate_event(struct wiimote_t* wm, byte event, byte* msg) {
+	wiic_update_timestamp(wm);
+	save_state(wm);
+
+	switch (event) {
+		case WM_RPT_BTN:
+		{
+			/* button */
+			wiic_pressed_buttons(wm, msg);
+			break;
+		}
+		case WM_RPT_BTN_ACC:
+		{
+			/* button - motion */
+			wiic_pressed_buttons(wm, msg);
+
+			wm->accel.x = msg[2];
+			wm->accel.y = msg[3];
+			wm->accel.z = msg[4];
+
+			/* calculate the gforces on each axis */
+			calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce, WIIMOTE_IS_FLAG_SET(wm, WIIC_SMOOTHING));
+						
+			/* calculate the remote orientation */
+			calculate_orientation(&wm->gforce.vec, &wm->orient.angle);
+
+			break;
+		}
+		case WM_RPT_READ:
+		{
+			/* data read */
+			event_data_read(wm, msg);
+
+			/* yeah buttons may be pressed, but this wasn't an "event" */
+			return;
+		}
+		case WM_RPT_CTRL_STATUS:
+		{
+			/* controller status */
+			event_status(wm, msg);
+
+			/* don't execute the event callback */
+			return;
+		}
+		case WM_RPT_BTN_EXP:
+		{
+			/* button - expansion */
+			wiic_pressed_buttons(wm, msg);
+			handle_expansion(wm, msg+2);
+
+			break;
+		}
+		case WM_RPT_BTN_ACC_EXP:
+		{
+			/* button - motion - expansion */
+			wiic_pressed_buttons(wm, msg);
+
+			wm->accel.x = msg[2];
+			wm->accel.y = msg[3];
+			wm->accel.z = msg[4];
+
+			calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce, WIIMOTE_IS_FLAG_SET(wm, WIIC_SMOOTHING));
+			calculate_orientation(&wm->gforce.vec, &wm->orient.angle);
+
+			handle_expansion(wm, msg+5);
+
+			break;
+		}
+		case WM_RPT_BTN_ACC_IR:
+		{
+			/* button - motion - ir */
+			wiic_pressed_buttons(wm, msg);
+
+			wm->accel.x = msg[2];
+			wm->accel.y = msg[3];
+			wm->accel.z = msg[4];
+			
+			calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce, WIIMOTE_IS_FLAG_SET(wm, WIIC_SMOOTHING));
+			calculate_orientation(&wm->gforce.vec, &wm->orient.angle);
+
+			/* ir */
+			calculate_extended_ir(wm, msg+5);
+
+			break;
+		}
+		case WM_RPT_BTN_IR_EXP:
+		{
+			/* button - ir - expansion */
+			wiic_pressed_buttons(wm, msg);
+			handle_expansion(wm, msg+12);
+
+			/* ir */
+			calculate_basic_ir(wm, msg+2);
+
+			break;
+		}
+		case WM_RPT_BTN_ACC_IR_EXP:
+		{
+			/* button - motion - ir - expansion */
+			wiic_pressed_buttons(wm, msg);
+
+			wm->accel.x = msg[2];
+			wm->accel.y = msg[3];
+			wm->accel.z = msg[4];
+
+			calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce, WIIMOTE_IS_FLAG_SET(wm, WIIC_SMOOTHING));
+			calculate_orientation(&wm->gforce.vec, &wm->orient.angle);
+
+			handle_expansion(wm, msg+15);
+
+			/* ir */
+			calculate_basic_ir(wm, msg+5);
+
+			break;
+		}
+		case WM_RPT_WRITE:
+		{
+			/* write feedback - safe to skip */
+			break;
+		}
+		default:
+		{
+			WIIC_DEBUG("Unknown event, can not handle it [Code 0x%x].", event);
+			return;
+		}
+	}
+
+	/* was there an event? */
+	if (state_changed(wm))
+		wm->event = WIIC_EVENT;
+}
+
+
+/**
+ *	@brief Find what buttons are pressed.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void wiic_pressed_buttons(struct wiimote_t* wm, byte* msg) {
+	short now;
+
+	/* convert to big endian */
+	now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL;
+
+	/* pressed now & were pressed, then held */
+	/* 
+	 * FIXME - With motion sensing disabled and no other activities
+	 * it's impossible to state if a button is held, since no other 
+	 * report will be sent.
+	 */
+	wm->btns_held = (now & wm->btns);
+	
+	/* were pressed or were held & not pressed now, then released */
+	wm->btns_released = ((wm->btns | wm->btns_held) & ~now);
+
+	/* buttons pressed now */
+	wm->btns = now;
+}
+
+
+/**
+ *	@brief Received a data packet from a read request.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param msg		The message specified in the event packet.
+ *
+ *	Data from the wiimote comes in packets.  If the requested
+ *	data segment size is bigger than one packet can hold then
+ *	several packets will be received.  These packets are first
+ *	reassembled into one, then the registered callback function
+ *	that handles data reads is invoked.
+ */
+static void event_data_read(struct wiimote_t* wm, byte* msg) {
+	/* we must always assume the packet received is from the most recent request */
+	byte err;
+	byte len;
+	unsigned short offset;
+	struct read_req_t* req = wm->read_req;
+
+	wiic_pressed_buttons(wm, msg);
+
+	/* find the next non-dirty request */
+	while (req && req->dirty)
+		req = req->next;
+
+	/* if we don't have a request out then we didn't ask for this packet */
+	if (!req) {
+		WIIC_WARNING("Received data packet when no request was made.");
+		return;
+	}
+
+	err = msg[2] & 0x0F;
+
+	if (err == 0x08)
+		WIIC_WARNING("Unable to read data - address does not exist.");
+	else if (err == 0x07)
+		WIIC_WARNING("Unable to read data - address is for write-only registers.");
+	else if (err)
+		WIIC_WARNING("Unable to read data - unknown error code %x.", err);
+
+	if (err) {
+		/* this request errored out, so skip it and go to the next one */
+
+		/* delete this request */
+		wm->read_req = req->next;
+		free(req);
+
+		/* if another request exists send it to the wiimote */
+		if (wm->read_req)
+			wiic_send_next_pending_read_request(wm);
+
+		return;
+	}
+
+	len = ((msg[2] & 0xF0) >> 4) + 1;
+	offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3));
+	req->addr = (req->addr & 0xFFFF);
+
+	req->wait -= len;
+	if (req->wait >= req->size)
+		/* this should never happen */
+		req->wait = 0;
+
+	WIIC_DEBUG("Received read packet:");
+	WIIC_DEBUG("    Packet read offset:   %i bytes", offset);
+	WIIC_DEBUG("    Request read offset:  %i bytes", req->addr);
+	WIIC_DEBUG("    Read offset into buf: %i bytes", offset - req->addr);
+	WIIC_DEBUG("    Read data size:       %i bytes", len);
+	WIIC_DEBUG("    Still need:           %i bytes", req->wait);
+
+	/* reconstruct this part of the data */
+	memcpy((req->buf + offset - req->addr), (msg + 5), len);
+
+	#ifdef WITH_WIIC_DEBUG
+	{
+		int i = 0;
+		printf("Read: ");
+		for (; i < req->size - req->wait; ++i)
+			printf("%x ", req->buf[i]);
+		printf("\n");
+	}
+	#endif
+
+	/* if all data has been received, execute the read event callback or generate event */
+	if (!req->wait) {
+		if (req->cb) {
+			/* this was a callback, so invoke it now */
+			req->cb(wm, req->buf, req->size);
+
+			/* delete this request */
+			wm->read_req = req->next;
+			free(req);
+		} else {
+			/*
+			 *	This should generate an event.
+			 *	We need to leave the event in the array so the client
+			 *	can access it still.  We'll flag is as being 'dirty'
+			 *	and give the client one cycle to use it.  Next event
+			 *	we will remove it from the list.
+			 */
+			wm->event = WIIC_READ_DATA;
+			req->dirty = 1;
+		}
+
+		/* if another request exists send it to the wiimote */
+		if (wm->read_req)
+			wiic_send_next_pending_read_request(wm);
+	}
+}
+
+
+/**
+ *	@brief Read the controller status.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param msg		The message specified in the event packet.
+ *
+ *	Read the controller status and execute the registered status callback.
+ */
+static void event_status(struct wiimote_t* wm, byte* msg) {
+	int led[4] = {0};
+	int attachment = 0;
+	int ir = 0;
+	int exp_changed = 0;
+
+	/*
+	 *	An event occured.
+	 *	This event can be overwritten by a more specific
+	 *	event type during a handshake or expansion removal.
+	 */
+	wm->event = WIIC_STATUS;
+
+	wiic_pressed_buttons(wm, msg);
+
+	/* find what LEDs are lit */
+	if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_1)	led[0] = 1;
+	if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_2)	led[1] = 1;
+	if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_3)	led[2] = 1;
+	if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_4)	led[3] = 1;
+
+	/* is an attachment connected to the expansion port? */
+	if ((msg[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT)
+		attachment = 1;
+
+	/* is the speaker enabled? */
+	if ((msg[2] & WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) == WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED)
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER);
+
+	/* is IR sensing enabled? */
+	if ((msg[2] & WM_CTRL_STATUS_BYTE1_IR_ENABLED) == WM_CTRL_STATUS_BYTE1_IR_ENABLED)
+		ir = 1;
+
+	/* find the battery level and normalize between 0 and 1 */
+	wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE);
+
+	/* expansion port */
+	if (attachment && !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
+		/* send the initialization code for the attachment */
+		handshake_expansion(wm, NULL, 0);
+		exp_changed = 1;
+	} else if (!attachment && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
+		/* attachment removed */
+		disable_expansion(wm);
+		exp_changed = 1;
+	}
+
+	/*
+	 *	From now on the remote will only send status packets.
+	 *	We need to send a WIIMOTE_CMD_REPORT_TYPE packet to
+	 *	reenable other incoming reports.
+	 */
+	if (exp_changed && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
+		/*
+		 *	Since the expansion status changed IR needs to
+		 *	be reset for the new IR report mode.
+		 */
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+		wiic_set_ir(wm, 1);
+	} else 
+		wiic_set_report_type(wm);
+}
+
+
+/**
+ *	@brief Handle data from the expansion.
+ *
+ *	@param wm		A pointer to a wiimote_t structure.
+ *	@param msg		The message specified in the event packet for the expansion.
+ */
+static void handle_expansion(struct wiimote_t* wm, byte* msg) {
+	switch (wm->exp.type) {
+		case EXP_NUNCHUK:
+			nunchuk_event(&wm->exp.nunchuk, msg);
+			break;
+		case EXP_CLASSIC:
+			classic_ctrl_event(&wm->exp.classic, msg);
+			break;
+		case EXP_GUITAR_HERO_3:
+			guitar_hero_3_event(&wm->exp.gh3, msg);
+			break;
+		case EXP_MOTION_PLUS:
+			motion_plus_event(&wm->exp.mp, msg);
+			break;
+		case EXP_BALANCE_BOARD:
+			balance_board_event(&wm->exp.bb, msg);
+			break;
+		default:
+			break;
+	}
+}
+
+
+/**
+ *	@brief Handle the handshake data from the expansion device.
+ *
+ *	@param wm		A pointer to a wiimote_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	Tries to determine what kind of expansion was attached
+ *	and invoke the correct handshake function.
+ *
+ *	If the data is NULL then this function will try to start
+ *	a handshake with the expansion.
+ */
+void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len) {
+	int id;
+
+	if (!data) {
+		if(WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP) || WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP_FAILED) || WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP_HANDSHAKE))
+			return;
+
+		byte* handshake_buf;
+		byte buf = 0x00;
+
+		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+			disable_expansion(wm);
+
+		wiic_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1);
+
+		/* get the calibration data */
+		handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+		wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+		/* tell the wiimote to send expansion data */
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP);
+
+		return;
+	}
+
+	id = BIG_ENDIAN_LONG(*(int*)(data + 220));
+
+	/* call the corresponding handshake function for this expansion */
+	switch (id) {
+		case EXP_ID_CODE_NUNCHUK:
+		{
+			if (nunchuk_handshake(wm, &wm->exp.nunchuk, data, len))
+				wm->event = WIIC_NUNCHUK_INSERTED;
+			break;
+		}
+		case EXP_ID_CODE_CLASSIC_CONTROLLER:
+		{
+			if (classic_ctrl_handshake(wm, &wm->exp.classic, data, len))
+				wm->event = WIIC_CLASSIC_CTRL_INSERTED;
+			break;
+		}
+		case EXP_ID_CODE_GUITAR:
+		{
+			if (guitar_hero_3_handshake(wm, &wm->exp.gh3, data, len))
+				wm->event = WIIC_GUITAR_HERO_3_CTRL_INSERTED;
+			break;
+		}
+		case EXP_ID_BALANCE_BOARD:
+		{
+			if(balance_board_handshake(wm, &wm->exp.bb, data, len))
+				wm->event = WIIC_BALANCE_BOARD_INSERTED;
+			break;
+		}
+		default:
+		{
+			WIIC_WARNING("Unknown expansion type. Code: 0x%x", id);
+			break;
+		}
+	}
+
+	free(data);
+}
+
+
+
+/**
+ *	@brief Disable the expansion device if it was enabled.
+ *
+ *	@param wm		A pointer to a wiimote_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	If the data is NULL then this function will try to start
+ *	a handshake with the expansion.
+ */
+void disable_expansion(struct wiimote_t* wm) {
+	if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+		return;
+
+	/* tell the assoicated module the expansion was removed */
+	switch (wm->exp.type) {
+		case EXP_NUNCHUK:
+			nunchuk_disconnected(&wm->exp.nunchuk);
+			wm->event = WIIC_NUNCHUK_REMOVED;
+			break;
+		case EXP_CLASSIC:
+			classic_ctrl_disconnected(&wm->exp.classic);
+			wm->event = WIIC_CLASSIC_CTRL_REMOVED;
+			break;
+		case EXP_GUITAR_HERO_3:
+			guitar_hero_3_disconnected(&wm->exp.gh3);
+			wm->event = WIIC_GUITAR_HERO_3_CTRL_REMOVED;
+			break;
+		case EXP_MOTION_PLUS:
+	 		motion_plus_disconnected(&wm->exp.mp);
+	 		wm->event = WIIC_MOTION_PLUS_REMOVED;
+	 		break;
+		case EXP_BALANCE_BOARD:
+	 		balance_board_disconnected(&wm->exp.bb);
+	 		wm->event = WIIC_BALANCE_BOARD_REMOVED;
+	 		break;
+		default:
+			break;
+	}
+
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED);
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
+	wm->exp.type = EXP_NONE;
+}
+
+
+/**
+ *	@brief Save important state data.
+ *	@param wm	A pointer to a wiimote_t structure.
+ */
+static void save_state(struct wiimote_t* wm) {
+	/* wiimote */
+	wm->lstate.btns = wm->btns;
+	wm->lstate.accel = wm->accel;
+
+	/* ir */
+	if (WIIC_USING_IR(wm)) {
+		wm->lstate.ir_ax = wm->ir.ax;
+		wm->lstate.ir_ay = wm->ir.ay;
+		wm->lstate.ir_distance = wm->ir.distance;
+	}
+
+	/* expansion */
+	switch (wm->exp.type) {
+		case EXP_NUNCHUK:
+			wm->lstate.exp_ljs_ang = wm->exp.nunchuk.js.ang;
+			wm->lstate.exp_ljs_mag = wm->exp.nunchuk.js.mag;
+			wm->lstate.exp_btns = wm->exp.nunchuk.btns;
+			wm->lstate.exp_accel = wm->exp.nunchuk.accel;
+			break;
+
+		case EXP_CLASSIC:
+			wm->lstate.exp_ljs_ang = wm->exp.classic.ljs.ang;
+			wm->lstate.exp_ljs_mag = wm->exp.classic.ljs.mag;
+			wm->lstate.exp_rjs_ang = wm->exp.classic.rjs.ang;
+			wm->lstate.exp_rjs_mag = wm->exp.classic.rjs.mag;
+			wm->lstate.exp_r_shoulder = wm->exp.classic.r_shoulder;
+			wm->lstate.exp_l_shoulder = wm->exp.classic.l_shoulder;
+			wm->lstate.exp_btns = wm->exp.classic.btns;
+			break;
+
+		case EXP_GUITAR_HERO_3:
+			wm->lstate.exp_ljs_ang = wm->exp.gh3.js.ang;
+			wm->lstate.exp_ljs_mag = wm->exp.gh3.js.mag;
+			wm->lstate.exp_r_shoulder = wm->exp.gh3.whammy_bar;
+			wm->lstate.exp_btns = wm->exp.gh3.btns;
+			break;
+			
+		case EXP_MOTION_PLUS:
+			wm->lstate.mp_acc_mode = wm->exp.mp.acc_mode;
+			wm->lstate.mp_raw_gyro.roll = wm->exp.mp.raw_gyro.roll;
+			wm->lstate.mp_raw_gyro.pitch = wm->exp.mp.raw_gyro.pitch;
+			wm->lstate.mp_raw_gyro.yaw = wm->exp.mp.raw_gyro.yaw;
+			break;
+			
+		case EXP_BALANCE_BOARD:
+			wm->lstate.pressure_raw_data.top_left = wm->exp.bb.pressure_raw_data.top_left;
+			wm->lstate.pressure_raw_data.top_right = wm->exp.bb.pressure_raw_data.top_right;
+			wm->lstate.pressure_raw_data.bottom_left = wm->exp.bb.pressure_raw_data.bottom_left;
+			wm->lstate.pressure_raw_data.bottom_right = wm->exp.bb.pressure_raw_data.bottom_right;
+			break;
+
+		case EXP_NONE:
+			break;
+	}
+}
+
+
+/**
+ *	@brief Determine if the current state differs significantly from the previous.
+ *	@param wm	A pointer to a wiimote_t structure.
+ *	@return	1 if a significant change occured, 0 if not.
+ */
+static int state_changed(struct wiimote_t* wm) {
+	#define STATE_CHANGED(a, b)		if (a != b)				return 1
+
+	#define CROSS_THRESH(last, now, thresh)										\
+				do {															\
+					if (WIIMOTE_IS_FLAG_SET(wm, WIIC_ORIENT_THRESH)) {		\
+						if ((diff_f(last.roll, now.roll) >= thresh) ||			\
+							(diff_f(last.pitch, now.pitch) >= thresh) ||		\
+							(diff_f(last.yaw, now.yaw) >= thresh))				\
+						{														\
+							last = now;											\
+							return 1;											\
+						}														\
+					} else {													\
+						if (last.roll != now.roll)		return 1;				\
+						if (last.pitch != now.pitch)	return 1;				\
+						if (last.yaw != now.yaw)		return 1;				\
+					}															\
+				} while (0)
+
+	#define CROSS_THRESH_XYZ(last, now, thresh)									\
+				do {															\
+					if (WIIMOTE_IS_FLAG_SET(wm, WIIC_ORIENT_THRESH)) {		\
+						if ((diff_f(last.x, now.x) >= thresh) ||				\
+							(diff_f(last.y, now.y) >= thresh) ||				\
+							(diff_f(last.z, now.z) >= thresh))					\
+						{														\
+							last = now;											\
+							return 1;											\
+						}														\
+					} else {													\
+						if (last.x != now.x)		return 1;					\
+						if (last.y != now.y)		return 1;					\
+						if (last.z != now.z)		return 1;					\
+					}															\
+				} while (0)
+
+	#define CROSS_THRESH_RATE(last, now, thresh)								\
+				do {															\
+					if (WIIMOTE_IS_FLAG_SET(wm, WIIC_ORIENT_THRESH)) {		\
+						if ((diff_f(last.roll, now.roll) >= thresh) ||				\
+							(diff_f(last.pitch, now.pitch) >= thresh) ||				\
+							(diff_f(last.yaw, now.yaw) >= thresh))					\
+						{														\
+							last = now;											\
+							return 1;											\
+						}														\
+					} else {													\
+						if (last.roll != now.roll)		return 1;					\
+						if (last.pitch != now.pitch)		return 1;					\
+						if (last.yaw != now.yaw)		return 1;					\
+					}															\
+				} while (0)
+				
+	/* ir */
+	if (WIIC_USING_IR(wm)) {
+		STATE_CHANGED(wm->lstate.ir_ax, wm->ir.ax);
+		STATE_CHANGED(wm->lstate.ir_ay, wm->ir.ay);
+		STATE_CHANGED(wm->lstate.ir_distance, wm->ir.distance);
+	}
+
+	/* accelerometer */
+	if (WIIC_USING_ACC(wm)) {
+		/* raw accelerometer */
+		CROSS_THRESH_XYZ(wm->lstate.accel, wm->accel, wm->accel_threshold);
+
+		/* orientation */
+ 		CROSS_THRESH(wm->lstate.orient.angle, wm->orient.angle, wm->orient_threshold);
+	}
+
+	/* expansion */
+	switch (wm->exp.type) {
+		case EXP_NUNCHUK:
+		{
+			STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.nunchuk.js.ang);
+			STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.nunchuk.js.mag);
+			STATE_CHANGED(wm->lstate.exp_btns, wm->exp.nunchuk.btns);
+
+			CROSS_THRESH(wm->lstate.exp_orient.angle, wm->exp.nunchuk.orient.angle, wm->exp.nunchuk.orient_threshold);
+			CROSS_THRESH_XYZ(wm->lstate.exp_accel, wm->exp.nunchuk.accel, wm->exp.nunchuk.accel_threshold);
+			break;
+		}
+		case EXP_CLASSIC:
+		{
+			STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.classic.ljs.ang);
+			STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.classic.ljs.mag);
+			STATE_CHANGED(wm->lstate.exp_rjs_ang, wm->exp.classic.rjs.ang);
+			STATE_CHANGED(wm->lstate.exp_rjs_mag, wm->exp.classic.rjs.mag);
+			STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.classic.r_shoulder);
+			STATE_CHANGED(wm->lstate.exp_l_shoulder, wm->exp.classic.l_shoulder);
+			STATE_CHANGED(wm->lstate.exp_btns, wm->exp.classic.btns);
+			break;
+		}
+		case EXP_GUITAR_HERO_3:
+		{
+			STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.gh3.js.ang);
+			STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.gh3.js.mag);
+			STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.gh3.whammy_bar);
+			STATE_CHANGED(wm->lstate.exp_btns, wm->exp.gh3.btns);
+			break;
+		}
+		case EXP_MOTION_PLUS:
+		{
+			/* acceleration mode */
+			STATE_CHANGED(wm->lstate.mp_acc_mode, wm->exp.mp.acc_mode);
+
+			/* raw gyro rate */
+ 			CROSS_THRESH_RATE(wm->lstate.mp_raw_gyro, wm->exp.mp.raw_gyro, wm->exp.mp.raw_gyro_threshold);
+			break;
+		}
+		case EXP_BALANCE_BOARD:
+		{
+			/* balance board */
+			STATE_CHANGED(wm->lstate.pressure_raw_data.top_left,wm->exp.bb.pressure_raw_data.top_left);
+			STATE_CHANGED(wm->lstate.pressure_raw_data.top_right,wm->exp.bb.pressure_raw_data.top_right);
+			STATE_CHANGED(wm->lstate.pressure_raw_data.bottom_left,wm->exp.bb.pressure_raw_data.bottom_left);
+			STATE_CHANGED(wm->lstate.pressure_raw_data.bottom_right,wm->exp.bb.pressure_raw_data.bottom_right);
+			break;
+		}	
+		case EXP_NONE:
+		{
+			break;
+		}
+	}
+
+	STATE_CHANGED(wm->lstate.btns, wm->btns);
+
+	return 0;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/events.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/events.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/events.h	(revision 9780)
@@ -0,0 +1,57 @@
+/*
+ *    events.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles wiimote events.
+ *
+ *	The file includes functions that handle the events
+ *	that are sent from the wiimote to us.
+ */
+
+#ifndef EVENTS_H_INCLUDED
+#define EVENTS_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wiic_pressed_buttons(struct wiimote_t* wm, byte* msg);
+
+void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len);
+void disable_expansion(struct wiimote_t* wm);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // EVENTS_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c	(revision 9780)
@@ -0,0 +1,168 @@
+/*
+ *    guitar_hero_3.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Guitar Hero 3 expansion device.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "guitar_hero_3.h"
+
+static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now);
+
+/**
+ *	@brief Handle the handshake data from the guitar.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	@return	Returns 1 if handshake was successful, 0 if not.
+ */
+int guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len) {
+	int i;
+	int offset = 0;
+
+	/*
+	 *	The good fellows that made the Guitar Hero 3 controller
+	 *	failed to factory calibrate the devices.  There is no
+	 *	calibration data on the device.
+	 */
+
+	gh3->btns = 0;
+	gh3->btns_held = 0;
+	gh3->btns_released = 0;
+	gh3->whammy_bar = 0.0f;
+
+	/* decrypt data */
+	for (i = 0; i < len; ++i)
+		data[i] = (data[i] ^ 0x17) + 0x17;
+
+	if (data[offset] == 0xFF) {
+		/*
+		 *	Sometimes the data returned here is not correct.
+		 *	This might happen because the wiimote is lagging
+		 *	behind our initialization sequence.
+		 *	To fix this just request the handshake again.
+		 *
+		 *	Other times it's just the first 16 bytes are 0xFF,
+		 *	but since the next 16 bytes are the same, just use
+		 *	those.
+		 */
+		if (data[offset + 16] == 0xFF) {
+			/* get the calibration data */
+			byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+			WIIC_DEBUG("Guitar Hero 3 handshake appears invalid, trying again.");
+			wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+			return 0;
+		} else
+			offset += 16;
+	}
+
+	/* joystick stuff */
+	gh3->js.max.x = GUITAR_HERO_3_JS_MAX_X;
+	gh3->js.min.x = GUITAR_HERO_3_JS_MIN_X;
+	gh3->js.center.x = GUITAR_HERO_3_JS_CENTER_X;
+	gh3->js.max.y = GUITAR_HERO_3_JS_MAX_Y;
+	gh3->js.min.y = GUITAR_HERO_3_JS_MIN_Y;
+	gh3->js.center.y = GUITAR_HERO_3_JS_CENTER_Y;
+
+	/* handshake done */
+	wm->exp.type = EXP_GUITAR_HERO_3;
+
+	return 1;
+}
+
+
+/**
+ *	@brief The guitar disconnected.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ */
+void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3) {
+	memset(gh3, 0, sizeof(struct guitar_hero_3_t));
+}
+
+
+
+/**
+ *	@brief Handle guitar event.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg) {
+	int i;
+
+	/* decrypt data */
+	for (i = 0; i < 6; ++i)
+		msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+	guitar_hero_3_pressed_buttons(gh3, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+
+	/* whammy bar */
+	gh3->whammy_bar = (msg[3] - GUITAR_HERO_3_WHAMMY_BAR_MIN) / (float)(GUITAR_HERO_3_WHAMMY_BAR_MAX - GUITAR_HERO_3_WHAMMY_BAR_MIN);
+
+	/* joy stick */
+	calc_joystick_state(&gh3->js, msg[0], msg[1]);
+}
+
+
+/**
+ *	@brief Find what buttons are pressed.
+ *
+ *	@param cc		A pointer to a classic_ctrl_t structure.
+ *	@param msg		The message byte specified in the event packet.
+ */
+static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now) {
+	/* message is inverted (0 is active, 1 is inactive) */
+	now = ~now & GUITAR_HERO_3_BUTTON_ALL;
+
+	/* pressed now & were pressed, then held */
+	gh3->btns_held = (now & gh3->btns);
+
+	/* were pressed or were held & not pressed now, then released */
+	gh3->btns_released = ((gh3->btns | gh3->btns_held) & ~now);
+
+	/* buttons pressed now */
+	gh3->btns = now;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h	(revision 9780)
@@ -0,0 +1,65 @@
+/*
+ *    guitar_hero_3.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Guitar Hero 3 expansion device.
+ */
+
+#ifndef GUITAR_HERO_3_H_INCLUDED
+#define GUITAR_HERO_3_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#define GUITAR_HERO_3_JS_MIN_X				0xC5
+#define GUITAR_HERO_3_JS_MAX_X				0xFC
+#define GUITAR_HERO_3_JS_CENTER_X			0xE0
+#define GUITAR_HERO_3_JS_MIN_Y				0xC5
+#define GUITAR_HERO_3_JS_MAX_Y				0xFA
+#define GUITAR_HERO_3_JS_CENTER_Y			0xE0
+#define GUITAR_HERO_3_WHAMMY_BAR_MIN		0xEF
+#define GUITAR_HERO_3_WHAMMY_BAR_MAX		0xFA
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len);
+
+void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3);
+
+void guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GUITAR_HERO_3_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/io.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io.c	(revision 9780)
@@ -0,0 +1,122 @@
+/*
+ *    io.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles device I/O (non-OS specific).
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "io.h"
+
+
+ /**
+ *	@brief Get initialization data from the wiimote.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param data		unused
+ *	@param len		unused
+ *
+ *	When first called for a wiimote_t structure, a request
+ *	is sent to the wiimote for initialization information.
+ *	This includes factory set accelerometer data.
+ *	The handshake will be concluded when the wiimote responds
+ *	with this data.
+ */
+void wiic_handshake(struct wiimote_t* wm, byte* data, unsigned short len) {
+	if (!wm)	return;
+
+	switch (wm->handshake_state) {
+		case 0:
+		{
+			/* send request to wiimote for accelerometer calibration */
+			byte* buf;
+
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+			wiic_set_leds(wm, WIIMOTE_LED_NONE);
+
+			buf = (byte*)malloc(sizeof(byte) * 8);
+			wiic_read_data_cb(wm, wiic_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
+			wm->handshake_state++;
+
+			wiic_set_leds(wm, WIIMOTE_LED_NONE);
+
+			break;
+		}
+		case 1:
+		{
+			struct read_req_t* req = wm->read_req;
+			struct accel_t* accel = &wm->accel_calib;
+
+			/* received read data */
+			accel->cal_zero.x = req->buf[0];
+			accel->cal_zero.y = req->buf[1];
+			accel->cal_zero.z = req->buf[2];
+
+			accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
+			accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
+			accel->cal_g.z = req->buf[6] - accel->cal_zero.z;
+
+			/* done with the buffer */
+			free(req->buf);
+
+			/* handshake is done */
+			WIIC_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
+					accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
+					accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);
+
+
+			/* request the status of the wiimote to see if there is an expansion */
+			wiic_status(wm);
+
+			WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
+			wm->handshake_state++;
+
+			/* now enable IR if it was set before the handshake completed */
+			if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
+				WIIC_DEBUG("Handshake finished, enabling IR.");
+				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+				wiic_set_ir(wm, 1);
+			}
+
+			break;
+		}
+		default:
+		{
+			break;
+		}
+	}
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/io.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io.h	(revision 9780)
@@ -0,0 +1,59 @@
+/*
+ *    io.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles device I/O.
+ */
+
+#ifndef CONNECT_H_INCLUDED
+#define CONNECT_H_INCLUDED
+
+#ifdef LINUX
+#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/bluetooth.h"
+#endif
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wiic_handshake(struct wiimote_t* wm, byte* data, unsigned short len);
+
+int wiic_io_read(struct wiimote_t* wm);
+int wiic_io_write(struct wiimote_t* wm, byte* buf, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CONNECT_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h	(revision 9780)
@@ -0,0 +1,107 @@
+/*
+ *	io_mac.h
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief I/O header file for MacOS.
+ */
+#ifndef IO_MAC_H
+#define IO_MAC_H
+
+#import <stdio.h>
+#import <stdlib.h>
+#import <unistd.h>
+
+#define BLUETOOTH_VERSION_USE_CURRENT 
+
+#import <arpa/inet.h>				/* htons() */
+#import <IOBluetooth/IOBluetoothUtilities.h>
+#import <IOBluetooth/objc/IOBluetoothDevice.h>
+#import <IOBluetooth/objc/IOBluetoothHostController.h>
+#import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h>
+#import <IOBluetooth/objc/IOBluetoothL2CAPChannel.h>
+
+#import "wiic_internal.h"
+#import "io.h"
+
+@interface WiiSearch : NSObject
+{
+	IOBluetoothDeviceInquiry* inquiry;
+	BOOL isDiscovering;
+	// Number of found wiimotes
+	int foundWiimotes;
+	// Maximum number of wiimotes to be searched
+	int maxWiimotes;
+	// The Wiimotes structure
+	wiimote** wiimotes;
+}
+
+- (BOOL) isDiscovering;
+- (void) setDiscovering:(BOOL) flag;
+- (void) setWiimoteStruct:(wiimote**) wiimote_struct;
+- (int) getFoundWiimotes;
+- (IOReturn) start:(unsigned int) timeout maxWiimotes:(unsigned int) wiimotesNum;
+- (IOReturn) stop;
+- (IOReturn) close;
+- (void) retrieveWiimoteInfo:(IOBluetoothDevice*) device;
+- (void) deviceInquiryStarted:(IOBluetoothDeviceInquiry*) sender;
+- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) sender device:(IOBluetoothDevice *) device;
+- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*) sender error:(IOReturn) error aborted:(BOOL) aborted;
+
+@end
+
+@interface WiiConnect : NSObject
+{
+	// Buffer to store incoming data from the Wiimote
+	NSData* receivedMsg;
+	unsigned int msgLength;
+	
+	// Reference to the relative wiimote struct (used only to complete handshaking)
+	wiimote* _wm;
+	BOOL isReading;
+	BOOL timeout;
+	BOOL disconnecting;
+}
+
+- (IOBluetoothL2CAPChannel *) openL2CAPChannelWithPSM:(BluetoothL2CAPPSM) psm device:(IOBluetoothDevice*) device delegate:(id) delegate;
+- (IOReturn) connectToWiimote:(wiimote*) wm;
+- (void) l2capChannelData:(IOBluetoothL2CAPChannel*) channel data:(byte *) data length:(NSUInteger) length;
+- (byte*) getNextMsg;
+- (unsigned int) getMsgLength;
+- (void) deleteMsg;
+- (void) disconnected:(IOBluetoothUserNotification*) notification fromDevice:(IOBluetoothDevice*) device;
+- (BOOL) isReading;
+- (void) setReading:(BOOL) flag;
+- (BOOL) isTimeout;
+- (void) setTimeout:(BOOL) flag;
+- (void) startTimerThread;
+- (void) wakeUpMainThreadRunloop:(id)arg;
+- (BOOL) isDisconnecting;
+@end
+
+#endif /* IO_MAC_H */
Index: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m	(revision 9780)
@@ -0,0 +1,765 @@
+/*
+ *	io_mac.m
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Handles device I/O for Mac.
+ */
+#ifdef __APPLE__
+
+#import "io_mac.h"
+
+// Used just to retrieve max num of wiimotes in handler functions
+static int max_num_wiimotes = 0;
+
+@implementation WiiSearch
+
+#pragma mark -
+#pragma mark WiiSearch
+- (id) init
+{
+	self = [super init];
+	foundWiimotes = 0;
+	isDiscovering = NO;
+	if (self != nil) { 
+		/* 
+		 * Calling IOBluetoothLocalDeviceAvailable has two advantages:
+		 * 1. it sets up a event source in the run loop (bug for C version of the bluetooth api)
+		 * 2. it checks for the availability of the BT hardware
+		 */
+		if (![IOBluetoothHostController defaultController])
+		{
+			[self release];
+			self = nil;
+		}		
+	}
+
+	return self;
+}
+
+- (void) dealloc
+{	
+	inquiry = 0;
+	WIIC_DEBUG("Wiimote Discovery released");
+	[super dealloc];
+}
+
+- (BOOL) isDiscovering
+{
+	return isDiscovering;
+}
+
+- (void) setDiscovering:(BOOL) flag
+{
+	isDiscovering = flag;
+}
+
+- (void) setWiimoteStruct:(wiimote**) wiimote_struct
+{
+	wiimotes = wiimote_struct;
+}
+
+- (int) getFoundWiimotes
+{
+	return foundWiimotes;
+}
+
+- (IOReturn) start:(unsigned int) timeout maxWiimotes:(unsigned int) wiimotesNum
+{
+	if (![IOBluetoothHostController defaultController]) {
+		WIIC_ERROR("Unable to find any bluetooth receiver on your host.");
+		return kIOReturnNotAttached;
+	}
+	
+	// If we are currently discovering, we can't start a new discovery right now.
+	if ([self isDiscovering]) {
+		WIIC_INFO("Wiimote search is already in progress...");
+		return kIOReturnSuccess;
+	}
+	
+	[self close];
+	maxWiimotes = wiimotesNum;
+	foundWiimotes = 0;
+
+	inquiry = [IOBluetoothDeviceInquiry inquiryWithDelegate:self];
+	// We set the search timeout
+	if(timeout == 0)
+		[inquiry setInquiryLength:5];
+	else if(timeout < 20)
+		[inquiry setInquiryLength:timeout];
+	else
+		[inquiry setInquiryLength:20];
+	[inquiry setSearchCriteria:kBluetoothServiceClassMajorAny majorDeviceClass:WM_DEV_MAJOR_CLASS minorDeviceClass:WM_DEV_MINOR_CLASS];
+	[inquiry setUpdateNewDeviceNames:NO];
+
+	IOReturn status = [inquiry start];
+	if (status == kIOReturnSuccess) {
+		[inquiry retain];
+	} else {
+		[self close];
+		WIIC_ERROR("Unable to search for bluetooth devices.");
+	}
+	
+	return status;
+}
+
+- (IOReturn) stop
+{
+	return [inquiry stop];
+}
+
+- (IOReturn) close
+{
+	IOReturn ret = kIOReturnSuccess;
+	
+	ret = [inquiry stop];
+	[inquiry release];
+	inquiry = nil;
+	
+	WIIC_DEBUG(@"Discovery closed");
+	return ret;
+}
+
+#pragma mark -
+#pragma mark IOBluetoothDeviceInquiry delegates
+//*************** HANDLERS FOR WIIC_FIND FOR MACOSX *******************/
+- (void) retrieveWiimoteInfo:(IOBluetoothDevice*) device
+{	
+	// We set the device reference (we must retain it to use it after the search)
+	wiimotes[foundWiimotes]->device = [[device retain] getDeviceRef];
+	wiimotes[foundWiimotes]->address = (CFStringRef)[[device getAddressString] retain];
+	
+	// C String (common for Mac and Linux)
+	CFStringGetCString(wiimotes[foundWiimotes]->address,wiimotes[foundWiimotes]->bdaddr_str,18,kCFStringEncodingMacRoman);
+	
+	WIIMOTE_ENABLE_STATE(wiimotes[foundWiimotes], WIIMOTE_STATE_DEV_FOUND);
+	WIIC_INFO("Found Wiimote (%s) [id %i].",CFStringGetCStringPtr(wiimotes[foundWiimotes]->address, kCFStringEncodingMacRoman),wiimotes[foundWiimotes]->unid);
+	++foundWiimotes;
+}
+
+- (void) deviceInquiryStarted:(IOBluetoothDeviceInquiry*) sender
+{
+	[self setDiscovering:YES];
+}
+
+- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) sender device:(IOBluetoothDevice *) device
+{
+	if(foundWiimotes < maxWiimotes)
+		[self retrieveWiimoteInfo:device];
+	else
+		[inquiry stop];
+}
+
+- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*) sender error:(IOReturn) error aborted:(BOOL) aborted
+{	
+	// The inquiry has completed, we can now process what we have found
+	[self setDiscovering:NO];
+
+	// We stop the search because of errors
+	if ((error != kIOReturnSuccess) && !aborted) {
+		foundWiimotes = 0;
+		[self close];
+		WIIC_ERROR("Search not completed, because of unexpected errors. This error can be due to a short search timeout.");
+		return;
+	}
+	
+	foundWiimotes = [[inquiry foundDevices] count];
+}
+
+@end
+
+@implementation WiiConnect
+#pragma mark -
+#pragma mark WiiConnect
+- (id) init
+{
+	self = [super init];
+	receivedMsg = [[NSData alloc] init];
+	msgLength = 0;
+	_wm = 0;
+	isReading = NO;
+	timeout = NO;
+	disconnecting = NO;
+	return self;
+}
+
+- (void) dealloc
+{	
+	WIIC_DEBUG("Wiimote released");
+	if(receivedMsg)
+		[receivedMsg release];
+	receivedMsg = 0;
+	_wm = 0;
+	[super dealloc];
+}
+
+- (byte*) getNextMsg
+{
+	if(!receivedMsg)
+		return 0;
+
+	return (byte*)[receivedMsg bytes];
+}
+
+- (void) deleteMsg
+{
+	if(receivedMsg) {
+		[receivedMsg release];
+		msgLength = 0;
+	}
+}
+
+- (BOOL) isDisconnecting
+{
+	return disconnecting;
+}
+
+- (BOOL) isReading
+{
+	return isReading;
+}
+
+- (void) setReading:(BOOL) flag
+{
+	isReading = flag;
+}
+
+- (BOOL) isTimeout
+{
+	return timeout;
+}
+
+- (void) setTimeout:(BOOL) flag
+{
+	timeout = flag;
+}
+
+- (void) startTimerThread
+{
+	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+	
+	// Timer 
+	sleep(1);
+	
+	[pool drain];
+}
+
+- (void) wakeUpMainThreadRunloop:(id)arg
+{
+    // This method is executed on main thread!
+    // It doesn't need to do anything actually, just having it run will
+    // make sure the main thread stops running the runloop
+}
+
+
+- (IOBluetoothL2CAPChannel*) openL2CAPChannelWithPSM:(BluetoothL2CAPPSM) psm device:(IOBluetoothDevice*) device delegate:(id) delegate
+{
+	IOBluetoothL2CAPChannel* channel = nil;
+	
+	if ([device openL2CAPChannelSync:&channel withPSM:psm delegate:delegate] != kIOReturnSuccess) 
+		channel = nil;
+	
+	return channel;
+}
+
+- (IOReturn) connectToWiimote:(wiimote*) wm
+{
+	IOBluetoothDevice* device = [IOBluetoothDevice withDeviceRef:wm->device];
+	IOBluetoothL2CAPChannel* outCh = nil;
+	IOBluetoothL2CAPChannel* inCh = nil;
+	
+	if(!device) {
+		WIIC_ERROR("Non existent device or already connected.");
+		return kIOReturnBadArgument;
+	}
+	
+	outCh = [self openL2CAPChannelWithPSM:WM_OUTPUT_CHANNEL device:device delegate:self];
+	if (!outCh) {
+		WIIC_ERROR("Unable to open L2CAP output channel (id %i).", wm->unid);
+		[device closeConnection];
+		return kIOReturnNotOpen;
+	}
+	wm->outputCh = [[outCh retain] getL2CAPChannelRef];
+	usleep(20000);
+	
+	inCh = [self openL2CAPChannelWithPSM:WM_INPUT_CHANNEL device:device delegate:self];
+	if (!inCh) {
+		WIIC_ERROR("Unable to open L2CAP input channel (id %i).", wm->unid);
+		[device closeConnection];
+		return kIOReturnNotOpen;
+	}
+	wm->inputCh = [[inCh retain] getL2CAPChannelRef];
+	usleep(20000);
+	
+	IOBluetoothUserNotification* disconnectNotification = [device registerForDisconnectNotification:self selector:@selector(disconnected:fromDevice:)];
+	if(!disconnectNotification) {
+		WIIC_ERROR("Unable to register disconnection handler (id %i).", wm->unid);
+		[device closeConnection];
+		return kIOReturnNotOpen;
+	}
+	
+	// We store the reference to its relative structure (Used for completing the handshake step)
+	_wm = wm;
+	
+	return kIOReturnSuccess;
+}
+
+#pragma mark -
+#pragma mark IOBluetoothL2CAPChannel delegates
+- (void) disconnected:(IOBluetoothUserNotification*) notification fromDevice:(IOBluetoothDevice*) device
+{
+	[self deleteMsg];
+	[self setReading:NO];
+	disconnecting = YES;
+		
+	// The wiimote_t struct must be re-initialized due to the disconnection
+	wiic_disconnected(_wm) ;	
+}
+
+//*************** HANDLERS FOR WIIC_IO_READ FOR MACOSX *******************/
+- (void) l2capChannelData:(IOBluetoothL2CAPChannel*) channel data:(byte *) data length:(NSUInteger) length 
+{
+	// This is done in case the output channel woke up this handler
+	if(!data) {
+	    [self setReading:NO];
+		length = 0;
+		return;
+	}
+
+	/* 
+	 * This is called if we are receiving data before completing
+	 * the handshaking, hence before calling wiic_poll
+	 */
+	if(WIIMOTE_IS_SET(_wm, WIIMOTE_STATE_HANDSHAKE))
+		propagate_event(_wm, data[1], data+2);
+
+	receivedMsg = [[NSData dataWithBytes:data length:length] retain]; 
+	msgLength = length;
+	
+    // This is done when a message is successfully received. Stop the main loop after reading
+    [self setReading:NO];
+}
+
+- (unsigned int) getMsgLength
+{
+	return msgLength;
+}
+
+- (void) l2capChannelReconfigured:(IOBluetoothL2CAPChannel*) l2capChannel
+{
+      //NSLog(@"l2capChannelReconfigured");
+}
+
+- (void) l2capChannelWriteComplete:(IOBluetoothL2CAPChannel*) l2capChannel refcon:(void*) refcon status:(IOReturn) error
+{
+      //NSLog(@"l2capChannelWriteComplete");
+}
+
+- (void) l2capChannelQueueSpaceAvailable:(IOBluetoothL2CAPChannel*) l2capChannel
+{
+      //NSLog(@"l2capChannelQueueSpaceAvailable");
+}
+
+- (void) l2capChannelOpenComplete:(IOBluetoothL2CAPChannel*) l2capChannel status:(IOReturn) error
+{
+	//NSLog(@"l2capChannelOpenComplete (PSM:0x%x)", [l2capChannel getPSM]);
+}
+
+
+@end
+
+#pragma mark -
+#pragma mark Wiiuse
+/**
+ *	@brief Find a wiimote or wiimotes.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *	@param max_wiimotes	The number of wiimote structures in \a wm.
+ *	@param timeout		The number of seconds before the search times out.
+ *
+ *	@return The number of wiimotes found.
+ *
+ *	@see wiimote_connect()
+ *
+ *	This function will only look for wiimote devices.						\n
+ *	When a device is found the address in the structures will be set.		\n
+ *	You can then call wiimote_connect() to connect to the found				\n
+ *	devices.
+ */
+int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout) 
+{
+	int found_wiimotes = 0;
+
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+	WiiSearch* search = [[WiiSearch alloc] init];
+	[search setWiimoteStruct:wm];
+	
+	if(timeout) { // Single search
+		[search start:timeout maxWiimotes:max_wiimotes];
+	
+		NSRunLoop *theRL = [NSRunLoop currentRunLoop];
+		while ([search isDiscovering] && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
+	
+		found_wiimotes = [search getFoundWiimotes];
+	}
+	else { // Unlimited search
+		found_wiimotes = 0;
+		while(!found_wiimotes) {
+			[search start:timeout maxWiimotes:max_wiimotes];
+	
+			NSRunLoop *theRL = [NSRunLoop currentRunLoop];
+			while ([search isDiscovering] && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
+	
+			found_wiimotes = [search getFoundWiimotes];	
+		}
+	}
+	
+	WIIC_INFO("Found %i Wiimote device(s).", found_wiimotes);
+	
+	[search release];
+	[pool drain];
+	
+	return found_wiimotes;
+}
+
+
+//*************** HANDLERS FOR WIIC_DISCONNECT FOR MACOSX *******************/
+/**
+ *	@brief Disconnect a wiimote.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *
+ *	@see wiic_connect()
+ *
+ *	Note that this will not free the wiimote structure.
+ */
+void wiic_disconnect(struct wiimote_t* wm) 
+{
+	IOReturn error;
+
+    if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+            return;
+
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+	// Input Channel
+	if(wm->inputCh) {
+		IOBluetoothL2CAPChannel* inCh = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->inputCh];
+		error = [inCh closeChannel];
+		[inCh setDelegate:nil];
+		if(error != kIOReturnSuccess) 
+			WIIC_ERROR("Unable to close input channel (id %i).", wm->unid);			
+		usleep(10000);
+		[inCh release];
+		inCh = nil;
+		wm->inputCh = 0;
+	}
+	
+	// Output Channel
+	if(wm->outputCh) {
+		IOBluetoothL2CAPChannel* outCh = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->outputCh];
+		error = [outCh closeChannel];
+		[outCh setDelegate:nil];
+		if(error != kIOReturnSuccess) 
+			WIIC_ERROR("Unable to close output channel (id %i).", wm->unid);			
+		usleep(10000);
+		[outCh release];
+		outCh = nil;
+		wm->outputCh = 0;
+	}
+	
+	// Device
+	if(wm->device) {
+		IOBluetoothDevice* device = [IOBluetoothDevice withDeviceRef:wm->device];
+		error = [device closeConnection];
+
+		if(error != kIOReturnSuccess) 
+			WIIC_ERROR("Unable to close the device connection (id %i).", wm->unid);			
+		usleep(10000);
+		[device release];
+		device = nil;
+		wm->device = 0;
+	}
+	
+	[pool drain];
+	
+	wm->event = WIIC_NONE;
+
+    WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+    WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+}
+
+/**
+ *	@brief Connect to a wiimote with a known address.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param address	The address of the device to connect to.
+ *					If NULL, use the address in the struct set by wiic_find().
+ *  @param autoreconnect	Re-connects the device in case of unexpected disconnection.
+ *
+ *	@return 1 on success, 0 on failure
+ */
+int wiic_connect_single(struct wiimote_t* wm, char* address, int autoreconnect) 
+{
+	// Skip if already connected or device not found
+	if(!wm || WIIMOTE_IS_CONNECTED(wm) || wm->device == 0) {
+		WIIC_ERROR("Non existent device or already connected.");
+		return 0;	
+	}
+
+	// Convert the IP address
+	// FIXME - see if it is possible
+
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+	WiiConnect* connect = [[[WiiConnect alloc] init] autorelease];
+	if([connect connectToWiimote:wm] == kIOReturnSuccess) {
+		WIIC_INFO("Connected to wiimote [id %i].", wm->unid);
+		// This is stored to retrieve incoming data
+		wm->connectionHandler = (void*)([connect retain]);
+
+		// Do the handshake 
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+		wiic_handshake(wm, NULL, 0);
+		wiic_set_report_type(wm);
+		
+		/* autoreconnect flag */
+		wm->autoreconnect = autoreconnect;
+		
+		[pool drain];
+	}
+	else {
+		[pool drain];
+		return 0;
+	}
+	
+	return 1;
+}
+
+/**
+ *	@brief Connect to a wiimote or wiimotes once an address is known.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *	@param wiimotes		The number of wiimote structures in \a wm.
+ *	@param autoreconnect	Re-connect to the device in case of unexpected disconnection.
+ *
+ *	@return The number of wiimotes that successfully connected.
+ *
+ *	@see wiic_find()
+ *	@see wiic_connect_single()
+ *	@see wiic_disconnect()
+ *
+ *	Connect to a number of wiimotes when the address is already set
+ *	in the wiimote_t structures.  These addresses are normally set
+ *	by the wiic_find() function, but can also be set manually.
+ */
+int wiic_connect(struct wiimote_t** wm, int wiimotes, int autoreconnect) 
+{
+	int connected = 0;
+	int i = 0;
+	
+	for (; i < wiimotes; ++i) {
+		if(!(wm[i])) {
+			WIIC_ERROR("Trying to connect more Wiimotes than initialized");
+			return;
+		}
+		
+		if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
+			// If the device address is not set, skip it 
+			continue;
+
+		if (wiic_connect_single(wm[i], NULL, autoreconnect))
+			++connected;
+	}
+
+	return connected;
+}
+
+/**
+ *	@brief Load Wii devices registered in the wiimotes.config file.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *
+ *	@return The number of wiimotes successfully loaded.
+ *
+ *	@see wiic_find()
+ *  @see wiic_connect()
+ *	@see wiic_connect_single()
+ *	@see wiic_disconnect()
+ *
+ *	From version 0.53, it is possible to register the MAC address of your 
+ *  Wii devices. This allows to automatically load them, without waiting for any
+ *  search timeout. To register a new device, go to: <HOME_DIR>/.wiic/ and
+ *  edit the file wiimotes.config, by adding the MAC address of the device 
+ *  you want to register (one line per MAC address).
+ */
+int wiic_load(struct wiimote_t** wm) 
+{
+	int loaded = 0;
+	int i = 0;
+	char str[200];
+	char configPath[100];
+	char* tmp = 0;
+	
+	// Retrieve the HOME environment variable
+	tmp = getenv("HOME");
+	strcpy(configPath,tmp);
+	strncat(configPath,"/.wiic/wiimotes.config",22);
+
+	// Open the config file
+	FILE* fd = 0;
+	fd = fopen(configPath,"r");
+	if(!fd) 
+		return loaded;
+
+	// Read line by line
+	while(fgets(str,sizeof(str),fd) != NULL && loaded < 1) {
+		int len = strlen(str)-1;
+      	if(str[len] == '\n') 
+        	str[len] = 0;
+		loaded++;
+	}
+	
+	// We initialize the device structure
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+	for (; i < loaded; ++i) {
+		NSString* string = [NSString stringWithCString:str encoding:[NSString defaultCStringEncoding]];
+		BluetoothDeviceAddress deviceAddr;
+		IOBluetoothNSStringToDeviceAddress(string, &deviceAddr);
+		IOBluetoothDevice* device = [IOBluetoothDevice withAddress:&deviceAddr];
+		wm[i]->device = [[device retain] getDeviceRef];
+		wm[i]->address = (CFStringRef)[[device getAddressString] retain];
+		WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND);
+		WIIC_INFO("Loaded Wiimote (%s) [id %i].",CFStringGetCStringPtr(wm[i]->address, kCFStringEncodingMacRoman),wm[i]->unid);
+	}
+	[pool drain];
+
+	return loaded;
+}
+
+int wiic_io_read(struct wiimote_t* wm) 
+{
+    if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED))
+            return 0;
+
+    /* If this wiimote is not connected, skip it */
+    if (!WIIMOTE_IS_CONNECTED(wm))
+            return 0;
+			
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+	WiiConnect* deviceHandler = 0;
+	deviceHandler = (WiiConnect*)(wm->connectionHandler);
+
+	/* If this wiimote is disconnecting, skip it */
+	if (!deviceHandler || [deviceHandler isDisconnecting]) {
+		[pool drain];
+		return 0;
+	}
+
+    // Run the main loop to get bt data
+	[deviceHandler setReading:YES];
+	[deviceHandler setTimeout:NO];
+
+	// We start the thread which manages the timeout to implement a non-blocking read 
+	[NSThread detachNewThreadSelector:@selector(startTimerThread) toTarget:deviceHandler withObject:nil];
+
+	NSRunLoop *theRL = [NSRunLoop currentRunLoop];
+	// Two possible events: we receive and incoming message or there is a timeout
+	while([deviceHandler isReading] && ![deviceHandler isTimeout]) {
+		NSAutoreleasePool *pool_loop = [[NSAutoreleasePool alloc] init]; // This is used for fast release of NSDate, otherwise it leaks
+		[theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+		[pool_loop drain];
+	}
+	
+	// In this case we have no incoming data (TIMEOUT)
+	if([deviceHandler isTimeout]) {
+		[pool drain];
+		return 0;
+	}
+
+	if(!(wm->connectionHandler)) {
+		WIIC_ERROR("Unable to find the connection handler (id %i).", wm->unid);
+		[pool drain];
+		return 0;
+	}
+
+	// Read next message
+	byte* buffer = 0;
+	unsigned int length = 0;
+	if(![deviceHandler isDisconnecting]) {
+		buffer = [deviceHandler getNextMsg];
+		length = [deviceHandler getMsgLength];
+	}
+
+	if(!buffer || !length) {
+		[pool drain];
+		return 0;
+	}
+
+	// Forward to WiiC
+	if(length < sizeof(wm->event_buf)) 
+		memcpy(wm->event_buf,buffer,length);
+	else {
+		WIIC_DEBUG("Received data are more than the buffer.... strange! (id %i)", wm->unid);
+		memcpy(wm->event_buf,buffer,sizeof(wm->event_buf));
+	}
+
+	// Release the consumed message
+	[deviceHandler deleteMsg];
+
+	[pool drain];
+		
+    return 1;
+}
+
+
+int wiic_io_write(struct wiimote_t* wm, byte* buf, int len) 
+{
+	unsigned int length = (unsigned int)len;
+	
+	// Small check before writing
+	if(!wm || !(wm->outputCh)) {
+		WIIC_ERROR("Attempt to write over non-existent channel (id %i).", wm->unid);
+		perror("Error Details");
+		return 0;
+	}
+
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+	IOBluetoothL2CAPChannel* channel = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->outputCh];
+    IOReturn error = [channel writeSync:buf length:length];
+	if (error != kIOReturnSuccess) 
+		WIIC_ERROR("Unable to write over the output channel (id %i).", wm->unid);		
+    usleep(10000);
+	
+    [pool drain];
+
+	return (error == kIOReturnSuccess ? len : 0);
+}
+
+#endif 
Index: code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c	(revision 9780)
@@ -0,0 +1,341 @@
+/*
+ *    io_nix.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles device I/O for *nix.
+ */
+
+#ifndef __APPLE__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/bluetooth.h"
+#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/hci.h"
+#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/hci_lib.h"
+#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/l2cap.h"
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "io.h"
+
+/**
+ *	@brief Find a wiimote or wiimotes.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *	@param max_wiimotes	The number of wiimote structures in \a wm.
+ *	@param timeout		The number of seconds before the search times out.
+ *
+ *	@return The number of wiimotes found.
+ *
+ *	@see wiimote_connect()
+ *
+ *	This function will only look for wiimote devices.						\n
+ *	When a device is found the address in the structures will be set.		\n
+ *	You can then call wiimote_connect() to connect to the found				\n
+ *	devices.
+ */
+int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
+	int device_id;
+	int device_sock;
+	int found_devices;
+	int found_wiimotes;
+
+	/* reset all wiimote bluetooth device addresses */
+	for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes)
+		wm[found_wiimotes]->bdaddr = *BDADDR_ANY;
+	found_wiimotes = 0;
+
+	/* get the id of the first bluetooth device. */
+	device_id = hci_get_route(NULL);
+	if (device_id < 0) {
+		perror("hci_get_route");
+		return 0;
+	}
+
+	/* create a socket to the device */
+	device_sock = hci_open_dev(device_id);
+	if (device_sock < 0) {
+		perror("hci_open_dev");
+		return 0;
+	}
+
+	inquiry_info scan_info_arr[128];
+	inquiry_info* scan_info = scan_info_arr;
+	memset(&scan_info_arr, 0, sizeof(scan_info_arr));
+
+	/* scan for bluetooth devices for 'timeout' seconds */
+	if(timeout)
+		found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
+	else {
+		while(!(found_devices = hci_inquiry(device_id, 5, 128, NULL, &scan_info, IREQ_CACHE_FLUSH))) ; // Unlimited inquiry
+	}
+		
+	if (found_devices < 0) {
+		perror("hci_inquiry");
+		return 0;
+	}
+
+	WIIC_INFO("Found %i bluetooth device(s).", found_devices);
+
+	int i = 0;
+
+	/* display discovered devices */
+	for (; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) {
+		if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) &&
+			(scan_info[i].dev_class[1] == WM_DEV_CLASS_1) &&
+			(scan_info[i].dev_class[2] == WM_DEV_CLASS_2))
+		{
+			/* found a device */
+			ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str);
+
+			WIIC_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid);
+
+			wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr;
+			WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND);
+			++found_wiimotes;
+		}
+	}
+
+	close(device_sock);
+	return found_wiimotes;
+}
+
+
+/**
+ *	@brief Connect to a wiimote or wiimotes once an address is known.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *	@param wiimotes		The number of wiimote structures in \a wm.
+ *  @param autoreconnect	Re-connects the device in case of unexpected disconnection.
+ *
+ *	@return The number of wiimotes that successfully connected.
+ *
+ *	@see wiic_find()
+ *	@see wiic_connect_single()
+ *	@see wiic_disconnect()
+ *
+ *	Connect to a number of wiimotes when the address is already set
+ *	in the wiimote_t structures.  These addresses are normally set
+ *	by the wiic_find() function, but can also be set manually.
+ */
+int wiic_connect(struct wiimote_t** wm, int wiimotes, int autoreconnect) 
+{
+	int connected = 0;
+	int i = 0;
+
+	for (; i < wiimotes; ++i) {
+		if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
+			/* if the device address is not set, skip it */
+			continue;
+		
+		if (wiic_connect_single(wm[i], NULL, autoreconnect)) {
+			++connected;
+		}
+	}
+
+	return connected;
+}
+
+/**
+ *	@brief Load Wii devices registered in the wiimotes.config file.
+ *
+ *	@param wm			An array of wiimote_t structures.
+ *
+ *	@return The number of wiimotes successfully loaded.
+ *
+ *	@see wiic_find()
+ *  @see wiic_connect()
+ *	@see wiic_connect_single()
+ *	@see wiic_disconnect()
+ *
+ *	Up to version 0.53, it is possible to register the MAC address of your 
+ *  Wii devices. This allows to automatically load them, without waiting for any
+ *  search timeout. To register a new device, go to: <HOME_DIR>/.wiic/ and
+ *  edit the file wiimotes.config, by adding the MAC address of the device 
+ *  you want to register (one line per MAC address).
+ */
+int wiic_load(struct wiimote_t** wm) 
+{
+	int loaded = 0;
+	int i = 0;
+	char str[200];
+	char* str_ptr = 0;
+	char configPath[100];
+	char* tmp = 0;
+	
+	// Retrieve the HOME environment variable
+	tmp = getenv("HOME");
+	strcpy(configPath,tmp);
+	strncat(configPath,"/.wiic/wiimotes.config",22);
+
+	// Open the config file
+	FILE* fd = 0;
+	fd = fopen(configPath,"r");
+	if(!fd) 
+		return loaded;
+
+	// Read line by line
+	while(fgets(str,sizeof(str),fd) != NULL && loaded < 1) {
+		int len = strlen(str)-1;
+      	if(str[len] == '\n') 
+        	str[len] = 0;
+		loaded++;
+	}
+	
+	// We initialize the device structure
+	for (; i < loaded; ++i) {
+		/* found a device */
+		strncpy(wm[i]->bdaddr_str,str,18);
+		str_ptr = str;
+		str2ba(str_ptr,&(wm[i]->bdaddr));
+		WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND);
+		WIIC_INFO("Loaded Wiimote (%s) [id %i].",wm[i]->bdaddr_str,wm[i]->unid);
+	}
+
+	return loaded;
+}
+
+/**
+ *	@brief Connect to a wiimote with a known address.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param address	The address of the device to connect to.
+ *					If NULL, use the address in the struct set by wiic_find().
+ *	@param autoreconnect	Re-connect to the device in case of unexpected disconnection.
+ *
+ *	@return 1 on success, 0 on failure
+ */
+int wiic_connect_single(struct wiimote_t* wm, char* address, int autoreconnect) {
+	struct sockaddr_l2 addr;
+	memset(&addr, 0, sizeof(addr));
+
+	if (!wm || WIIMOTE_IS_CONNECTED(wm))
+		return 0;
+
+	addr.l2_family = AF_BLUETOOTH;
+
+	if (address) 
+		/* use provided address */
+		str2ba(address, &addr.l2_bdaddr);
+	else
+		/* use address of device discovered */
+		addr.l2_bdaddr = wm->bdaddr;
+
+	/*
+	 *	OUTPUT CHANNEL
+	 */
+	wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+	if (wm->out_sock == -1)
+		return 0;
+
+	addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);
+
+	/* connect to wiimote */
+	if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+		perror("connect() output sock");
+		return 0;
+	}
+
+	/*
+	 *	INPUT CHANNEL
+	 */
+	wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+	if (wm->in_sock == -1) {
+		close(wm->out_sock);
+		wm->out_sock = -1;
+		return 0;
+	}
+
+	addr.l2_psm = htobs(WM_INPUT_CHANNEL);
+
+	/* connect to wiimote */
+	if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+		perror("connect() interrupt sock");
+		close(wm->out_sock);
+		wm->out_sock = -1;
+		return 0;
+	}
+	
+	/* autoreconnect flag */
+	wm->autoreconnect = autoreconnect;
+
+	WIIC_INFO("Connected to wiimote [id %i].", wm->unid);
+
+	/* do the handshake */
+	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+	wiic_handshake(wm, NULL, 0);
+
+	wiic_set_report_type(wm);
+
+	return 1;
+}
+
+
+/**
+ *	@brief Disconnect a wiimote.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *
+ *	@see wiic_connect()
+ *
+ *	Note that this will not free the wiimote structure.
+ */
+void wiic_disconnect(struct wiimote_t* wm) {
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return;
+
+	close(wm->out_sock);
+	close(wm->in_sock);
+
+	wm->out_sock = -1;
+	wm->in_sock = -1;
+	wm->event = WIIC_NONE;
+
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+}
+
+
+int wiic_io_read(struct wiimote_t* wm) {
+	/* not used */
+	return 0;
+}
+
+
+int wiic_io_write(struct wiimote_t* wm, byte* buf, int len) {
+	return write(wm->out_sock, buf, len);
+}
+
+
+#endif /* ifndef __APPLE__ */
Index: code/branches/wiimote/src/external/wiicpp/wiic/ir.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/ir.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/ir.c	(revision 9780)
@@ -0,0 +1,742 @@
+/*
+ *    ir.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles IR data.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "ir.h"
+
+static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2);
+static void interpret_ir_data(struct wiimote_t* wm);
+static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang);
+static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y);
+static void reorder_ir_dots(struct ir_dot_t* dot);
+static float ir_distance(struct ir_dot_t* dot);
+static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y);
+static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy);
+
+
+/**
+ *	@brief	Set if the wiimote should track IR targets.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param status	1 to enable, 0 to disable.
+ */
+void wiic_set_ir(struct wiimote_t* wm, int status) {
+	byte buf;
+	char* block1 = NULL;
+	char* block2 = NULL;
+	int ir_level;
+
+	if (!wm)
+		return;
+
+	/*
+	 *	Wait for the handshake to finish first.
+	 *	When it handshake finishes and sees that
+	 *	IR is enabled, it will call this function
+	 *	again to actually enable IR.
+	 */
+	if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE)) {
+		WIIC_DEBUG("Tried to enable IR, will wait until handshake finishes.");
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
+		return;
+	}
+
+	/*
+	 *	Check to make sure a sensitivity setting is selected.
+	 */
+	ir_level = get_ir_sens(wm, &block1, &block2);
+	if (!ir_level) {
+		WIIC_ERROR("No IR sensitivity setting selected.");
+		return;
+	}
+
+	if (status) {
+		/* if already enabled then stop */
+		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+			return;
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
+	} else {
+		/* if already disabled then stop */
+		if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+			return;
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+	}
+
+	/* set camera 1 and 2 */
+	buf = (status ? 0x04 : 0x00);
+	wiic_send(wm, WM_CMD_IR, &buf, 1);
+	wiic_send(wm, WM_CMD_IR_2, &buf, 1);
+
+	if (!status) {
+		WIIC_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid);
+		wiic_set_report_type(wm);
+		return;
+	}
+
+	/* enable IR, set sensitivity */
+	buf = 0x08;
+	wiic_write_data(wm, WM_REG_IR, &buf, 1);
+
+	/* wait for the wiimote to catch up */
+	usleep(50000);
+
+	/* write sensitivity blocks */
+	wiic_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
+	wiic_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);
+
+	/* set the IR mode */
+	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+		buf = WM_IR_TYPE_BASIC;
+	else
+		buf = WM_IR_TYPE_EXTENDED;
+	wiic_write_data(wm, WM_REG_IR_MODENUM, &buf, 1);
+
+	usleep(50000);
+
+	/* set the wiimote report type */
+	wiic_set_report_type(wm);
+
+	WIIC_DEBUG("Enabled IR camera for wiimote id %i (sensitivity level %i).", wm->unid, ir_level);
+}
+
+
+/**
+ *	@brief	Get the IR sensitivity settings.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param block1	[out] Pointer to where block1 will be set.
+ *	@param block2	[out] Pointer to where block2 will be set.
+ *
+ *	@return Returns the sensitivity level.
+ */
+static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2) {
+	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL1)) {
+		*block1 = WM_IR_BLOCK1_LEVEL1;
+		*block2 = WM_IR_BLOCK2_LEVEL1;
+		return 1;
+	} else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL2)) {
+		*block1 = WM_IR_BLOCK1_LEVEL2;
+		*block2 = WM_IR_BLOCK2_LEVEL2;
+		return 2;
+	} else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL3)) {
+		*block1 = WM_IR_BLOCK1_LEVEL3;
+		*block2 = WM_IR_BLOCK2_LEVEL3;
+		return 3;
+	} else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL4)) {
+		*block1 = WM_IR_BLOCK1_LEVEL4;
+		*block2 = WM_IR_BLOCK2_LEVEL4;
+		return 4;
+	} else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL5)) {
+		*block1 = WM_IR_BLOCK1_LEVEL5;
+		*block2 = WM_IR_BLOCK2_LEVEL5;
+		return 5;
+	}
+
+	*block1 = NULL;
+	*block2 = NULL;
+	return 0;
+}
+
+
+/**
+ *	@brief	Set the virtual screen resolution for IR tracking.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param x       Screen resolution width.
+ * @param y			Screen resolution height.
+ */
+void wiic_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y) {
+	if (!wm)	return;
+
+	wm->ir.vres[0] = (x-1);
+	wm->ir.vres[1] = (y-1);
+}
+
+
+/**
+ *	@brief	Set the XY position for the IR cursor.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ * @param pos		The position of the IR emitter (WIIC_IR_ABOVE or WIIC_IR_BELOW)
+ */
+void wiic_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos) {
+	if (!wm)	return;
+
+	wm->ir.pos = pos;
+
+	switch (pos) {
+
+		case WIIC_IR_ABOVE:
+			wm->ir.offset[0] = 0;
+
+			if (wm->ir.aspect == WIIC_ASPECT_16_9)
+				wm->ir.offset[1] = WM_ASPECT_16_9_Y/2 - 70;
+			else if (wm->ir.aspect == WIIC_ASPECT_4_3)
+				wm->ir.offset[1] = WM_ASPECT_4_3_Y/2 - 100;
+
+			return;
+
+		case WIIC_IR_BELOW:
+			wm->ir.offset[0] = 0;
+
+			if (wm->ir.aspect == WIIC_ASPECT_16_9)
+				wm->ir.offset[1] = -WM_ASPECT_16_9_Y/2 + 100;
+			else if (wm->ir.aspect == WIIC_ASPECT_4_3)
+				wm->ir.offset[1] = -WM_ASPECT_4_3_Y/2 + 70;
+
+			return;
+
+		default:
+			return;
+	};
+}
+
+
+/**
+ *	@brief	Set the aspect ratio of the TV/monitor.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param aspect	Either WIIC_ASPECT_16_9 or WIIC_ASPECT_4_3
+ */
+void wiic_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect) {
+	if (!wm)	return;
+
+	wm->ir.aspect = aspect;
+
+	if (aspect == WIIC_ASPECT_4_3) {
+		wm->ir.vres[0] = WM_ASPECT_4_3_X;
+		wm->ir.vres[1] = WM_ASPECT_4_3_Y;
+	} else {
+		wm->ir.vres[0] = WM_ASPECT_16_9_X;
+		wm->ir.vres[1] = WM_ASPECT_16_9_Y;
+	}
+
+	/* reset the position offsets */
+	wiic_set_ir_position(wm, wm->ir.pos);
+}
+
+
+/**
+ *	@brief	Set the IR sensitivity.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param level	1-5, same as Wii system sensitivity setting.
+ *
+ *	If the level is < 1, then level will be set to 1.
+ *	If the level is > 5, then level will be set to 5.
+ */
+void wiic_set_ir_sensitivity(struct wiimote_t* wm, int level) {
+	char* block1 = NULL;
+	char* block2 = NULL;
+
+	if (!wm)	return;
+
+	if (level > 5)		level = 5;
+	if (level < 1)		level = 1;
+
+	WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 |
+								WIIMOTE_STATE_IR_SENS_LVL2 |
+								WIIMOTE_STATE_IR_SENS_LVL3 |
+								WIIMOTE_STATE_IR_SENS_LVL4 |
+								WIIMOTE_STATE_IR_SENS_LVL5));
+
+	switch (level) {
+		case 1:
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1);
+			break;
+		case 2:
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2);
+			break;
+		case 3:
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3);
+			break;
+		case 4:
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4);
+			break;
+		case 5:
+			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5);
+			break;
+		default:
+			return;
+	}
+
+	/* set the new sensitivity */
+	get_ir_sens(wm, &block1, &block2);
+
+	wiic_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
+	wiic_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);
+
+	WIIC_DEBUG("Set IR sensitivity to level %i (unid %i)", level, wm->unid);
+}
+
+
+/**
+ *	@brief Calculate the data from the IR spots.  Basic IR mode.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param data		Data returned by the wiimote for the IR spots.
+ */
+void calculate_basic_ir(struct wiimote_t* wm, byte* data) {
+	struct ir_dot_t* dot = wm->ir.dot;
+	int i;
+
+	dot[0].rx = 1023 - (data[0] | ((data[2] & 0x30) << 4));
+	dot[0].ry = data[1] | ((data[2] & 0xC0) << 2);
+
+	dot[1].rx = 1023 - (data[3] | ((data[2] & 0x03) << 8));
+	dot[1].ry = data[4] | ((data[2] & 0x0C) << 6);
+
+	dot[2].rx = 1023 - (data[5] | ((data[7] & 0x30) << 4));
+	dot[2].ry = data[6] | ((data[7] & 0xC0) << 2);
+
+	dot[3].rx = 1023 - (data[8] | ((data[7] & 0x03) << 8));
+	dot[3].ry = data[9] | ((data[7] & 0x0C) << 6);
+
+	/* set each IR spot to visible if spot is in range */
+	for (i = 0; i < 4; ++i) {
+		if (dot[i].ry == 1023)
+			dot[i].visible = 0;
+		else {
+			dot[i].visible = 1;
+			dot[i].size = 0;		/* since we don't know the size, set it as 0 */
+		}
+	}
+
+	interpret_ir_data(wm);
+}
+
+
+/**
+ *	@brief Calculate the data from the IR spots.  Extended IR mode.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param data		Data returned by the wiimote for the IR spots.
+ */
+void calculate_extended_ir(struct wiimote_t* wm, byte* data) {
+	struct ir_dot_t* dot = wm->ir.dot;
+	int i;
+
+	for (i = 0; i < 4; ++i) {
+		dot[i].rx = 1023 - (data[3*i] | ((data[(3*i)+2] & 0x30) << 4));
+		dot[i].ry = data[(3*i)+1] | ((data[(3*i)+2] & 0xC0) << 2);
+
+		dot[i].size = data[(3*i)+2] & 0x0F;
+
+		/* if in range set to visible */
+		if (dot[i].ry == 1023)
+			dot[i].visible = 0;
+		else
+			dot[i].visible = 1;
+	}
+
+	interpret_ir_data(wm);
+}
+
+
+/**
+ *	@brief Interpret IR data into more user friendly variables.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ */
+static void interpret_ir_data(struct wiimote_t* wm) {
+	struct ir_dot_t* dot = wm->ir.dot;
+	int i;
+	float roll = 0.0f;
+	int last_num_dots = wm->ir.num_dots;
+
+	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC))
+		roll = wm->orient.angle.roll;
+
+	/* count visible dots */
+	wm->ir.num_dots = 0;
+	for (i = 0; i < 4; ++i) {
+		if (dot[i].visible)
+			wm->ir.num_dots++;
+	}
+
+	switch (wm->ir.num_dots) {
+		case 0:
+		{
+			wm->ir.state = 0;
+
+			/* reset the dot ordering */
+			for (i = 0; i < 4; ++i)
+				dot[i].order = 0;
+
+			wm->ir.x = 0;
+			wm->ir.y = 0;
+			wm->ir.z = 0.0f;
+
+			return;
+		}
+		case 1:
+		{
+			fix_rotated_ir_dots(wm->ir.dot, roll);
+
+			if (wm->ir.state < 2) {
+				/*
+				 *	Only 1 known dot, so use just that.
+				 */
+				for (i = 0; i < 4; ++i) {
+					if (dot[i].visible) {
+						wm->ir.x = dot[i].x;
+						wm->ir.y = dot[i].y;
+
+						wm->ir.ax = wm->ir.x;
+						wm->ir.ay = wm->ir.y;
+
+						/*	can't calculate yaw because we don't have the distance */
+						//wm->orient.yaw = calc_yaw(&wm->ir);
+
+						ir_convert_to_vres(&wm->ir.x, &wm->ir.y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+						break;
+					}
+				}
+			} else {
+				/*
+				 *	Only see 1 dot but know theres 2.
+				 *	Try to estimate where the other one
+				 *	should be and use that.
+				 */
+				for (i = 0; i < 4; ++i) {
+					if (dot[i].visible) {
+						int ox = 0;
+						int x, y;
+
+						if (dot[i].order == 1)
+							/* visible is the left dot - estimate where the right is */
+							ox = dot[i].x + wm->ir.distance;
+						else if (dot[i].order == 2)
+							/* visible is the right dot - estimate where the left is */
+							ox = dot[i].x - wm->ir.distance;
+
+						x = ((signed int)dot[i].x + ox) / 2;
+						y = dot[i].y;
+
+						wm->ir.ax = x;
+						wm->ir.ay = y;
+						wm->orient.angle.yaw = calc_yaw(&wm->ir);
+
+						if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) {
+							ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+							wm->ir.x = x;
+							wm->ir.y = y;
+						}
+
+						break;
+					}
+				}
+			}
+
+			break;
+		}
+		case 2:
+		case 3:
+		case 4:
+		{
+			/*
+			 *	Two (or more) dots known and seen.
+			 *	Average them together to estimate the true location.
+			 */
+			int x, y;
+			wm->ir.state = 2;
+
+			fix_rotated_ir_dots(wm->ir.dot, roll);
+
+			/* if there is at least 1 new dot, reorder them all */
+			if (wm->ir.num_dots > last_num_dots) {
+				reorder_ir_dots(dot);
+				wm->ir.x = 0;
+				wm->ir.y = 0;
+			}
+
+			wm->ir.distance = ir_distance(dot);
+			wm->ir.z = 1023 - wm->ir.distance;
+
+			get_ir_dot_avg(wm->ir.dot, &x, &y);
+
+			wm->ir.ax = x;
+			wm->ir.ay = y;
+			wm->orient.angle.yaw = calc_yaw(&wm->ir);
+
+			if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) {
+				ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+				wm->ir.x = x;
+				wm->ir.y = y;
+			}
+
+			break;
+		}
+		default:
+		{
+			break;
+		}
+	}
+
+	#ifdef WITH_WIIC_DEBUG
+	{
+	int ir_level;
+	WIIC_GET_IR_SENSITIVITY(wm, &ir_level);
+	WIIC_DEBUG("IR sensitivity: %i", ir_level);
+	WIIC_DEBUG("IR visible dots: %i", wm->ir.num_dots);
+	for (i = 0; i < 4; ++i)
+		if (dot[i].visible)
+			WIIC_DEBUG("IR[%i][order %i] (%.3i, %.3i) -> (%.3i, %.3i)", i, dot[i].order, dot[i].rx, dot[i].ry, dot[i].x, dot[i].y);
+	WIIC_DEBUG("IR[absolute]: (%i, %i)", wm->ir.x, wm->ir.y);
+	}
+	#endif
+}
+
+
+
+/**
+ *	@brief Fix the rotation of the IR dots.
+ *
+ *	@param dot		An array of 4 ir_dot_t objects.
+ *	@param ang		The roll angle to correct by (-180, 180)
+ *
+ *	If there is roll then the dots are rotated
+ *	around the origin and give a false cursor
+ *	position. Correct for the roll.
+ *
+ *	If the accelerometer is off then obviously
+ *	this will not do anything and the cursor
+ *	position may be inaccurate.
+ */
+static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang) {
+	float s, c;
+	int x, y;
+	int i;
+
+	if (!ang) {
+		for (i = 0; i < 4; ++i) {
+			dot[i].x = dot[i].rx;
+			dot[i].y = dot[i].ry;
+		}
+		return;
+	}
+
+	s = sin(DEGREE_TO_RAD(ang));
+	c = cos(DEGREE_TO_RAD(ang));
+
+	/*
+	 *	[ cos(theta)  -sin(theta) ][ ir->rx ]
+	 *	[ sin(theta)  cos(theta)  ][ ir->ry ]
+	 */
+
+	for (i = 0; i < 4; ++i) {
+		if (!dot[i].visible)
+			continue;
+
+		x = dot[i].rx - (1024/2);
+		y = dot[i].ry - (768/2);
+
+		dot[i].x = (c * x) + (-s * y);
+		dot[i].y = (s * x) + (c * y);
+
+		dot[i].x += (1024/2);
+		dot[i].y += (768/2);
+	}
+}
+
+
+/**
+ *	@brief Average IR dots.
+ *
+ *	@param dot		An array of 4 ir_dot_t objects.
+ *	@param x		[out] Average X
+ *	@param y		[out] Average Y
+ */
+static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y) {
+	int vis = 0, i = 0;
+
+	*x = 0;
+	*y = 0;
+
+	for (; i < 4; ++i) {
+		if (dot[i].visible) {
+			*x += dot[i].x;
+			*y += dot[i].y;
+			++vis;
+		}
+	}
+
+	*x /= vis;
+	*y /= vis;
+}
+
+
+/**
+ *	@brief Reorder the IR dots.
+ *
+ *	@param dot		An array of 4 ir_dot_t objects.
+ */
+static void reorder_ir_dots(struct ir_dot_t* dot) {
+	int i, j, order;
+
+	/* reset the dot ordering */
+	for (i = 0; i < 4; ++i)
+		dot[i].order = 0;
+
+	for (order = 1; order < 5; ++order) {
+		i = 0;
+
+		for (; !dot[i].visible || dot[i].order; ++i)
+		if (i > 4)
+			return;
+
+		for (j = 0; j < 4; ++j) {
+			if (dot[j].visible && !dot[j].order && (dot[j].x < dot[i].x))
+				i = j;
+		}
+
+		dot[i].order = order;
+	}
+}
+
+
+/**
+ *	@brief Calculate the distance between the first 2 visible IR dots.
+ *
+ *	@param dot		An array of 4 ir_dot_t objects.
+ */
+static float ir_distance(struct ir_dot_t* dot) {
+	int i1, i2;
+	int xd, yd;
+
+	for (i1 = 0; i1 < 4; ++i1)
+		if (dot[i1].visible)
+			break;
+	if (i1 == 4)
+		return 0.0f;
+
+	for (i2 = i1+1; i2 < 4; ++i2)
+		if (dot[i2].visible)
+			break;
+	if (i2 == 4)
+		return 0.0f;
+
+	xd = dot[i2].x - dot[i1].x;
+	yd = dot[i2].y - dot[i1].y;
+
+	return sqrt(xd*xd + yd*yd);
+}
+
+
+/**
+ *	@brief Correct for the IR bounding box.
+ *
+ *	@param x		[out] The current X, it will be updated if valid.
+ *	@param y		[out] The current Y, it will be updated if valid.
+ *	@param aspect	Aspect ratio of the screen.
+ *	@param offset_x	The X offset of the bounding box.
+ *	@param offset_y	The Y offset of the bounding box.
+ *
+ *	@return Returns 1 if the point is valid and was updated.
+ *
+ *	Nintendo was smart with this bit. They sacrifice a little
+ *	precision for a big increase in usability.
+ */
+static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y) {
+	int x0, y0;
+	int xs, ys;
+
+	if (aspect == WIIC_ASPECT_16_9) {
+		xs = WM_ASPECT_16_9_X;
+		ys = WM_ASPECT_16_9_Y;
+	} else {
+		xs = WM_ASPECT_4_3_X;
+		ys = WM_ASPECT_4_3_Y;
+	}
+
+	x0 = ((1024 - xs) / 2) + offset_x;
+	y0 = ((768 - ys) / 2) + offset_y;
+
+	if ((*x >= x0)
+		&& (*x <= (x0 + xs))
+		&& (*y >= y0)
+		&& (*y <= (y0 + ys)))
+	{
+		*x -= offset_x;
+		*y -= offset_y;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+
+/**
+ *	@brief Interpolate the point to the user defined virtual screen resolution.
+ */
+static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy) {
+	int xs, ys;
+
+	if (aspect == WIIC_ASPECT_16_9) {
+		xs = WM_ASPECT_16_9_X;
+		ys = WM_ASPECT_16_9_Y;
+	} else {
+		xs = WM_ASPECT_4_3_X;
+		ys = WM_ASPECT_4_3_Y;
+	}
+
+	*x -= ((1024-xs)/2);
+	*y -= ((768-ys)/2);
+
+	*x = (*x / (float)xs) * vx;
+	*y = (*y / (float)ys) * vy;
+}
+
+
+/**
+ *	@brief Calculate yaw given the IR data.
+ *
+ *	@param ir	IR data structure.
+ */
+float calc_yaw(struct ir_t* ir) {
+	float x;
+
+	x = ir->ax - 512;
+	x = x * (ir->z / 1024.0f);
+
+	return RAD_TO_DEGREE( atanf(x / ir->z) );
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/ir.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/ir.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/ir.h	(revision 9780)
@@ -0,0 +1,59 @@
+/*
+ *    ir.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Handles IR data.
+ */
+
+#ifndef IR_H_INCLUDED
+#define IR_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#define WII_VRES_X		560
+#define WII_VRES_Y		340
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void calculate_basic_ir(struct wiimote_t* wm, byte* data);
+void calculate_extended_ir(struct wiimote_t* wm, byte* data);
+float calc_yaw(struct ir_t* ir);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IR_H_INCLUDED
+
+
Index: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c	(revision 9780)
@@ -0,0 +1,278 @@
+/*
+ *	motionplus.c
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Motion Plus expansion device.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "motionplus.h"
+
+/**
+ *	@brief Convert raw data in deg/sec angular rates.
+ *
+ *	@param mp		A pointer to a motionplus_t structure.
+ *	
+ *	Subtract calibration data from raw data, and convert the difference in deg/sec
+ *	angular rates. The function also considers the fast/slow rotation mode
+ *	and performs very simple filtering for slow rotations.
+ */
+void calculate_gyro_rates(struct motion_plus_t* mp, struct ang3s_t* in, struct ang3f_t* out)
+{
+	short int tmp_r, tmp_p, tmp_y;
+	float tmp_roll, tmp_pitch, tmp_yaw;
+	
+	// We consider calibration data
+	tmp_r = in->roll - mp->cal_gyro.roll;
+	tmp_p = in->pitch - mp->cal_gyro.pitch;
+	tmp_y = in->yaw - mp->cal_gyro.yaw;
+
+	// We convert to degree/sec according to fast/slow mode
+	if(mp->acc_mode & 0x04)
+		tmp_roll = tmp_r / 20.0;
+	else
+		tmp_roll = tmp_r / 4.0;
+
+	if(mp->acc_mode & 0x02)
+		tmp_pitch = tmp_p / 20.0;
+	else
+		tmp_pitch = tmp_p / 4.0;
+		
+	if(mp->acc_mode & 0x01)
+		tmp_yaw = tmp_y / 20.0;
+	else
+		tmp_yaw = tmp_y / 4.0;
+	
+	out->roll = tmp_roll;
+	out->pitch = tmp_pitch;
+	out->yaw = tmp_yaw;
+}
+
+/**
+ *	@brief Handle Motion Plus event.
+ *
+ *	@param mp		A pointer to a motionplus_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void motion_plus_event(struct motion_plus_t* mp, byte* msg) 
+{
+	// Check if the gyroscope is in fast or slow mode (0 if rotating fast, 1 if slow or still)
+	mp->acc_mode = ((msg[4] & 0x2) << 1) | ((msg[3] & 0x1) << 1) | ((msg[3] & 0x2) >> 1); 
+	
+	mp->a_raw_gyro.roll = ((msg[4] & 0xFC) << 6) | msg[1];
+	mp->a_raw_gyro.pitch = ((msg[5] & 0xFC) << 6) | msg[2];
+	mp->a_raw_gyro.yaw = ((msg[3] & 0xFC) << 6) | msg[0];
+
+	// First calibration
+	if((mp->a_raw_gyro.roll > 5000) && (mp->a_raw_gyro.pitch > 5000) && (mp->a_raw_gyro.yaw > 5000) && 
+		!(mp->cal_gyro.roll) && !(mp->cal_gyro.pitch) && !(mp->cal_gyro.yaw)) {
+		wiic_calibrate_motion_plus(mp);	
+	}
+	
+	if(mp->smooth)
+		motion_plus_apply_smoothing(mp);
+	else {
+		mp->raw_gyro.roll = mp->a_raw_gyro.roll;
+		mp->raw_gyro.pitch = mp->a_raw_gyro.pitch;
+		mp->raw_gyro.yaw = mp->a_raw_gyro.yaw;
+	}
+				
+	// Calculate angular rates in deg/sec and performs some simple filtering (both unsmoothed and smoothed)
+	calculate_gyro_rates(mp,&(mp->a_raw_gyro),&(mp->a_gyro_rate));
+	calculate_gyro_rates(mp,&(mp->raw_gyro),&(mp->gyro_rate));
+}
+
+/**
+ *	@brief Apply smoothing to the Motion Plus gyroscopes.
+ *
+ *	@param mp		Pointer to a motion_plus_t structure.
+ *
+ */
+void motion_plus_apply_smoothing(struct motion_plus_t *mp)
+{
+	float alpha = mp->smooth_alpha;
+	
+	mp->raw_gyro.roll = alpha*mp->raw_gyro.roll + (1.0-alpha)*mp->a_raw_gyro.roll;
+	mp->raw_gyro.pitch = alpha*mp->raw_gyro.pitch + (1.0-alpha)*mp->a_raw_gyro.pitch;
+	mp->raw_gyro.yaw = alpha*mp->raw_gyro.yaw + (1.0-alpha)*mp->a_raw_gyro.yaw;
+}
+
+/**
+ *	@brief Handle the handshake from the Motion Plus.
+ *
+ *	@param wm		A pointer to a wiimote_t structure.
+ *	@param data		The data that should contain the Motion Plus ID to check.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	@return	Returns 1 if handshake was successful, 0 if not.
+ */
+int motion_plus_handshake(struct wiimote_t* wm, byte* data, unsigned short len) 
+{
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED);
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
+
+	unsigned int val = (data[2] << 24) | (data[3] << 16) | (data[4] << 8) | data[5];
+
+	if(val == EXP_ID_CODE_MOTION_PLUS) {
+		/* handshake done */
+		wm->event = WIIC_MOTION_PLUS_INSERTED;
+		wm->exp.type = EXP_MOTION_PLUS;
+		
+		WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP);
+		WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_MOTION_PLUS);
+		
+		// Init gyroscopes
+		wm->exp.mp.cal_gyro.roll = 0;
+		wm->exp.mp.cal_gyro.pitch = 0;
+		wm->exp.mp.cal_gyro.yaw = 0;
+		wm->exp.mp.orient.angle.roll = 0.0;
+		wm->exp.mp.orient.angle.pitch = 0.0;
+		wm->exp.mp.orient.angle.yaw = 0.0;
+		wm->exp.mp.raw_gyro.roll = wm->exp.mp.a_raw_gyro.roll = 0;
+		wm->exp.mp.raw_gyro.pitch = wm->exp.mp.a_raw_gyro.pitch = 0;
+		wm->exp.mp.raw_gyro.yaw = wm->exp.mp.a_raw_gyro.yaw = 0;
+		wm->exp.mp.gyro_rate.roll = wm->exp.mp.a_gyro_rate.roll = 0.0;
+		wm->exp.mp.gyro_rate.pitch = wm->exp.mp.a_gyro_rate.pitch = 0.0;
+		wm->exp.mp.gyro_rate.yaw = wm->exp.mp.a_gyro_rate.yaw = 0.0;
+		wm->exp.mp.raw_gyro_threshold = 15;
+		wm->exp.mp.smooth = 1;
+		wm->exp.mp.smooth_alpha = MP_SMOOTH_ALPHA;
+		
+		// Calibration (will be done as soon as we receive the first event)
+		WIIC_INFO("Please, wait for gyro calibration...\n");
+		sleep(1);
+	}
+	else {
+		WIIC_ERROR("Unable to activate Motion Plus");
+		wiic_set_motion_plus(wm,0);
+		return 0;
+	}
+	
+	return 1;
+}
+
+/**
+ *	@brief Control the Motion Plus support.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param status	Flag to control if the support should be enabled or not (1 to enable, 0 to disable).
+ */
+void wiic_set_motion_plus(struct wiimote_t *wm, int status)
+{
+	byte val;
+	byte* buf = 0;
+	byte* tmp = 0;
+
+	// If we're handshaking other expansions, than skip this
+	if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE))
+		return;
+
+	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
+	if(status) {
+		// We initialize the motion plus
+		val = 0x55;
+		wiic_write_data(wm,WM_MOTION_PLUS_INIT,&val,1);
+		usleep(10000);
+
+		// We initialize the motion plus
+		val = 0x04;
+		wiic_write_data(wm,WM_MOTION_PLUS_ENABLE,&val,1);
+		usleep(10000);
+
+		// Callback to check if the init process performed right
+		tmp = (byte*)malloc(sizeof(byte)*6);
+		wiic_read_data_cb(wm, motion_plus_handshake, tmp, WM_MOTION_PLUS_ID_ADDR, 6);
+	}
+	else {
+		disable_expansion(wm);
+		WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_MOTION_PLUS);
+		val = 0x55;
+		wiic_write_data(wm,WM_MOTION_PLUS_DISABLE,&val,1);
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
+	}
+}
+
+
+/**
+ *	@brief Calibrate the Motion Plus gyroscopes.
+ *
+ *	@param mp		Pointer to a motion_plus_t structure.
+ *
+ *  This should be called only after receiving the first values
+ *	from the Motion Plus.
+ */
+void wiic_calibrate_motion_plus(struct motion_plus_t *mp)
+{
+	mp->cal_gyro.roll = mp->raw_gyro.roll = mp->a_raw_gyro.roll ;
+	mp->cal_gyro.pitch = mp->raw_gyro.pitch = mp->a_raw_gyro.pitch ;
+	mp->cal_gyro.yaw = mp->raw_gyro.yaw = mp->a_raw_gyro.yaw ;
+}
+
+
+/**
+ *	@brief Notification of Motion Plus disconnection.
+ *
+ *	@param mp	A pointer to a motion_plus_t structure.
+ */
+void motion_plus_disconnected(struct motion_plus_t* mp)
+{
+	WIIC_DEBUG("Motion plus disconnected");
+	memset(mp, 0, sizeof(struct motion_plus_t));
+}
+
+/**
+ *	@brief	Set the gyroscope event threshold.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param threshold	The decimal place that should be considered a significant change.
+ */
+void wiic_set_mp_threshold(struct wiimote_t* wm, int threshold) {
+	if (!wm)	return;
+
+	wm->exp.mp.raw_gyro_threshold = threshold;
+}
+
+/**
+ *	@brief	Enable the gyroscope smoothing (through an exponential moving average)
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param status		1 to enable - 0 to disable
+ *  @param alpha		Alpha smoothness parameter (between 0.0 and 1.0)
+ */
+void wiic_set_mp_smooth(struct wiimote_t* wm, int status, float alpha) {
+	wm->exp.mp.smooth = status;
+	wm->exp.mp.smooth_alpha = alpha;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h	(revision 9780)
@@ -0,0 +1,61 @@
+/*
+ *	motionplus.h
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Motion Plus expansion device.
+ */
+#ifndef MOTIONPLUS_H_INCLUDED
+#define MOTIONPLUS_H_INCLUDED
+
+#include "wiic_internal.h"
+#include <math.h>
+
+#define MP_SMOOTH_ALPHA	0.65f
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int motion_plus_handshake(struct wiimote_t* wm, byte* data, unsigned short len);
+
+void motion_plus_disconnected(struct motion_plus_t* mp);
+
+void motion_plus_event(struct motion_plus_t* mp, byte* msg);
+
+void wiic_set_mp_threshold(struct wiimote_t* wm, int threshold);
+
+void wiic_set_mp_smooth(struct wiimote_t* wm, int status, float alpha);
+
+void motion_plus_apply_smoothing(struct motion_plus_t* mp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MOTIONPLUS_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c	(revision 9780)
@@ -0,0 +1,209 @@
+/*
+ *    nunchuck.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Nunchuk expansion device.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "nunchuk.h"
+
+static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now);
+
+/**
+ *	@brief Handle the handshake data from the nunchuk.
+ *
+ *	@param nc		A pointer to a nunchuk_t structure.
+ *	@param data		The data read in from the device.
+ *	@param len		The length of the data block, in bytes.
+ *
+ *	@return	Returns 1 if handshake was successful, 0 if not.
+ */
+int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len) {
+	int i;
+	int offset = 0;
+
+	nc->btns = 0;
+	nc->btns_held = 0;
+	nc->btns_released = 0;
+
+	/* set the smoothing to the same as the wiimote */
+	nc->flags = &wm->flags;
+	nc->accel_calib.st_alpha = wm->accel_calib.st_alpha;
+
+	/* decrypt data */
+	for (i = 0; i < len; ++i)
+		data[i] = (data[i] ^ 0x17) + 0x17;
+
+	if (data[offset] == 0xFF) {
+		/*
+		 *	Sometimes the data returned here is not correct.
+		 *	This might happen because the wiimote is lagging
+		 *	behind our initialization sequence.
+		 *	To fix this just request the handshake again.
+		 *
+		 *	Other times it's just the first 16 bytes are 0xFF,
+		 *	but since the next 16 bytes are the same, just use
+		 *	those.
+		 */
+		if (data[offset + 16] == 0xFF) {
+			/* get the calibration data */
+			byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+			WIIC_DEBUG("Nunchuk handshake appears invalid, trying again.");
+			wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+			return 0;
+		} else
+			offset += 16;
+	}
+
+	nc->accel_calib.cal_zero.x = data[offset + 0];
+	nc->accel_calib.cal_zero.y = data[offset + 1];
+	nc->accel_calib.cal_zero.z = data[offset + 2];
+	nc->accel_calib.cal_g.x = data[offset + 4];
+	nc->accel_calib.cal_g.y = data[offset + 5];
+	nc->accel_calib.cal_g.z = data[offset + 6];
+	nc->js.max.x = data[offset + 8];
+	nc->js.min.x = data[offset + 9];
+	nc->js.center.x = data[offset + 10];
+	nc->js.max.y = data[offset + 11];
+	nc->js.min.y = data[offset + 12];
+	nc->js.center.y = data[offset + 13];
+
+	/* default the thresholds to the same as the wiimote */
+	nc->orient_threshold = wm->orient_threshold;
+	nc->accel_threshold = wm->accel_threshold;
+
+	/* handshake done */
+	wm->exp.type = EXP_NUNCHUK;
+
+	return 1;
+}
+
+
+/**
+ *	@brief The nunchuk disconnected.
+ *
+ *	@param nc		A pointer to a nunchuk_t structure.
+ */
+void nunchuk_disconnected(struct nunchuk_t* nc) {
+	memset(nc, 0, sizeof(struct nunchuk_t));
+}
+
+
+
+/**
+ *	@brief Handle nunchuk event.
+ *
+ *	@param nc		A pointer to a nunchuk_t structure.
+ *	@param msg		The message specified in the event packet.
+ */
+void nunchuk_event(struct nunchuk_t* nc, byte* msg) {
+	int i;
+
+	/* decrypt data */
+	for (i = 0; i < 6; ++i)
+		msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+	/* get button states */
+	nunchuk_pressed_buttons(nc, msg[5]);
+
+	/* calculate joystick state */
+	calc_joystick_state(&nc->js, msg[0], msg[1]);
+
+	/* calculate orientation */
+	nc->accel.x = msg[2];
+	nc->accel.y = msg[3];
+	nc->accel.z = msg[4];
+
+	calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce, NUNCHUK_IS_FLAG_SET(nc, WIIC_SMOOTHING));
+	calculate_orientation(&nc->gforce.vec, &nc->orient.angle);
+}
+
+
+/**
+ *	@brief Find what buttons are pressed.
+ *
+ *	@param nc		Pointer to a nunchuk_t structure.
+ *	@param msg		The message byte specified in the event packet.
+ */
+static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now) {
+	/* message is inverted (0 is active, 1 is inactive) */
+	now = ~now & NUNCHUK_BUTTON_ALL;
+
+	/* pressed now & were pressed, then held */
+	nc->btns_held = (now & nc->btns);
+
+	/* were pressed or were held & not pressed now, then released */
+	nc->btns_released = ((nc->btns | nc->btns_held) & ~now);
+
+	/* buttons pressed now */
+	nc->btns = now;
+}
+
+
+/**
+ *	@brief	Set the orientation event threshold for the nunchuk.
+ *
+ *	@param wm			Pointer to a wiimote_t structure with a nunchuk attached.
+ *	@param threshold	The decimal place that should be considered a significant change.
+ *
+ *	See wiic_set_orient_threshold() for details.
+ */
+void wiic_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold) {
+	if (!wm)	return;
+
+	wm->exp.nunchuk.orient_threshold = threshold;
+}
+
+
+/**
+ *	@brief	Set the accelerometer event threshold for the nunchuk.
+ *
+ *	@param wm			Pointer to a wiimote_t structure with a nunchuk attached.
+ *	@param threshold	The decimal place that should be considered a significant change.
+ *
+ *	See wiic_set_orient_threshold() for details.
+ */
+void wiic_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold) {
+	if (!wm)	return;
+
+	wm->exp.nunchuk.accel_threshold = threshold;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h	(revision 9780)
@@ -0,0 +1,56 @@
+/*
+ *    nunchuck.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief Nunchuk expansion device.
+ */
+
+#ifndef NUNCHUK_H_INCLUDED
+#define NUNCHUK_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len);
+
+void nunchuk_disconnected(struct nunchuk_t* nc);
+
+void nunchuk_event(struct nunchuk_t* nc, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NUNCHUK_H_INCLUDED
Index: code/branches/wiimote/src/external/wiicpp/wiic/speaker.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/speaker.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/speaker.c	(revision 9780)
@@ -0,0 +1,159 @@
+/*
+ *	speaker.c
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Handles the Wiimote speakers.
+ */
+//#pragma pack(nopack)
+#include "wiic_internal.h"
+#include "speaker.h"
+
+void wiic_set_speaker(struct wiimote_t* wm, int status) {
+		
+	if (status) {
+		// if already enabled then stop
+		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER))
+			return;
+			
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER);
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_MUTE);
+		
+		byte buf;
+		  
+		/* Initialization Protocol */
+	
+		// Enable Speaker
+		buf = 0x04;
+		wiic_send(wm, WM_CMD_SPEAKER_ENABLE, &buf, 1);
+		  
+		// Mute Speaker
+		buf = 0x04;
+		wiic_send(wm, WM_CMD_SPEAKER_MUTE, &buf, 1);
+		  
+		// Write 0x01 to register 0xa20009
+		buf = 0x01;
+		wiic_write_data(wm, 0x04a20009, &buf, 1);
+    
+		// Write 0x08 to register 0xa20001
+		buf = 0x08;
+		wiic_write_data(wm, 0x04a20001, &buf, 1);
+		  		  
+ 		// 1st byte for configuration 
+ 		buf = 0x00;
+ 		wiic_write_data(wm, 0x04a20001, &buf, 1);
+ 		// 2nd byte for configuration
+ 		buf = 0x00;
+ 		wiic_write_data(wm, 0x04a20002, &buf, 1);
+ 		// 3rd byte for configuration
+ 		buf = 0xD0;
+ 		wiic_write_data(wm, 0x04a20003, &buf, 1);
+ 		// 4th byte for configuration
+ 		buf = 0x07;
+ 		wiic_write_data(wm, 0x04a20004, &buf, 1);
+ 		// 5th byte for configuration
+ 		buf = 40;
+ 		wiic_write_data(wm, 0x04a20005, &buf, 1);
+ 		// 6th byte for configuration
+ 		buf = 0x00;
+ 		wiic_write_data(wm, 0x04a20006, &buf, 1);
+ 		// 7th byte for configuration
+ 		buf = 0x00;
+ 		wiic_write_data(wm, 0x04a20007, &buf, 1);
+		  
+		// Write 0x01 to register 0xa20008
+		buf = 0x01;
+		wiic_write_data(wm, 0x04a20008, &buf, 1);
+	  
+		// Unmute Speaker
+		buf = 0x00;
+		wiic_send(wm, WM_CMD_SPEAKER_MUTE, &buf, 1);	  
+
+		WIIC_DEBUG("Speaker enabled");
+	} 
+	else {
+		// if already disabled then stop 
+		if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER)) 
+			return;
+		
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_SPEAKER);
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_MUTE);
+		WIIC_DEBUG("Speaker disabled");
+		byte buf = 0x00;
+		wiic_send(wm, WM_CMD_SPEAKER_ENABLE, &buf, 1);
+	}
+
+	/* set the wiimote report type */
+	wiic_set_report_type(wm);
+	
+	/* wait for the wiimote to catch up */
+	usleep(50000);	
+}
+
+
+void wiic_mute_speaker(struct wiimote_t* wm, int status) {
+
+	if (status) {
+		// if already enabled then stop
+		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER_MUTE))
+			return;
+			
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_MUTE);
+		WIIC_DEBUG("Speaker unmuted");
+		byte buf = 0x00;
+		wiic_send(wm, WM_CMD_SPEAKER_MUTE, &buf, 1);
+	} 	
+    else {
+		// if already disabled then stop
+		if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER_MUTE))
+			return;
+			
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_MUTE);
+		WIIC_DEBUG("Speaker muted");
+		byte buf = 0x04;
+		wiic_send(wm, WM_CMD_SPEAKER_MUTE, &buf, 1);
+	}
+}
+
+void wiic_sound(struct wiimote_t* wm) {	
+	/*Working buffer*/
+	unsigned char buf1[21] = {0xA0, 0xC3, 0xC3, 0xC3, 0xC3,0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,0xC3, 0xC3, 0xC3, 0xC3};	
+	
+	int t;
+
+ 	for(t = 0; t <= 50; t++) {
+   	    wiic_send(wm, WM_CMD_SPEAKER_DATA, buf1, 21);
+   	    usleep(50000);
+   	}
+	
+	/* set the wiimote report type */
+	wiic_set_report_type(wm);
+	
+	/* wait for the wiimote to catch up */
+	usleep(50000);
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/speaker.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/speaker.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/speaker.h	(revision 9780)
@@ -0,0 +1,51 @@
+/*
+ *	speaker.h
+ *
+ *	Written By:
+ *		Gabriele Randelli	
+ *		Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
+ *
+ *	Copyright 2010
+ *
+ *	This file is part of wiiC.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	$Header$
+ *
+ */
+
+/**
+ *	@file
+ *	@brief Handles the Wiimote speakers.
+ */
+#ifndef SPEAKER_H_INCLUDED
+#define SPEAKER_H_INCLUDED
+
+#include "wiic_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wiic_set_speaker(struct wiimote_t* wm, int status);
+void wiic_mute_speaker(struct wiimote_t* wm, int status);
+void wiic_sound(struct wiimote_t* wm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPEAKER_H_INCLUDED
+
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic.c	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic.c	(revision 9780)
@@ -0,0 +1,720 @@
+/*
+ *    wiic.c
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief General wiimote operations.
+ *
+ *	The file includes functions that handle general
+ *	tasks.  Most of these are functions that are part
+ *	of the API.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "definitions.h"
+#include "wiic_internal.h"
+#include "events.h"
+#include "io.h"
+
+static int g_banner = 0;
+
+/**
+ *	@breif Returns the version of the library.
+ */
+const char* wiic_version() {
+	return WIIC_VERSION;
+}
+
+
+/**
+ *	@brief Clean up wiimote_t array created by wiic_init()
+ */
+void wiic_cleanup(struct wiimote_t** wm, int wiimotes) {
+	int i = 0;
+
+	if (!wm)
+		return;
+
+	WIIC_DEBUG("wiiC clean up...");
+
+	for (; i < wiimotes; ++i) {
+		wiic_disconnect(wm[i]);
+		free(wm[i]);
+	}
+
+	free(wm);
+
+	return;
+}
+
+
+/**
+ *	@brief Initialize an array of wiimote structures.
+ *
+ *	@param wiimotes		Number of wiimote_t structures to create.
+ *
+ *	@return An array of initialized wiimote_t structures.
+ *
+ *	@see wiic_connect()
+ *
+ *	The array returned by this function can be passed to various
+ *	functions, including wiic_connect().
+ */
+struct wiimote_t** wiic_init(int wiimotes) {
+	int i = 0;
+	struct wiimote_t** wm = NULL;
+
+	/*
+	 *	Please do not remove this banner.
+	 *	GPL asks that you please leave output credits intact.
+	 *	Thank you.
+	 *
+	 *	This banner is only displayed once so that if you need
+	 *	to call this function again it won't be intrusive.
+	 */
+	if (!g_banner) {
+		WIIC_DEBUG(	"WiiC v" WIIC_VERSION " loaded.\n"
+				"By: Gabriele Randelli <randelli[at]dis{dot}uniroma1{dot}it>\n"
+				"http://www.dis.uniroma1.it/~randelli\n\n");
+		g_banner = 1;
+	}
+
+	if (!wiimotes)
+		return NULL;
+
+	wm = malloc(sizeof(struct wiimote_t*) * wiimotes);
+
+	for (i = 0; i < wiimotes; ++i) {
+		wm[i] = malloc(sizeof(struct wiimote_t));
+		memset(wm[i], 0, sizeof(struct wiimote_t));
+
+		wm[i]->unid = i+1;
+
+		#ifdef __APPLE__
+			wm[i]->device = 0;
+			wm[i]->address = 0;
+			wm[i]->inputCh = 0;
+			wm[i]->outputCh = 0;
+			wm[i]->disconnectionRef = 0;
+			wm[i]->connectionHandler = 0;
+		#elif LINUX
+			wm[i]->bdaddr = *BDADDR_ANY;
+			wm[i]->out_sock = -1;
+			wm[i]->in_sock = -1;	
+		#endif
+
+		wm[i]->state = WIIMOTE_INIT_STATES;
+		wm[i]->flags = WIIC_INIT_FLAGS;
+		wm[i]->autoreconnect = 0;
+		wm[i]->event = WIIC_NONE;
+
+		wm[i]->exp.type = EXP_NONE;
+
+		wiic_set_aspect_ratio(wm[i], WIIC_ASPECT_4_3);
+		wiic_set_ir_position(wm[i], WIIC_IR_ABOVE);
+
+		wm[i]->orient_threshold = 0.5f;
+		wm[i]->accel_threshold = 5;
+
+		wm[i]->accel_calib.st_alpha = WIIC_DEFAULT_SMOOTH_ALPHA;
+		
+		gettimeofday(&(wm[i]->timestamp),0);
+	}
+
+	return wm;
+}
+
+
+/**
+ *	@brief	The wiimote disconnected.
+ *
+ *	@param wm	Pointer to a wiimote_t structure.
+ */
+void wiic_disconnected(struct wiimote_t* wm) {
+	if (!wm)	return;
+	
+	// Auto-reconnect?
+	if(wm->autoreconnect && wiic_connect_single(wm,NULL,1))
+		return;
+		
+	WIIC_INFO("Wiimote disconnected [id %i].", wm->unid);
+
+	/* disable the connected flag */
+	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+
+	/* reset a bunch of stuff */
+	#if __APPLE__ // MacOSX
+		if(wm->inputCh) {
+			IOBluetoothObjectRelease(wm->inputCh);
+			wm->inputCh = 0;
+		}
+		if(wm->outputCh) {
+			IOBluetoothObjectRelease(wm->outputCh);			
+			wm->outputCh = 0;			
+		}
+	#else // Linux
+		wm->out_sock = -1;
+		wm->in_sock = -1;
+	#endif
+
+	wm->leds = 0;
+	wm->state = WIIMOTE_INIT_STATES;
+	wm->read_req = NULL;
+	wm->handshake_state = 0;
+	wm->btns = 0;
+	wm->btns_held = 0;
+	wm->btns_released = 0;
+	memset(wm->event_buf, 0, sizeof(wm->event_buf));
+	wm->event = WIIC_DISCONNECT;
+}
+
+
+/**
+ *	@brief	Enable or disable the rumble.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param status	1 to enable, 0 to disable.
+ */
+void wiic_rumble(struct wiimote_t* wm, int status) {
+	byte buf;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return;
+
+	/* make sure to keep the current lit leds */
+	buf = wm->leds;
+
+	if (status) {
+		WIIC_DEBUG("Starting rumble...");
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
+	} else {
+		WIIC_DEBUG("Stopping rumble...");
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
+	}
+
+	/* preserve IR state */
+	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+		buf |= 0x04;
+
+	wiic_send(wm, WM_CMD_RUMBLE, &buf, 1);
+}
+
+
+/**
+ *	@brief	Toggle the state of the rumble.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ */
+void wiic_toggle_rumble(struct wiimote_t* wm) {
+	if (!wm)	return;
+
+	wiic_rumble(wm, !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE));
+}
+
+
+/**
+ *	@brief	Set the enabled LEDs.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param leds		What LEDs to enable.
+ *
+ *	\a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4.
+ */
+void wiic_set_leds(struct wiimote_t* wm, int leds) {
+	byte buf;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) 
+		return;
+
+	/* remove the lower 4 bits because they control rumble */
+	wm->leds = (leds & 0xF0);
+	buf = wm->leds;
+
+	wiic_send(wm, WM_CMD_LED, &buf, 1);
+}
+
+
+/**
+ *	@brief	Set if the wiimote should report motion sensing.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param status	1 to enable, 0 to disable.
+ *
+ *	Since reporting motion sensing sends a lot of data,
+ *	the wiimote saves power by not transmitting it
+ *	by default.
+ */
+void wiic_motion_sensing(struct wiimote_t* wm, int status) {
+	if (status)
+		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC);
+	else
+		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
+
+	wiic_set_report_type(wm);
+}
+
+
+/**
+ *	@brief	Set the report type based on the current wiimote state.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *
+ *	@return The report type sent.
+ *
+ *	The wiimote reports formatted packets depending on the
+ *	report type that was last requested.  This function will
+ *	update the type of report that should be sent based on
+ *	the current state of the device.
+ */
+int wiic_set_report_type(struct wiimote_t* wm) {
+	byte buf[2];
+	int motion, exp, ir;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return 0;
+
+	buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIC_CONTINUOUS) ? 0x04 : 0x00);	/* set to 0x04 for continuous reporting */
+	buf[1] = 0x00;
+
+	motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC);
+	exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP);
+	ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR);
+
+	if (motion && ir && exp)	buf[1] = WM_RPT_BTN_ACC_IR_EXP;
+	else if (motion && exp)		buf[1] = WM_RPT_BTN_ACC_EXP;
+	else if (motion && ir)		buf[1] = WM_RPT_BTN_ACC_IR;
+	else if (ir && exp)			buf[1] = WM_RPT_BTN_IR_EXP;
+	else if (ir)				buf[1] = WM_RPT_BTN_ACC_IR;
+	else if (exp) 				buf[1] = WM_RPT_BTN_EXP; 
+	else if (motion)			buf[1] = WM_RPT_BTN_ACC;
+	else						buf[1] = WM_RPT_BTN;
+
+	WIIC_DEBUG("Setting report type: 0x%x", buf[1]);
+
+	exp = wiic_send(wm, WM_CMD_REPORT_TYPE, buf, 2);
+	if (exp <= 0)
+		return exp;
+
+	return buf[1];
+}
+
+
+/**
+ *	@brief	Read data from the wiimote (callback version).
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param read_cb	Function pointer to call when the data arrives from the wiimote.
+ *	@param buffer	An allocated buffer to store the data as it arrives from the wiimote.
+ *					Must be persistent in memory and large enough to hold the data.
+ *	@param addr		The address of wiimote memory to read from.
+ *	@param len		The length of the block to be read.
+ *
+ *	The library can only handle one data read request at a time
+ *	because it must keep track of the buffer and other
+ *	events that are specific to that request.  So if a request
+ *	has already been made, subsequent requests will be added
+ *	to a pending list and be sent out when the previous
+ *	finishes.
+ */
+int wiic_read_data_cb(struct wiimote_t* wm, wiic_read_cb read_cb, byte* buffer, unsigned int addr, unsigned short len) {
+	struct read_req_t* req;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return 0;
+	if (!buffer || !len || !read_cb)
+		return 0;
+
+	/* make this request structure */
+	req = (struct read_req_t*)malloc(sizeof(struct read_req_t));
+	req->cb = read_cb;
+	req->buf = buffer;
+	req->addr = addr;
+	req->size = len;
+	req->wait = len;
+	req->dirty = 0;
+	req->next = NULL;
+
+	/* add this to the request list */
+	if (!wm->read_req) {
+		/* root node */
+		wm->read_req = req;
+
+		WIIC_DEBUG("Data read request can be sent out immediately.");
+
+		/* send the request out immediately */
+		wiic_send_next_pending_read_request(wm);
+	} else {
+		struct read_req_t* nptr = wm->read_req;
+		for (; nptr->next; nptr = nptr->next);
+		nptr->next = req;
+
+		WIIC_DEBUG("Added pending data read request.");
+	}
+
+	return 1;
+}
+
+
+/**
+ *	@brief	Read data from the wiimote (event version).
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param buffer	An allocated buffer to store the data as it arrives from the wiimote.
+ *					Must be persistent in memory and large enough to hold the data.
+ *	@param addr		The address of wiimote memory to read from.
+ *	@param len		The length of the block to be read.
+ *
+ *	The library can only handle one data read request at a time
+ *	because it must keep track of the buffer and other
+ *	events that are specific to that request.  So if a request
+ *	has already been made, subsequent requests will be added
+ *	to a pending list and be sent out when the previous
+ *	finishes.
+ */
+int wiic_read_data(struct wiimote_t* wm, byte* buffer, unsigned int addr, unsigned short len) {
+	struct read_req_t* req;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return 0;
+	if (!buffer || !len)
+		return 0;
+
+	/* make this request structure */
+	req = (struct read_req_t*)malloc(sizeof(struct read_req_t));
+	req->cb = NULL;
+	req->buf = buffer;
+	req->addr = addr;
+	req->size = len;
+	req->wait = len;
+	req->dirty = 0;
+	req->next = NULL;
+
+	/* add this to the request list */
+	if (!wm->read_req) {
+		/* root node */
+		wm->read_req = req;
+
+		WIIC_DEBUG("Data read request can be sent out immediately.");
+
+		/* send the request out immediately */
+		wiic_send_next_pending_read_request(wm);
+	} else {
+		struct read_req_t* nptr = wm->read_req;
+		for (; nptr->next; nptr = nptr->next);
+		nptr->next = req;
+
+		WIIC_DEBUG("Added pending data read request.");
+	}
+
+	return 1;
+}
+
+
+/**
+ *	@brief Send the next pending data read request to the wiimote.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *
+ *	@see wiic_read_data()
+ *
+ *	This function is not part of the wiic API.
+ */
+void wiic_send_next_pending_read_request(struct wiimote_t* wm) {
+	byte buf[6];
+	struct read_req_t* req;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return;
+	if (!wm->read_req)	return;
+
+	/* skip over dirty ones since they have already been read */
+	req = wm->read_req;
+	while (req && req->dirty)
+		req = req->next;
+	if (!req)
+		return;
+		
+	/* the offset is in big endian */
+	*(unsigned int*)(buf) = BIG_ENDIAN_LONG(req->addr);
+	/* the length is in big endian */
+	*(unsigned short*)(buf + 4) = BIG_ENDIAN_SHORT(req->size);
+
+	WIIC_DEBUG("Request read at address: 0x%x  length: %i", req->addr, req->size);
+	wiic_send(wm, WM_CMD_READ_DATA, buf, 6);
+}
+
+
+/**
+ *	@brief Request the wiimote controller status.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *
+ *	Controller status includes: battery level, LED status, expansions
+ */
+void wiic_status(struct wiimote_t* wm) {
+	byte buf = 0;
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return;
+
+	WIIC_DEBUG("Requested wiimote status.");
+
+	wiic_send(wm, WM_CMD_CTRL_STATUS, &buf, 1);
+}
+
+
+/**
+ *	@brief Find a wiimote_t structure by its unique identifier.
+ *
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param wiimotes	The number of wiimote_t structures in \a wm.
+ *	@param unid		The unique identifier to search for.
+ *
+ *	@return Pointer to a wiimote_t structure, or NULL if not found.
+ */
+struct wiimote_t* wiic_get_by_id(struct wiimote_t** wm, int wiimotes, int unid) {
+	int i = 0;
+
+	for (; i < wiimotes; ++i) {
+		if (wm[i]->unid == unid)
+			return wm[i];
+	}
+
+	return NULL;
+}
+
+
+/**
+ *	@brief	Write data to the wiimote.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param addr			The address to write to.
+ *	@param data			The data to be written to the memory location.
+ *	@param len			The length of the block to be written.
+ */
+int wiic_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len) {
+	byte buf[21] = {0};		/* the payload is always 23 */
+
+	if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+		return 0;
+	if (!data || !len)
+		return 0;
+
+	WIIC_DEBUG("Writing %i bytes to memory location 0x%x...", len, addr);
+
+	#ifdef WITH_WIIC_DEBUG
+	{
+		int i = 0;
+		printf("Write data is: ");
+		for (; i < len; ++i)
+			printf("%x ", data[i]);
+		printf("\n");
+	}
+	#endif
+
+	/* the offset is in big endian */
+	*(int*)(buf) = BIG_ENDIAN_LONG(addr);
+
+	/* length */
+	*(byte*)(buf + 4) = len;
+
+	/* data */
+	memcpy(buf + 5, data, len);
+
+	wiic_send(wm, WM_CMD_WRITE_DATA, buf, 21);
+	return 1;
+}
+
+
+/**
+ *	@brief	Send a packet to the wiimote.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param report_type	The report type to send (WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc). Found in wiic.h
+ *	@param msg			The payload.
+ *	@param len			Length of the payload in bytes.
+ *
+ *	This function should replace any write()s directly to the wiimote device.
+ */
+int wiic_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) {
+	byte buf[32];		/* no payload is better than this */
+	int rumble = 0;
+
+	buf[0] = WM_SET_REPORT | WM_BT_OUTPUT;
+	buf[1] = report_type;
+
+	switch (report_type) {
+		case WM_CMD_LED:
+		case WM_CMD_RUMBLE:
+		case WM_CMD_CTRL_STATUS:
+		case WM_CMD_REPORT_TYPE:
+		{
+			/* Rumble flag for: 0x11, 0x13, 0x14, 0x15, 0x19 or 0x1a */
+			if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE))
+				rumble = 1;
+			break;
+		}
+		default:
+			break;
+	}
+
+	memcpy(buf+2, msg, len);
+	if (rumble) 
+		buf[2] |= 0x01;
+	else 
+		buf[2] &= 0xFE;	// Fix for Wiiuse bug
+
+	#ifdef WITH_WIIC_DEBUG
+	{
+		int x = 2;
+		printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]);
+		for (; x < len+2; ++x)
+			printf("%.2x ", buf[x]);
+		printf("\n");
+	}
+	#endif
+
+	return wiic_io_write(wm, buf, len+2);
+}
+
+
+/**
+ *	@brief Set flags for the specified wiimote.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param enable		Flags to enable.
+ *	@param disable		Flags to disable.
+ *
+ *	@return The flags set after 'enable' and 'disable' have been applied.
+ *
+ *	The values 'enable' and 'disable' may be any flags OR'ed together.
+ *	Flags are defined in wiic.h.
+ */
+int wiic_set_flags(struct wiimote_t* wm, int enable, int disable) {
+	if (!wm)	return 0;
+
+	/* remove mutually exclusive flags */
+	enable &= ~disable;
+	disable &= ~enable;
+
+	wm->flags |= enable;
+	wm->flags &= ~disable;
+
+	return wm->flags;
+}
+
+
+/**
+ *	@brief Set the wiimote smoothing alpha value.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param alpha		The alpha value to set. Between 0 and 1.
+ *
+ *	@return Returns the old alpha value.
+ *
+ *	The alpha value is between 0 and 1 and is used in an exponential
+ *	smoothing algorithm.
+ *
+ *	Smoothing is only performed if the WIIC_SMOOTHING is set.
+ */
+float wiic_set_smooth_alpha(struct wiimote_t* wm, float alpha) {
+	float old;
+
+	if (!wm)	return 0.0f;
+
+	old = wm->accel_calib.st_alpha;
+
+	wm->accel_calib.st_alpha = alpha;
+
+	/* if there is a nunchuk set that too */
+	if (wm->exp.type == EXP_NUNCHUK)
+		wm->exp.nunchuk.accel_calib.st_alpha = alpha;
+
+	return old;
+}
+
+
+/**
+ *	@brief	Set the orientation event threshold.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param threshold	The decimal place that should be considered a significant change.
+ *
+ *	If threshold is 0.01, and any angle changes by 0.01 then a significant change
+ *	has occured and the event callback will be invoked.  If threshold is 1 then
+ *	the angle has to change by a full degree to generate an event.
+ */
+void wiic_set_orient_threshold(struct wiimote_t* wm, float threshold) {
+	if (!wm)	return;
+
+	wm->orient_threshold = threshold;
+}
+
+
+/**
+ *	@brief	Set the accelerometer event threshold.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ *	@param threshold	The decimal place that should be considered a significant change.
+ */
+void wiic_set_accel_threshold(struct wiimote_t* wm, int threshold) {
+	if (!wm)	return;
+
+	wm->accel_threshold = threshold;
+}
+
+
+/**
+ *	@brief Try to resync with the wiimote by starting a new handshake.
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ */
+void wiic_resync(struct wiimote_t* wm) {
+	if (!wm)	return;
+
+	wm->handshake_state = 0;
+	wiic_handshake(wm, NULL, 0);
+}
+
+/**
+ *	@brief Update the relative timestamp of a wiimote device
+ *
+ *	@param wm			Pointer to a wiimote_t structure.
+ */
+void wiic_update_timestamp(struct wiimote_t* wm)
+{
+	// We retrieve the overall gesture timestamp
+	gettimeofday(&(wm->timestamp),0);
+}
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic.h	(revision 9780)
@@ -0,0 +1,86 @@
+/*
+ *    wiic.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *
+ *	@brief API header file.
+ *
+ *	If this file is included from inside the wiiuse source
+ *	and not from a third party program, then wiimote_internal.h
+ *	is also included which extends this file.
+ */
+#ifndef WIIC_H_INCLUDED
+#define WIIC_H_INCLUDED
+
+#ifdef __APPLE__
+	/* mac */
+	#include <CoreFoundation/CoreFoundation.h>
+	#include <IOBluetooth/IOBluetoothUserLib.h>
+#else
+	/* nix */
+	#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/bluetooth.h"
+#endif
+
+#ifdef WIIC_INTERNAL_H_INCLUDED
+	#define WCONST
+#else
+	#define WCONST		const
+#endif
+
+/*
+ *	Largest known payload is 21 bytes.
+ *	Add 2 for the prefix and round up to a power of 2.
+ */
+#define MAX_PAYLOAD			32
+
+/*****************************************
+ *
+ *	Include API specific stuff
+ *
+ *****************************************/
+
+#define WIIC_EXPORT_DECL
+#define WIIC_IMPORT_DECL
+
+#ifdef WIIC_COMPILE_LIB
+	#define WIIC_EXPORT WIIC_EXPORT_DECL
+#else
+	#define WIIC_EXPORT WIIC_IMPORT_DECL
+#endif
+
+#include "wiic_macros.h"
+#include "wiic_structs.h"
+#include "wiic_functions.h"
+
+
+#endif /* WIIC_H_INCLUDED */
+
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h	(revision 9780)
@@ -0,0 +1,33 @@
+/*
+ *    wiic_doc.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+ /*! \mainpage WiiC
+ *
+ * \section intro_sec Introduction
+ *
+ * This is the introduction.
+ *
+ *  
+ */
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h	(revision 9780)
@@ -0,0 +1,98 @@
+/*
+ *    wiic_functions.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *
+ *	@brief WiiC public functions.
+ *
+ *	Contains all the public functions, available for third
+ *	party applications. This header is included in wiic.h.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* wiic.c */
+WIIC_EXPORT extern const char* wiic_version();
+
+WIIC_EXPORT extern struct wiimote_t** wiic_init(int wiimotes);
+WIIC_EXPORT extern void wiic_disconnected(struct wiimote_t* wm);
+WIIC_EXPORT extern void wiic_cleanup(struct wiimote_t** wm, int wiimotes);
+WIIC_EXPORT extern void wiic_rumble(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern void wiic_toggle_rumble(struct wiimote_t* wm);
+WIIC_EXPORT extern void wiic_set_leds(struct wiimote_t* wm, int leds);
+WIIC_EXPORT extern void wiic_motion_sensing(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern int wiic_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len);
+WIIC_EXPORT extern int wiic_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len);
+WIIC_EXPORT extern void wiic_status(struct wiimote_t* wm);
+WIIC_EXPORT extern struct wiimote_t* wiic_get_by_id(struct wiimote_t** wm, int wiimotes, int unid);
+WIIC_EXPORT extern int wiic_set_flags(struct wiimote_t* wm, int enable, int disable);
+WIIC_EXPORT extern float wiic_set_smooth_alpha(struct wiimote_t* wm, float alpha);
+WIIC_EXPORT extern void wiic_set_orient_threshold(struct wiimote_t* wm, float threshold);
+WIIC_EXPORT extern void wiic_resync(struct wiimote_t* wm);
+WIIC_EXPORT extern void wiic_set_accel_threshold(struct wiimote_t* wm, int threshold);
+WIIC_EXPORT extern void wiic_update_timestamp(struct wiimote_t* wm);
+
+/* connect.c */
+WIIC_EXPORT extern int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
+WIIC_EXPORT extern int wiic_load(struct wiimote_t** wm);
+WIIC_EXPORT extern int wiic_connect(struct wiimote_t** wm, int wiimotes, int autoreconnect);
+WIIC_EXPORT extern int wiic_connect_single(struct wiimote_t* wm, char* address, int autoreconnect);
+WIIC_EXPORT extern void wiic_disconnect(struct wiimote_t* wm);
+
+/* events.c */
+WIIC_EXPORT extern int wiic_poll(struct wiimote_t** wm, int wiimotes);
+
+/* ir.c */
+WIIC_EXPORT extern void wiic_set_ir(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern void wiic_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y);
+WIIC_EXPORT extern void wiic_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos);
+WIIC_EXPORT extern void wiic_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect);
+WIIC_EXPORT extern void wiic_set_ir_sensitivity(struct wiimote_t* wm, int level);
+
+/* nunchuk.c */
+WIIC_EXPORT extern void wiic_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold);
+WIIC_EXPORT extern void wiic_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold);
+
+/* speaker.c */
+WIIC_EXPORT extern void wiic_set_speaker(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern void wiic_mute_speaker(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern void wiic_sound(struct wiimote_t* wm);
+
+/* motionplus.c */
+WIIC_EXPORT extern void wiic_set_motion_plus(struct wiimote_t* wm, int status);
+WIIC_EXPORT extern void wiic_calibrate_motion_plus(struct motion_plus_t* mp);
+WIIC_EXPORT extern void wiic_set_mp_threshold(struct wiimote_t* wm, int threshold);
+
+#ifdef __cplusplus
+}
+#endif
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h	(revision 9780)
@@ -0,0 +1,232 @@
+/*
+ *    wiic_internal.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *	@brief General internal wiic stuff.
+ *
+ *	Since WiiC is a library, wiic.h is a duplicate
+ *	of the API header.
+ *
+ *	The code that would normally go in that file, but
+ *	which is not needed by third party developers,
+ *	is put here.
+ *
+ *	So wiic_internal.h is included by other files
+ *	internally, wiic.h is included only here.
+ */
+
+#ifndef WIIC_INTERNAL_H_INCLUDED
+#define WIIC_INTERNAL_H_INCLUDED
+
+#ifndef __APPLE__
+	#include <arpa/inet.h>				/* htons() */
+	#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/bluetooth.h"
+#endif
+
+#include "definitions.h"
+
+/* WiiC version */
+#define WIIC_VERSION					"1.2"
+#define WIIC_LOG_VERSION				 1.0
+
+/********************
+ *
+ *	Wiimote internal codes
+ *
+ ********************/
+
+/* Communication channels */
+#define WM_OUTPUT_CHANNEL			0x11
+#define WM_INPUT_CHANNEL			0x13
+
+#define WM_SET_REPORT				0x50
+
+/* commands */
+#define WM_CMD_LED					0x11
+#define WM_CMD_REPORT_TYPE			0x12
+#define WM_CMD_RUMBLE				0x13
+#define WM_CMD_IR					0x13
+#define WM_CMD_SPEAKER_ENABLE		0x14
+#define WM_CMD_CTRL_STATUS			0x15
+#define WM_CMD_WRITE_DATA			0x16
+#define WM_CMD_READ_DATA			0x17
+#define WM_CMD_SPEAKER_DATA			0x18
+#define WM_CMD_SPEAKER_MUTE			0x19
+#define WM_CMD_IR_2					0x1A
+
+/* input report ids */
+#define WM_RPT_CTRL_STATUS			0x20
+#define WM_RPT_READ					0x21
+#define WM_RPT_WRITE				0x22
+#define WM_RPT_BTN					0x30
+#define WM_RPT_BTN_ACC				0x31
+#define WM_RPT_BTN_ACC_IR			0x33
+#define WM_RPT_BTN_EXP				0x34
+#define WM_RPT_BTN_ACC_EXP			0x35
+#define WM_RPT_BTN_IR_EXP			0x36
+#define WM_RPT_BTN_ACC_IR_EXP		0x37
+
+#define WM_BT_INPUT					0x01
+#define WM_BT_OUTPUT				0x02
+
+/* Identify the wiimote device by its class */
+
+/*
+ * The different codes wrt. to Linux
+ * is a bit hard to explain.
+ * Looking at Bluetooth CoD format, we have 24 bits.
+ * In wiic Linux they are stored in three fields,
+ * each one 8bit long. The result number is
+ * 0x002504. However, MacOS Bluetooth does
+ * not store them in such a way, rather it uses
+ * the concept of major service, major class,
+ * and minor class, that are respectivelly
+ * 11bit, 5bit, and 6bit long. Hence, the 
+ * numbers are different.
+ * The Wiimote CoD Bluetooth division is the following:
+ * 00000000001 00101 000001 00 (major service - major class - minor class - format type)
+ * This can also be seen in the WiiC Linux way:
+ * 00000000 00100101 00000100 
+ */
+#ifdef __APPLE__
+	#define WM_DEV_MINOR_CLASS				0x01
+	#define WM_DEV_MAJOR_CLASS				0x05
+	#define WM_DEV_MAJOR_SERVICE			0x01
+#else
+	#define WM_DEV_CLASS_0				0x04
+	#define WM_DEV_CLASS_1				0x25
+	#define WM_DEV_CLASS_2				0x00
+#endif
+#define WM_VENDOR_ID				0x057E
+#define WM_PRODUCT_ID				0x0306
+
+/* controller status stuff */
+#define WM_MAX_BATTERY_CODE			0xC8
+
+/* offsets in wiimote memory */
+#define WM_MEM_OFFSET_CALIBRATION	0x16
+#define WM_EXP_MEM_BASE				0x04A40000
+#define WM_EXP_MEM_ENABLE			0x04A40040
+#define WM_EXP_MEM_CALIBR			0x04A40020
+#define WM_EXP_ID					0x04A400FA
+#define EXP_HANDSHAKE_LEN					224
+
+#define WM_REG_IR					0x04B00030
+#define WM_REG_IR_BLOCK1			0x04B00000
+#define WM_REG_IR_BLOCK2			0x04B0001A
+#define WM_REG_IR_MODENUM			0x04B00033
+
+/* 
+ * Motion Plus (please note that the first 
+ * "04" in these addresses
+ * is to enable register write) 
+ */
+#define WM_MOTION_PLUS_INIT			0x04A600F0
+#define WM_MOTION_PLUS_ID_ADDR		0x04A400FA	/** This register contains the Motion Plus ID, if correctly activated */
+#define WM_MOTION_PLUS_ENABLE		0x04A600FE // We're using the unencrypted version
+#define WM_MOTION_PLUS_DISABLE		0x04A400F0
+
+/* ir block data */
+#define WM_IR_BLOCK1_LEVEL1			"\x02\x00\x00\x71\x01\x00\x64\x00\xfe"
+#define WM_IR_BLOCK2_LEVEL1			"\xfd\x05"
+#define WM_IR_BLOCK1_LEVEL2			"\x02\x00\x00\x71\x01\x00\x96\x00\xb4"
+#define WM_IR_BLOCK2_LEVEL2			"\xb3\x04"
+#define WM_IR_BLOCK1_LEVEL3			"\x02\x00\x00\x71\x01\x00\xaa\x00\x64"
+#define WM_IR_BLOCK2_LEVEL3			"\x63\x03"
+#define WM_IR_BLOCK1_LEVEL4			"\x02\x00\x00\x71\x01\x00\xc8\x00\x36"
+#define WM_IR_BLOCK2_LEVEL4			"\x35\x03"
+#define WM_IR_BLOCK1_LEVEL5			"\x07\x00\x00\x71\x01\x00\x72\x00\x20"
+#define WM_IR_BLOCK2_LEVEL5			"\x1f\x03"
+
+#define WM_IR_TYPE_BASIC			0x01
+#define WM_IR_TYPE_EXTENDED			0x03
+
+/* controller status flags for the first message byte */
+/* bit 1 is unknown */
+#define WM_CTRL_STATUS_BYTE1_ATTACHMENT			0x02
+#define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED	0x04
+#define WM_CTRL_STATUS_BYTE1_IR_ENABLED			0x08
+#define WM_CTRL_STATUS_BYTE1_LED_1				0x10
+#define WM_CTRL_STATUS_BYTE1_LED_2				0x20
+#define WM_CTRL_STATUS_BYTE1_LED_3				0x40
+#define WM_CTRL_STATUS_BYTE1_LED_4				0x80
+
+/* aspect ratio */
+#define WM_ASPECT_16_9_X	660
+#define WM_ASPECT_16_9_Y	370
+#define WM_ASPECT_4_3_X		560
+#define WM_ASPECT_4_3_Y		420
+
+
+/**
+ *	Expansion stuff
+ */
+
+/* encrypted expansion id codes (located at 0x04A400FC) */
+#define EXP_ID_CODE_NUNCHUK					0x9A1EFEFE
+#define EXP_ID_CODE_CLASSIC_CONTROLLER		0x9A1EFDFD
+#define EXP_ID_CODE_GUITAR					0x9A1EFDFB
+/* unencrypted expansion id codes */
+#define EXP_ID_CODE_MOTION_PLUS				0xA4200405 /** Motion Plus ID (when activated) */
+#define EXP_ID_BALANCE_BOARD				0xA4200402
+
+/********************
+ *
+ *	End Wiimote internal codes
+ *
+ ********************/
+
+/*
+ *	Smooth tilt calculations are computed with the
+ *	exponential moving average formula:
+ *		St = St_last + (alpha * (tilt - St_last))
+ *	alpha is between 0 and 1
+ */
+#define WIIC_DEFAULT_SMOOTH_ALPHA			0.9f
+
+#include "wiic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* not part of the api */
+int wiic_set_report_type(struct wiimote_t* wm);
+void wiic_send_next_pending_read_request(struct wiimote_t* wm);
+int wiic_send(struct wiimote_t* wm, byte report_type, byte* msg, int len);
+int wiic_read_data_cb(struct wiimote_t* wm, wiic_read_cb read_cb, byte* buffer, unsigned int offset, unsigned short len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WIIC_INTERNAL_H_INCLUDED */
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h	(revision 9780)
@@ -0,0 +1,243 @@
+/*
+ *    wiic_macros.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *
+ *	@brief WiiC macros and typedef.
+ *
+ *	Contains all the macros to manage the state of the Wiimote,
+ *	its component, and other devices, as well as some useful 
+ *	typedef. This header is included in wiic.h.
+ */
+/* wiimote state flags */
+#define WIIMOTE_STATE_DEV_FOUND				0x00001
+#define WIIMOTE_STATE_HANDSHAKE				0x00002	/* actual connection exists but no handshake yet */
+#define WIIMOTE_STATE_HANDSHAKE_COMPLETE	0x00004	/* actual connection exists but no handshake yet */
+#define WIIMOTE_STATE_CONNECTED				0x00008
+#define WIIMOTE_STATE_RUMBLE				0x00010
+#define WIIMOTE_STATE_ACC					0x00020
+#define WIIMOTE_STATE_EXP					0x00040
+#define WIIMOTE_STATE_IR					0x00080
+#define WIIMOTE_STATE_SPEAKER				0x00100
+#define WIIMOTE_STATE_IR_SENS_LVL1			0x00200
+#define WIIMOTE_STATE_IR_SENS_LVL2			0x00400
+#define WIIMOTE_STATE_IR_SENS_LVL3			0x00800
+#define WIIMOTE_STATE_IR_SENS_LVL4			0x01000
+#define WIIMOTE_STATE_IR_SENS_LVL5			0x02000
+#define WIIMOTE_STATE_EXP_HANDSHAKE			0x04000	/* Added to handle handshaking concurrency between Motion Plus and other expansion types */
+#define WIIMOTE_STATE_EXP_FAILED			0x08000
+#define WIIMOTE_STATE_MOTION_PLUS			0x10000 /**< MotionPlus state flag, set when the MotionPlus is used */	
+#define WIIMOTE_STATE_SPEAKER_MUTE			0x20000 /**< Speaker Mute */	
+
+#define WIIMOTE_INIT_STATES					(WIIMOTE_STATE_IR_SENS_LVL3)
+
+/* macro to manage states */
+#define WIIMOTE_IS_SET(wm, s)			((wm->state & (s)) == (s))
+#define WIIMOTE_ENABLE_STATE(wm, s)		(wm->state |= (s))
+#define WIIMOTE_DISABLE_STATE(wm, s)	(wm->state &= ~(s))
+#define WIIMOTE_TOGGLE_STATE(wm, s)		((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s))
+
+/* macro to manage flags */
+#define WIIMOTE_IS_FLAG_SET(wm, s)		((wm->flags & (s)) == (s))
+#define WIIMOTE_ENABLE_FLAG(wm, s)		(wm->flags |= (s))
+#define WIIMOTE_DISABLE_FLAG(wm, s)		(wm->flags &= ~(s))
+#define WIIMOTE_TOGGLE_FLAG(wm, s)		((wm->flags & (s)) ? WIIMOTE_DISABLE_FLAG(wm, s) : WIIMOTE_ENABLE_FLAG(wm, s))
+
+#define NUNCHUK_IS_FLAG_SET(wm, s)		((*(wm->flags) & (s)) == (s))
+
+/* misc macros */
+#define WIIMOTE_ID(wm)					(wm->unid)
+#define WIIMOTE_IS_CONNECTED(wm)		(WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED))
+
+/* led bit masks */
+#define WIIMOTE_LED_NONE				0x00
+#define WIIMOTE_LED_1					0x10
+#define WIIMOTE_LED_2					0x20
+#define WIIMOTE_LED_3					0x40
+#define WIIMOTE_LED_4					0x80
+
+/* button codes */
+#define WIIMOTE_BUTTON_TWO				0x0001
+#define WIIMOTE_BUTTON_ONE				0x0002
+#define WIIMOTE_BUTTON_B				0x0004
+#define WIIMOTE_BUTTON_A				0x0008
+#define WIIMOTE_BUTTON_MINUS			0x0010
+#define WIIMOTE_BUTTON_ZACCEL_BIT6		0x0020
+#define WIIMOTE_BUTTON_ZACCEL_BIT7		0x0040
+#define WIIMOTE_BUTTON_HOME				0x0080
+#define WIIMOTE_BUTTON_LEFT				0x0100
+#define WIIMOTE_BUTTON_RIGHT			0x0200
+#define WIIMOTE_BUTTON_DOWN				0x0400
+#define WIIMOTE_BUTTON_UP				0x0800
+#define WIIMOTE_BUTTON_PLUS				0x1000
+#define WIIMOTE_BUTTON_ZACCEL_BIT4		0x2000
+#define WIIMOTE_BUTTON_ZACCEL_BIT5		0x4000
+#define WIIMOTE_BUTTON_UNKNOWN			0x8000
+#define WIIMOTE_BUTTON_ALL				0x1F9F
+
+/* nunchuk button codes */
+#define NUNCHUK_BUTTON_Z				0x01
+#define NUNCHUK_BUTTON_C				0x02
+#define NUNCHUK_BUTTON_ALL				0x03
+
+/* classic controller button codes */
+#define CLASSIC_CTRL_BUTTON_UP			0x0001
+#define CLASSIC_CTRL_BUTTON_LEFT		0x0002
+#define CLASSIC_CTRL_BUTTON_ZR			0x0004
+#define CLASSIC_CTRL_BUTTON_X			0x0008
+#define CLASSIC_CTRL_BUTTON_A			0x0010
+#define CLASSIC_CTRL_BUTTON_Y			0x0020
+#define CLASSIC_CTRL_BUTTON_B			0x0040
+#define CLASSIC_CTRL_BUTTON_ZL			0x0080
+#define CLASSIC_CTRL_BUTTON_FULL_R		0x0200
+#define CLASSIC_CTRL_BUTTON_PLUS		0x0400
+#define CLASSIC_CTRL_BUTTON_HOME		0x0800
+#define CLASSIC_CTRL_BUTTON_MINUS		0x1000
+#define CLASSIC_CTRL_BUTTON_FULL_L		0x2000
+#define CLASSIC_CTRL_BUTTON_DOWN		0x4000
+#define CLASSIC_CTRL_BUTTON_RIGHT		0x8000
+#define CLASSIC_CTRL_BUTTON_ALL			0xFEFF
+
+/* guitar hero 3 button codes */
+#define GUITAR_HERO_3_BUTTON_STRUM_UP	0x0001
+#define GUITAR_HERO_3_BUTTON_YELLOW		0x0008
+#define GUITAR_HERO_3_BUTTON_GREEN		0x0010
+#define GUITAR_HERO_3_BUTTON_BLUE		0x0020
+#define GUITAR_HERO_3_BUTTON_RED		0x0040
+#define GUITAR_HERO_3_BUTTON_ORANGE		0x0080
+#define GUITAR_HERO_3_BUTTON_PLUS		0x0400
+#define GUITAR_HERO_3_BUTTON_MINUS		0x1000
+#define GUITAR_HERO_3_BUTTON_STRUM_DOWN	0x4000
+#define GUITAR_HERO_3_BUTTON_ALL		0xFEFF
+
+
+/* wiimote option flags */
+#define WIIC_SMOOTHING				0x01
+#define WIIC_CONTINUOUS				0x04 
+#define WIIC_ORIENT_THRESH			0x04
+#define WIIC_INIT_FLAGS				(WIIC_SMOOTHING | WIIC_ORIENT_THRESH)
+
+/* expansion codes */
+#define EXP_NONE						0
+#define EXP_NUNCHUK						1
+#define EXP_CLASSIC						2
+#define EXP_GUITAR_HERO_3				3
+#define EXP_MOTION_PLUS					4
+#define EXP_BALANCE_BOARD				5
+
+/**
+ *	@brief Check if a button is pressed.
+ *	@param dev		Pointer to a wiimote_t or expansion structure.
+ *	@param button	The button you are interested in.
+ *	@return 1 if the button is pressed, 0 if not.
+ */
+#define IS_PRESSED(dev, button)		((dev->btns & button) == button)
+
+/**
+ *	@brief Check if a button is being held.
+ *	@param dev		Pointer to a wiimote_t or expansion structure.
+ *	@param button	The button you are interested in.
+ *	@return 1 if the button is held, 0 if not.
+ */
+#define IS_HELD(dev, button)			((dev->btns_held & button) == button)
+
+/**
+ *	@brief Check if a button is released on this event.					\n\n
+ *			This does not mean the button is not pressed, it means		\n
+ *			this button was just now released.
+ *	@param dev		Pointer to a wiimote_t or expansion structure.
+ *	@param button	The button you are interested in.
+ *	@return 1 if the button is released, 0 if not.
+ *
+ */
+#define IS_RELEASED(dev, button)		((dev->btns_released & button) == button)
+
+/**
+ *	@brief Check if a button has just been pressed this event.
+ *	@param dev		Pointer to a wiimote_t or expansion structure.
+ *	@param button	The button you are interested in.
+ *	@return 1 if the button is pressed, 0 if not.
+ */
+#define IS_JUST_PRESSED(dev, button)	(IS_PRESSED(dev, button) && !IS_HELD(dev, button))
+
+/**
+ *	@brief Return the IR sensitivity level.
+ *	@param wm		Pointer to a wiimote_t structure.
+ *	@param lvl		[out] Pointer to an int that will hold the level setting.
+ *	If no level is set 'lvl' will be set to 0.
+ */
+#define WIIC_GET_IR_SENSITIVITY(wm, lvl)									\
+			do {														\
+				if ((wm->state & WIIMOTE_STATE_IR_SENS_LVL1) == WIIMOTE_STATE_IR_SENS_LVL1) 		*lvl = 1;	\
+				else if ((wm->state & WIIMOTE_STATE_IR_SENS_LVL2) == WIIMOTE_STATE_IR_SENS_LVL2) 	*lvl = 2;	\
+				else if ((wm->state & WIIMOTE_STATE_IR_SENS_LVL3) == WIIMOTE_STATE_IR_SENS_LVL3) 	*lvl = 3;	\
+				else if ((wm->state & WIIMOTE_STATE_IR_SENS_LVL4) == WIIMOTE_STATE_IR_SENS_LVL4) 	*lvl = 4;	\
+				else if ((wm->state & WIIMOTE_STATE_IR_SENS_LVL5) == WIIMOTE_STATE_IR_SENS_LVL5) 	*lvl = 5;	\
+				else									*lvl = 0;		\
+			} while (0)
+
+#define WIIC_USING_ACC(wm)			((wm->state & WIIMOTE_STATE_ACC) == WIIMOTE_STATE_ACC)
+#define WIIC_USING_EXP(wm)			((wm->state & WIIMOTE_STATE_EXP) == WIIMOTE_STATE_EXP)
+#define WIIC_USING_IR(wm)				((wm->state & WIIMOTE_STATE_IR) == WIIMOTE_STATE_IR)
+#define WIIC_USING_SPEAKER(wm)		((wm->state & WIIMOTE_STATE_SPEAKER) == WIIMOTE_STATE_SPEAKER)
+#define WIIC_SPEAKER_MUTED(wm)		((wm->state & WIIMOTE_STATE_SPEAKER_MUTE) == WIIMOTE_STATE_SPEAKER_MUTE)
+#define WIIC_USING_MOTION_PLUS(wm)	((wm->state & WIIMOTE_STATE_MOTION_PLUS) == WIIMOTE_STATE_MOTION_PLUS)
+#define WIIC_IS_LED_SET(wm, num)		((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num)
+
+/** TYPEDEFS */
+typedef unsigned char byte;
+typedef char sbyte;
+
+/**
+ *      @brief Callback that handles a read event.
+ *
+ *      @param wm               Pointer to a wiimote_t structure.
+ *      @param data             Pointer to the filled data block.
+ *      @param len              Length in bytes of the data block.
+ *
+ *      @see wiic_init()
+ *
+ *      A registered function of this type is called automatically by the wiiuse
+ *      library when the wiimote has returned the full data requested by a previous
+ *      call to wiiuse_read_data().
+ */
+struct wiimote_t;
+typedef void (*wiic_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len);
+
+/**
+ *	@enum aspect_t
+ *	@brief Screen aspect ratio.
+ */
+typedef enum aspect_t {
+	WIIC_ASPECT_4_3,
+	WIIC_ASPECT_16_9
+} aspect_t;
Index: code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h	(revision 9780)
@@ -0,0 +1,474 @@
+/*
+ *    wiic_structs.h
+ *
+ *	  This file is part of WiiC, written by:
+ *		Gabriele Randelli
+ *		Email: randelli@dis.uniroma1.it
+ *
+ *    Copyright 2010
+ *		
+ *	  This file is based on Wiiuse, written By:
+ *		Michael Laforest	< para >
+ *		Email: < thepara (--AT--) g m a i l [--DOT--] com >
+ *
+ *	  Copyright 2006-2007
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *	  $Header$
+ */
+
+/**
+ *	@file
+ *
+ *	@brief WiiC structures.
+ *
+ *	Contains all the data structures, that represents
+ *	devices, sensors, and everything necessary. This header 
+ *	is included in wiic.h.
+ */
+struct vec3b_t;
+struct orient_t;
+struct gforce_t;
+
+/**
+ *	@struct read_req_t
+ *	@brief Data read request structure.
+ */
+struct read_req_t {
+	wiic_read_cb cb;			/**< read data callback											*/
+	byte* buf;					/**< buffer where read data is written							*/
+	unsigned int addr;			/**< the offset that the read started at						*/
+	unsigned short size;		/**< the length of the data read								*/
+	unsigned short wait;		/**< num bytes still needed to finish read						*/
+	byte dirty;					/**< set to 1 if not using callback and needs to be cleaned up	*/
+
+	struct read_req_t* next;	/**< next read request in the queue								*/
+};
+
+/*** COMMON STRUCTURES ***/
+
+/**
+ *	@struct vec2b_t
+ *	@brief Unsigned x,y byte vector.
+ */
+typedef struct vec2b_t {
+	byte x, y;
+} vec2b_t;
+
+
+/**
+ *	@struct vec3b_t
+ *	@brief Unsigned x,y,z byte vector.
+ */
+typedef struct vec3b_t {
+	byte x, y, z;
+} vec3b_t;
+
+/**
+ *	@struct vec3f_t
+ *	@brief Signed x,y,z float struct.
+ */
+typedef struct vec3f_t {
+	float x, y, z;
+} vec3f_t;
+
+/**
+ *	@struct ang3s_t
+ *	@brief RPY short int angles.
+ */
+typedef struct ang3s_t {
+	short roll, pitch, yaw;
+} ang3s_t;
+
+/**
+ *	@struct ang3f_t
+ *	@brief RPY float angles.
+ */
+typedef struct ang3f_t {
+	float roll, pitch, yaw;
+} ang3f_t;
+
+/**
+ *	@struct orient_t
+ *	@brief Orientation struct.
+ *
+ *	Yaw, pitch, and roll range from -180 to 180 degrees.
+ */
+typedef struct orient_t {
+	struct ang3f_t angle;	/**< roll, pitch and yaw (this may be smoothed if enabled)	*/
+} orient_t;
+
+/**
+ *	@struct ang_rate_t
+ *	@brief Angular rate struct.
+ *
+ *	Yaw, pitch, and roll rate from -180 to 180 degrees.
+ */
+typedef struct ang_rate_t {
+	struct ang3f_t rate;	/**< roll, pitch and yaw rate (this may be smoothed if enabled)	*/
+	struct ang3f_t a_rate;	/**< roll, pitch and yaw rate (unsmoothed)	*/
+} ang_rate_t;
+
+/**
+ *	@struct vel_t
+ *	@brief Velocity struct.
+ */
+typedef struct vel_t {
+	struct ang3s_t vel;		/**< raw rate, this may be smoothed if enabled 	*/
+	struct ang3s_t a_vel;	/**< raw rate (unsmoothed)	*/
+} vel_t;
+
+/**
+ *	@struct gforce_t
+ *	@brief Gravity force struct.
+ */
+typedef struct gforce_t {
+	struct vec3f_t vec;		/**< gforce, this may be smoothed if enabled 	*/
+	struct vec3f_t a_vec;	/**< gforce (unsmoothed)	*/
+} gforce_t;
+
+
+/**
+ *	@struct accel_t
+ *	@brief Accelerometer struct. For any device with an accelerometer.
+ */
+typedef struct accel_t {
+	struct vec3b_t cal_zero;		/**< zero calibration					*/
+	struct vec3b_t cal_g;			/**< 1g difference around 0cal			*/
+	float st_alpha;					/**< alpha value for smoothing [0-1]	*/
+} accel_t;
+
+/**
+ *	@struct gyro_t
+ *	@brief Gyro struct. For any device with a gyroscope.
+ */
+typedef struct gyro_t {
+	struct vec3b_t cal_zero;		/**< zero calibration					*/
+	float st_alpha;					/**< alpha value for smoothing [0-1]	*/
+} gyro_t;
+
+/**
+ *  @struct pressure_t
+ *  @brief Pressure sensor struct. Contains four pressure sensor measurements. Used for the Wii Balance Board.
+ */
+typedef struct pressure_t {
+	unsigned short top_left;
+	unsigned short top_right;
+	unsigned short bottom_left;
+	unsigned short bottom_right;
+} pressure_t;
+
+/**
+ *  @struct pressure_weight_t
+ *  @brief Pressure sensor weight struct. Contains four pressure sensor measurements in Kg. Used for the Wii Balance Board.
+ */
+typedef struct pressure_weight_t {
+	float top_left;
+	float top_right;
+	float bottom_left;
+	float bottom_right;
+	float weight; // This is the sum of the weight on the four sensors
+} pressure_weight_t;
+
+/* IR correction types */
+typedef enum ir_position_t {
+	WIIC_IR_ABOVE,
+	WIIC_IR_BELOW
+} ir_position_t;
+
+/**
+ *	@struct ir_dot_t
+ *	@brief A single IR source.
+ */
+typedef struct ir_dot_t {
+	byte visible;					/**< if the IR source is visible		*/
+
+	unsigned int x;					/**< interpolated X coordinate			*/
+	unsigned int y;					/**< interpolated Y coordinate			*/
+
+	short rx;						/**< raw X coordinate (0-1023)			*/
+	short ry;						/**< raw Y coordinate (0-767)			*/
+
+	byte order;						/**< increasing order by x-axis value	*/
+
+	byte size;						/**< size of the IR dot (0-15)			*/
+} ir_dot_t;
+
+
+/**
+ *	@struct ir_t
+ *	@brief IR struct. Hold all data related to the IR tracking.
+ */
+typedef struct ir_t {
+	struct ir_dot_t dot[4];			/**< IR dots							*/
+	byte num_dots;					/**< number of dots at this time		*/
+
+	enum aspect_t aspect;			/**< aspect ratio of the screen			*/
+
+	enum ir_position_t pos;			/**< IR sensor bar position				*/
+
+	unsigned int vres[2];			/**< IR virtual screen resolution		*/
+	int offset[2];					/**< IR XY correction offset			*/
+	int state;						/**< keeps track of the IR state		*/
+
+	int ax;							/**< absolute X coordinate				*/
+	int ay;							/**< absolute Y coordinate				*/
+
+	int x;							/**< calculated X coordinate			*/
+	int y;							/**< calculated Y coordinate			*/
+
+	float distance;					/**< pixel distance between first 2 dots*/
+	float z;						/**< calculated distance				*/
+} ir_t;
+
+
+/**
+ *	@struct joystick_t
+ *	@brief Joystick calibration structure.
+ *
+ *	The angle \a ang is relative to the positive y-axis into quadrant I
+ *	and ranges from 0 to 360 degrees.  So if the joystick is held straight
+ *	upwards then angle is 0 degrees.  If it is held to the right it is 90,
+ *	down is 180, and left is 270.
+ *
+ *	The magnitude \a mag is the distance from the center to where the
+ *	joystick is being held.  The magnitude ranges from 0 to 1.
+ *	If the joystick is only slightly tilted from the center the magnitude
+ *	will be low, but if it is closer to the outter edge the value will
+ *	be higher.
+ */
+typedef struct joystick_t {
+	struct vec2b_t max;				/**< maximum joystick values	*/
+	struct vec2b_t min;				/**< minimum joystick values	*/
+	struct vec2b_t center;			/**< center joystick values		*/
+
+	float ang;						/**< angle the joystick is being held		*/
+	float mag;						/**< magnitude of the joystick (range 0-1)	*/
+} joystick_t;
+
+
+/**
+ *	@struct nunchuk_t
+ *	@brief Nunchuk expansion device.
+ */
+typedef struct nunchuk_t {
+	struct accel_t accel_calib;		/**< nunchuk accelerometer calibration		*/
+	struct joystick_t js;			/**< joystick calibration					*/
+
+	int* flags;						/**< options flag (points to wiimote_t.flags) */
+
+	byte btns;						/**< what buttons have just been pressed	*/
+	byte btns_held;					/**< what buttons are being held down		*/
+	byte btns_released;				/**< what buttons were just released this	*/
+
+	float orient_threshold;			/**< threshold for orient to generate an event */
+	int accel_threshold;			/**< threshold for accel to generate an event */
+
+	struct vec3b_t accel;			/**< current raw acceleration data			*/
+	struct orient_t orient;			/**< current orientation on each axis		*/
+	struct orient_t a_orient;		/**< current orientation on each axis (unsmoothed)		*/
+	struct gforce_t gforce;			/**< current gravity forces on each axis	*/
+	struct gforce_t a_gforce;		/**< current gravity forces on each axis (unsmoothed)	*/
+} nunchuk_t;
+
+
+/**
+ *	@struct classic_ctrl_t
+ *	@brief Classic controller expansion device.
+ */
+typedef struct classic_ctrl_t {
+	short btns;						/**< what buttons have just been pressed	*/
+	short btns_held;				/**< what buttons are being held down		*/
+	short btns_released;			/**< what buttons were just released this	*/
+
+	float r_shoulder;				/**< right shoulder button (range 0-1)		*/
+	float l_shoulder;				/**< left shoulder button (range 0-1)		*/
+
+	struct joystick_t ljs;			/**< left joystick calibration				*/
+	struct joystick_t rjs;			/**< right joystick calibration				*/
+} classic_ctrl_t;
+
+
+/**
+ *	@struct guitar_hero_3_t
+ *	@brief Guitar Hero 3 expansion device.
+ */
+typedef struct guitar_hero_3_t {
+	short btns;						/**< what buttons have just been pressed	*/
+	short btns_held;				/**< what buttons are being held down		*/
+	short btns_released;			/**< what buttons were just released this	*/
+
+	float whammy_bar;				/**< whammy bar (range 0-1)					*/
+
+	struct joystick_t js;			/**< joystick calibration					*/
+} guitar_hero_3_t;
+
+/**
+ *	@struct balance_board_t
+ *	@brief Balance Board expansion device.
+ */
+typedef struct balance_board_t {
+	struct pressure_t cal_low_weight; // equivalent 0Kg
+	struct pressure_t cal_medium_weight; // equivalent 17Kg
+	struct pressure_t cal_high_weight; // equivalent 34Kg
+	struct pressure_t pressure_raw_data; // Actual reading
+	struct pressure_weight_t pressure_weight; // In Kg
+} balance_board_t;
+
+/**
+ *	@struct motion_plus_t
+ *	@brief Motion Plus expansion device.
+ */
+typedef struct motion_plus_t {
+	struct ang3s_t a_raw_gyro;			/**< current raw gyroscope data (unsmoothed) */
+	struct ang3s_t raw_gyro;			/**< current raw gyroscope data (smoothed, if enabled) */
+	struct ang3s_t cal_gyro;			/**< calibration raw gyroscope data */
+	struct ang3f_t a_gyro_rate;		/**< current gyro angle rate (unsmoothed) */
+	struct ang3f_t gyro_rate;		/**< current gyro angle rate (smoothed, if enabled) */
+	struct orient_t orient;				/**< current orientation on each axis using Motion Plus gyroscopes */
+	byte acc_mode;						/**< Fast/slow rotation mode for roll, pitch and yaw (0 if rotating fast, 1 if slow or still) */
+	int raw_gyro_threshold;			/**< threshold for gyroscopes to generate an event */
+	int smooth;					/**< smoothing enabled/disabled */
+	float smooth_alpha;				/**< smoothness alpha parameter*/
+} motion_plus_t;
+
+
+/**
+ *	@struct expansion_t
+ *	@brief Generic expansion device plugged into wiimote.
+ */
+typedef struct expansion_t {
+	int type;						/**< type of expansion attached				*/
+
+	union {
+		struct nunchuk_t nunchuk;
+		struct classic_ctrl_t classic;
+		struct guitar_hero_3_t gh3;
+		struct motion_plus_t mp;
+		struct balance_board_t bb;
+	};
+} expansion_t;
+
+
+/**
+ *	@struct wiimote_state_t
+ *	@brief Significant data from the previous event.
+ */
+typedef struct wiimote_state_t {
+	/* expansion_t */
+	float exp_ljs_ang;
+	float exp_rjs_ang;
+	float exp_ljs_mag;
+	float exp_rjs_mag;
+	unsigned short exp_btns;
+	struct orient_t exp_orient;
+	struct vec3b_t exp_accel;
+	float exp_r_shoulder;
+	float exp_l_shoulder;
+	
+	/* motion_plus_t */
+	byte mp_acc_mode;
+	struct ang3s_t mp_raw_gyro;
+	
+	/* balance_board_t */
+	struct pressure_t pressure_raw_data;
+
+	/* ir_t */
+	int ir_ax;
+	int ir_ay;
+	float ir_distance;
+
+	/* wiimote_t */
+	struct orient_t orient;
+	unsigned short btns;
+	struct vec3b_t accel;
+} wiimote_state_t;
+
+
+/**
+ *	@enum WIIC_EVENT_TYPE
+ *	@brief Events that wiic can generate from a poll.
+ */
+typedef enum WIIC_EVENT_TYPE {
+	WIIC_NONE = 0,
+	WIIC_EVENT,
+	WIIC_STATUS,
+	WIIC_CONNECT,
+	WIIC_DISCONNECT,
+	WIIC_UNEXPECTED_DISCONNECT,
+	WIIC_READ_DATA,
+	WIIC_NUNCHUK_INSERTED,
+	WIIC_NUNCHUK_REMOVED,
+	WIIC_CLASSIC_CTRL_INSERTED,
+	WIIC_CLASSIC_CTRL_REMOVED,
+	WIIC_GUITAR_HERO_3_CTRL_INSERTED,
+	WIIC_GUITAR_HERO_3_CTRL_REMOVED,
+	WIIC_MOTION_PLUS_INSERTED,
+	WIIC_MOTION_PLUS_REMOVED,
+	WIIC_BALANCE_BOARD_INSERTED,
+	WIIC_BALANCE_BOARD_REMOVED
+} WIIC_EVENT_TYPE;
+
+/**
+ *	@struct wiimote_t
+ *	@brief Wiimote structure.
+ */
+typedef struct wiimote_t {
+	WCONST int unid;						/**< user specified id						*/
+
+	#ifdef __APPLE__
+		WCONST IOBluetoothDeviceRef device;    	/**  Device reference object                */
+		WCONST CFStringRef address;            	/**  MacOS-like device address string       */
+		WCONST IOBluetoothL2CAPChannelRef inputCh;		/**  Input L2CAP channel					*/	
+		WCONST IOBluetoothL2CAPChannelRef outputCh;	/**  Output L2CAP channel					*/
+		WCONST IOBluetoothUserNotificationRef disconnectionRef;	/**  Disconnection Notification Reference **/
+		WCONST void* connectionHandler; /** Wiimote connection handler for MACOSX **/
+	#elif LINUX
+		WCONST bdaddr_t bdaddr;				/**< bt address								*/
+		WCONST int out_sock;				/**< output socket							*/
+		WCONST int in_sock;					/**< input socket 							*/	
+	#endif
+	
+	WCONST char bdaddr_str[18];			/**< readable bt address					*/
+	WCONST struct wiimote_state_t lstate;	/**< last saved state						*/
+	WCONST int state;						/**< various state flags					*/
+	WCONST int flags;						/**< options flag							*/
+	WCONST int autoreconnect;				/**< auto-reconnect the device in case of unexpected disconnection */
+	WCONST byte handshake_state;			/**< the state of the connection handshake	*/
+	
+	WCONST byte leds;						/**< currently lit leds						*/
+	WCONST float battery_level;				/**< battery level							*/
+
+	WCONST struct read_req_t* read_req;		/**< list of data read requests				*/
+	WCONST struct expansion_t exp;			/**< wiimote expansion device				*/
+
+	WCONST struct accel_t accel_calib;		/**< wiimote accelerometer calibration		*/
+	WCONST struct vec3b_t accel;			/**< current raw acceleration data			*/
+	WCONST struct orient_t orient;			/**< current orientation on each axis (smoothed and unsmoothed)		*/
+	WCONST struct gforce_t gforce;			/**< current gravity forces on each axis (smoothed and unsmoothed)	*/
+	WCONST float orient_threshold;			/**< threshold for orient to generate an event */
+	WCONST int accel_threshold;				/**< threshold for accel to generate an event */
+
+	WCONST struct ir_t ir;					/**< IR data								*/
+
+	WCONST unsigned short btns;				/**< what buttons have just been pressed	*/
+	WCONST unsigned short btns_held;		/**< what buttons are being held down		*/
+	WCONST unsigned short btns_released;	/**< what buttons were just released this	*/
+
+	WCONST WIIC_EVENT_TYPE event;			/**< type of event that occured				*/
+	WCONST byte event_buf[MAX_PAYLOAD];		/**< event buffer							*/
+	
+	struct timeval timestamp; 				/**< Absolute timestamp (relative to the most recent data) */
+} wiimote;
Index: code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt	(revision 9780)
@@ -0,0 +1,34 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../wiic/)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../log/)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(WIICPP_SOURCES wiicpp.cpp ../log/logger.cpp ../log/dataset.cpp ../log/training.cpp ../log/gyrosample.cpp ../log/accsample.cpp)
+#ADD_LIBRARY(wiicpp SHARED ${WIICPP_SOURCES})
+#TARGET_LINK_LIBRARIES(wiicpp wiic)
+
+#INSTALL(TARGETS wiicpp DESTINATION /usr/local/lib)
+INSTALL(FILES wiicpp.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/training.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/dataset.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/sample.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/accsample.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/gyrosample.h DESTINATION /usr/local/include/wiic/)
+INSTALL(FILES ../log/logger.h DESTINATION /usr/local/include/wiic/)
+
+SET_SOURCE_FILES(WIICPP_FILES
+  wiicpp.h
+  wiicpp.cpp
+)
+
+ORXONOX_ADD_LIBRARY(wiicpp_orxonox
+  ORXONOX_EXTERNAL
+  NO_DLL_INTERFACE
+  VERSION
+    1.1
+  LINK_LIBRARIES
+    wiic_orxonox
+  SOURCE_FILES
+    ${WIICPP_SOURCES}
+	
+)
+
Index: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp	(revision 9780)
@@ -0,0 +1,997 @@
+/*
+ *    wiicpp.cpp
+ *
+ *		This file is part of WiiC, written by:
+ *			Gabriele Randelli
+ *			Email: randelli@dis.uniroma1.it
+ *
+ *		Copyright 2010
+ *		
+ *		This file is based on WiiuseCpp, written By:
+ *        James Thomas
+ *        Email: jt@missioncognition.org
+ *
+ *    Copyright 2009
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * Note:  This C++ library is a (very) thin wrapper of the the WiiC library.
+ */
+
+#include <iostream>
+#include "wiicpp.h"
+#include <unistd.h>
+
+using namespace std;
+using namespace WiiC;
+
+/*
+ * CButtonBase class methods.
+ */
+CButtonBase::CButtonBase(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr)
+{
+    mpBtnsPtr = ButtonsPtr;
+    mpBtnsHeldPtr = ButtonsHeldPtr;
+    mpBtnsReleasedPtr = ButtonsReleasedPtr;
+}
+
+int CButtonBase::isPressed(int Button)
+{
+    return (Cast(mpBtnsPtr) & Button) == Button;
+}
+
+int CButtonBase::isHeld(int Button)
+{
+    return (Cast(mpBtnsHeldPtr) & Button) == Button;
+}
+
+int CButtonBase::isReleased(int Button)
+{
+    return (Cast(mpBtnsReleasedPtr) & Button) == Button;
+}
+
+int CButtonBase::isJustPressed(int Button)
+{
+    return ((Cast(mpBtnsPtr) & Button) == Button) && ((Cast(mpBtnsHeldPtr) & Button) != Button);
+}
+
+/*
+ * Initializers for classes derrived from CButtonBase.
+ */
+CButtons::CButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr) :
+    CButtonBase(ButtonsPtr, ButtonsHeldPtr, ButtonsReleasedPtr)
+{
+}
+
+CNunchukButtons::CNunchukButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr) :
+    CButtonBase(ButtonsPtr, ButtonsHeldPtr, ButtonsReleasedPtr)
+{
+}
+
+CClassicButtons::CClassicButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr) :
+    CButtonBase(ButtonsPtr, ButtonsHeldPtr, ButtonsReleasedPtr)
+{
+}
+
+CGH3Buttons::CGH3Buttons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr) :
+    CButtonBase(ButtonsPtr, ButtonsHeldPtr, ButtonsReleasedPtr)
+{
+}
+
+/*
+ * CJoystick class methods.
+ */
+
+CJoystick::CJoystick(struct joystick_t *JSPtr)
+{
+    mpJoystickPtr = JSPtr;
+}
+
+void CJoystick::GetMaxCal(int &X, int &Y)
+{
+    X = mpJoystickPtr->max.x;
+    Y = mpJoystickPtr->max.y;
+}
+
+void CJoystick::SetMaxCal(int X, int Y)
+{
+    mpJoystickPtr->max.x = X;
+    mpJoystickPtr->max.y = Y;
+}
+
+void CJoystick::GetMinCal(int &X, int &Y)
+{
+    X = mpJoystickPtr->min.x;
+    Y = mpJoystickPtr->min.y;
+}
+
+void CJoystick::SetMinCal(int X, int Y)
+{
+    mpJoystickPtr->min.x = X;
+    mpJoystickPtr->min.y = Y;
+}
+
+void CJoystick::GetCenterCal(int &X, int &Y)
+{
+    X = mpJoystickPtr->center.x;
+    Y = mpJoystickPtr->center.y;
+}
+
+void CJoystick::SetCenterCal(int X, int Y)
+{
+    mpJoystickPtr->center.x = X;
+    mpJoystickPtr->center.y = Y;
+}
+
+void CJoystick::GetPosition(float &Angle, float &Magnitude)
+{
+    Angle = mpJoystickPtr->ang;
+    Magnitude = mpJoystickPtr->mag;
+}
+
+/*
+ * CAccelerometer class methods.
+ */
+
+CAccelerometer::CAccelerometer(struct accel_t *AccelCalPtr, struct vec3b_t *AccelerationPtr, int *AccelThresholdPtr,
+                               struct orient_t *OrientationPtr, float *OrientationThresholdPtr,
+                               struct gforce_t *GForcePtr)
+{
+    mpAccelCalibPtr = AccelCalPtr;
+    mpAccelPtr = AccelerationPtr;
+    mpOrientPtr = OrientationPtr;
+    mpGForcePtr = GForcePtr;
+    mpAccelThresholdPtr = AccelThresholdPtr;
+    mpOrientThresholdPtr = OrientationThresholdPtr;
+}
+
+float CAccelerometer::SetSmoothAlpha(float Alpha)
+{
+    float old_value;
+
+    old_value = mpAccelCalibPtr->st_alpha;
+
+    mpAccelCalibPtr->st_alpha = Alpha;
+
+    return old_value;
+}
+
+float CAccelerometer::GetOrientThreshold()
+{
+    return *mpOrientThresholdPtr;
+}
+
+void CAccelerometer::SetOrientThreshold(float Threshold)
+{
+    *mpOrientThresholdPtr = Threshold;
+}
+
+int CAccelerometer::GetAccelThreshold()
+{
+    return *mpAccelThresholdPtr;
+}
+
+void CAccelerometer::SetAccelThreshold(int Threshold)
+{
+    *mpAccelThresholdPtr = Threshold;
+}
+
+/**
+ *
+ * @brief Retrieves the smoothed device attitude (pitch, roll, and yaw) computed with an
+ * exponential moving average.
+ *
+ * @param Pitch		[out] Reference variable where the smooth device pitch will be set.
+ * @param Roll		[out] Reference variable where the smooth device roll will be set.
+ * @param Yaw		[out] Reference variable where the smooth device yaw will be set. Please,
+ *						  note that without IR enabled, yaw cannot be retrieved.
+ */
+void CAccelerometer::GetOrientation(float &Pitch, float &Roll, float &Yaw)
+{
+    Pitch = mpOrientPtr->angle.pitch;
+    Roll = mpOrientPtr->angle.roll;
+    Yaw = mpOrientPtr->angle.yaw;
+}
+
+void CAccelerometer::GetGravityCalVector(float &X, float &Y, float &Z)
+{
+    X = mpAccelCalibPtr->cal_g.x;
+    Y = mpAccelCalibPtr->cal_g.y;
+    Z = mpAccelCalibPtr->cal_g.z;
+}
+
+void CAccelerometer::SetGravityCalVector(float X, float Y, float Z)
+{
+    mpAccelCalibPtr->cal_g.x = X;
+    mpAccelCalibPtr->cal_g.y = Y;
+    mpAccelCalibPtr->cal_g.z = Z;
+}
+
+void CAccelerometer::GetGravityVector(float &X, float &Y, float &Z)
+{
+    X = mpGForcePtr->vec.x;
+    Y = mpGForcePtr->vec.y;
+    Z = mpGForcePtr->vec.z;
+}
+
+void CAccelerometer::GetRawGravityVector(float &X, float &Y, float &Z)
+{
+    X = mpGForcePtr->a_vec.x;
+    Y = mpGForcePtr->a_vec.y;
+    Z = mpGForcePtr->a_vec.z;
+}
+
+/*
+ * CGyroscope class methods.
+ */
+CGyroscope::CGyroscope(struct ang3s_t* RawGyro, struct ang3s_t* CalGyro, struct ang3f_t* AngleRate, unsigned char* Mode, struct motion_plus_t* MPPtr, 
+	int* GyroThresholdPtr)
+{
+	mpRawGyro = RawGyro;
+	mpCalGyro = CalGyro;
+	mpAngleRate = AngleRate;
+	mpMode = Mode;
+	mpMPPtr = MPPtr;
+	mpGyroThresholdPtr = GyroThresholdPtr;
+}
+
+void CGyroscope::GetRawRates(int& Roll, int& Pitch, int& Yaw)
+{
+	Roll = mpRawGyro->roll;
+	Pitch = mpRawGyro->pitch;
+	Yaw = mpRawGyro->yaw;
+}
+
+void CGyroscope::GetRates(float& Roll, float& Pitch, float& Yaw)
+{
+	Roll = mpAngleRate->roll;
+	Pitch = mpAngleRate->pitch;
+	Yaw = mpAngleRate->yaw;
+}
+
+void CGyroscope::Calibrate()
+{
+	wiic_calibrate_motion_plus(mpMPPtr);	
+}
+
+int CGyroscope::GetGyroThreshold()
+{
+    return *mpGyroThresholdPtr;
+}
+
+void CGyroscope::SetGyroThreshold(int Threshold)
+{
+    *mpGyroThresholdPtr = Threshold;
+}
+
+
+/*
+ * CWeightSensor class methods.
+ */
+CWeightSensor::CWeightSensor(struct pressure_t* RawWeight, struct pressure_t* LowCalWeight, struct pressure_t* MediumCalWeight, struct pressure_t* HighCalWeight, struct pressure_weight_t* Weight, struct balance_board_t* BBPtr)
+{
+	mpRawWeight = RawWeight;
+	mpLowCalWeight = LowCalWeight;
+	mpMediumCalWeight = MediumCalWeight;
+	mpHighCalWeight = HighCalWeight;
+	mpWeight = Weight;
+	mpBBPtr = BBPtr;
+}
+
+void CWeightSensor::GetRawWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight)
+{
+	TopLeft = mpRawWeight->top_left;
+	TopRight = mpRawWeight->top_right;
+	BottomLeft = mpRawWeight->bottom_left;
+	BottomRight = mpRawWeight->bottom_right;
+}
+
+void CWeightSensor::GetLowCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight)
+{
+	TopLeft = mpLowCalWeight->top_left;
+	TopRight = mpLowCalWeight->top_right;
+	BottomLeft = mpLowCalWeight->bottom_left;
+	BottomRight = mpLowCalWeight->bottom_right;
+}
+
+void CWeightSensor::GetMediumCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight)
+{
+	TopLeft = mpMediumCalWeight->top_left;
+	TopRight = mpMediumCalWeight->top_right;
+	BottomLeft = mpMediumCalWeight->bottom_left;
+	BottomRight = mpMediumCalWeight->bottom_right;
+}
+
+void CWeightSensor::GetHighCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight)
+{
+	TopLeft = mpHighCalWeight->top_left;
+	TopRight = mpHighCalWeight->top_right;
+	BottomLeft = mpHighCalWeight->bottom_left;
+	BottomRight = mpHighCalWeight->bottom_right;
+}
+
+void CWeightSensor::GetWeight(float& TotalWeight, float& TopLeft, float& TopRight, float& BottomLeft, float& BottomRight)
+{
+	TotalWeight = mpWeight->weight;
+	TopLeft = mpWeight->top_left;
+	TopRight = mpWeight->top_right;
+	BottomLeft = mpWeight->bottom_left;
+	BottomRight = mpWeight->bottom_right;
+}
+
+
+/*
+ * CIRDot class methods.
+ */
+
+CIRDot::CIRDot()
+{
+    mpDotPtr = NULL;
+}
+
+CIRDot::CIRDot(struct ir_dot_t *DotPtr)
+{
+    mpDotPtr = DotPtr;
+}
+
+CIRDot::CIRDot(const CIRDot &copyin) // Copy constructor to handle pass by value.
+{
+    mpDotPtr = copyin.mpDotPtr;
+}
+
+int CIRDot::isVisible()
+{
+    return mpDotPtr->visible;
+}
+
+int CIRDot::GetSize()
+{
+    return mpDotPtr->size;
+}
+
+int CIRDot::GetOrder()
+{
+    return mpDotPtr->order;
+}
+
+void CIRDot::GetCoordinate(int &X, int &Y)
+{
+    X = mpDotPtr->x;
+    Y = mpDotPtr->y;
+}
+
+void CIRDot::GetRawCoordinate(int &X, int &Y)
+{
+    X = mpDotPtr->rx;
+    Y = mpDotPtr->ry;
+}
+
+/*
+ * CIR class methods.
+ */
+
+CIR::CIR(struct wiimote_t *wmPtr)
+{
+    mpWiimotePtr = wmPtr;
+}
+
+void CIR::SetMode(CIR::OnOffSelection State)
+{
+    wiic_set_ir(mpWiimotePtr, State);
+}
+
+void CIR::SetVres(unsigned int x, unsigned int y)
+{
+    wiic_set_ir_vres(mpWiimotePtr, x, y);
+}
+
+CIR::BarPositions CIR::GetBarPositionSetting()
+{
+    return (CIR::BarPositions) mpWiimotePtr->ir.pos;
+}
+
+void CIR::SetBarPosition(CIR::BarPositions PositionSelection)
+{
+    wiic_set_ir_position(mpWiimotePtr, (ir_position_t) PositionSelection);
+}
+
+CIR::AspectRatioSelections CIR::GetAspectRatioSetting()
+{
+    return (CIR::AspectRatioSelections) mpWiimotePtr->ir.aspect;
+}
+
+void CIR::SetAspectRatio(CIR::AspectRatioSelections AspectRatioSelection)
+{
+    wiic_set_aspect_ratio(mpWiimotePtr, (enum aspect_t) AspectRatioSelection);
+}
+
+void CIR::SetSensitivity(int Level)
+{
+    wiic_set_ir_sensitivity(mpWiimotePtr, Level);
+}
+
+int CIR::GetSensitivity()
+{
+    int level = 0;
+
+	 WIIC_GET_IR_SENSITIVITY(mpWiimotePtr, &level);
+
+    return level;
+}
+
+int CIR::GetNumDots()
+{
+    return mpWiimotePtr->ir.num_dots;
+}
+
+std::vector<CIRDot>& CIR::GetDots()
+{
+    int index;
+
+    // Empty the array of irdots before reloading
+    mpIRDotsVector.clear();
+
+    for(index = 0 ; index < 4 ; index++)
+    {
+        CIRDot dot((struct ir_dot_t *) (&(mpWiimotePtr->ir.dot[index])));
+		if(dot.isVisible())
+        	mpIRDotsVector.push_back(dot);
+    }
+
+    return mpIRDotsVector;
+}
+
+void CIR::GetOffset(int &X, int &Y)
+{
+    X = mpWiimotePtr->ir.offset[0];
+    Y = mpWiimotePtr->ir.offset[1];
+}
+
+int CIR::GetState()
+{
+    return mpWiimotePtr->ir.state;
+}
+
+void CIR::GetCursorPositionAbsolute(int &X, int &Y)
+{
+    X = mpWiimotePtr->ir.ax;
+    Y = mpWiimotePtr->ir.ay;
+}
+
+void CIR::GetCursorPosition(int &X, int &Y)
+{
+    X = mpWiimotePtr->ir.x;
+    Y = mpWiimotePtr->ir.y;
+}
+
+float CIR::GetPixelDistance()
+{
+    return mpWiimotePtr->ir.distance;
+}
+
+float CIR::GetDistance()
+{
+    return mpWiimotePtr->ir.z;
+}
+
+/*
+ * CExpansionDevice class methods.  This is a container class so there is not much.
+ */
+
+CExpansionDevice::CExpansionDevice(struct expansion_t * ExpPtr) :
+    Nunchuk(ExpPtr),Classic(ExpPtr),GuitarHero3(ExpPtr),MotionPlus(ExpPtr),BalanceBoard(ExpPtr)
+{
+    mpExpansionPtr = ExpPtr;
+}
+
+CExpansionDevice::ExpTypes CExpansionDevice::GetType()
+{
+    return (CExpansionDevice::ExpTypes) (mpExpansionPtr->type);
+}
+
+/*
+ * CNunchuk class methods.
+ */
+
+CNunchuk::CNunchuk(struct expansion_t *ExpPtr):
+    Buttons((void *) &(ExpPtr->nunchuk.btns), (void *) &(ExpPtr->nunchuk.btns_held),
+            (void *) &(ExpPtr->nunchuk.btns_released)), Joystick(&(ExpPtr->nunchuk.js)),
+            Accelerometer(&(ExpPtr->nunchuk.accel_calib), &(ExpPtr->nunchuk.accel), &(ExpPtr->nunchuk.accel_threshold),
+                          &(ExpPtr->nunchuk.orient), &(ExpPtr->nunchuk.orient_threshold), &(ExpPtr->nunchuk.gforce))
+{
+}
+
+/*
+ * CClassic class methods.
+ */
+
+CClassic::CClassic(struct expansion_t *ExpPtr):
+    Buttons((void *) &(ExpPtr->classic.btns), (void *) &(ExpPtr->classic.btns_held), (void *) &(ExpPtr->classic.btns_released)),LeftJoystick(&(ExpPtr->classic.ljs)), RightJoystick(&(ExpPtr->classic.rjs))
+{
+    // Initialize the expansion pointer.
+    mpClassicPtr = &(ExpPtr->classic);
+}
+
+float CClassic::GetLShoulderButton()
+{
+    return mpClassicPtr->l_shoulder;
+}
+
+float CClassic::GetRShoulderButton()
+{
+    return mpClassicPtr->r_shoulder;
+}
+
+/*
+ * CGuitarHero3 class methods.
+ */
+
+CGuitarHero3::CGuitarHero3(struct expansion_t *ExpPtr):
+    Buttons((void *) &(ExpPtr->gh3.btns), (void *) &(ExpPtr->gh3.btns_held), (void *) &(ExpPtr->gh3.btns_released)),
+            Joystick(&(ExpPtr->gh3.js))
+{
+    // Initialize the expansion pointer.
+    mpGH3Ptr = &(ExpPtr->gh3);
+}
+
+float CGuitarHero3::GetWhammyBar()
+{
+    return mpGH3Ptr->whammy_bar;
+}
+
+
+/*
+ * CMotionPlus class methods.
+ */
+CMotionPlus::CMotionPlus(struct expansion_t *ExpPtr):
+	Gyroscope(&(ExpPtr->mp.raw_gyro),&(ExpPtr->mp.cal_gyro),&(ExpPtr->mp.gyro_rate),(unsigned char*)&(ExpPtr->mp.acc_mode),&(ExpPtr->mp),
+	&(ExpPtr->mp.raw_gyro_threshold))
+{
+	mpMPPtr = &(ExpPtr->mp);
+}
+
+void CMotionPlus::Connect(struct wiimote_t* WiimotePtr)
+{
+	wiic_set_motion_plus(WiimotePtr,1);
+}
+
+void CMotionPlus::Disconnect(struct wiimote_t* WiimotePtr)
+{
+	wiic_set_motion_plus(WiimotePtr,0);
+}
+
+
+/*
+ * CBalanceBoard class methods.
+ */
+CBalanceBoard::CBalanceBoard(struct expansion_t *ExpPtr):
+	WeightSensor(&(ExpPtr->bb.pressure_raw_data),&(ExpPtr->bb.cal_low_weight),&(ExpPtr->bb.cal_medium_weight),&(ExpPtr->bb.cal_high_weight),&(ExpPtr->bb.pressure_weight),&(ExpPtr->bb))
+{
+    // Initialize the expansion pointer.
+	 mpBBPtr = &(ExpPtr->bb);
+} 
+
+
+/*
+ * CWiimote class methods.
+ */
+
+CWiimote::CWiimote() : // SWIG insisted it exist for the vectors. Hopefully it will only be used for copy.
+    IR(NULL), Buttons(NULL, NULL, NULL), Accelerometer((accel_t*) NULL, (vec3b_t*) NULL, (int*) &(mpTempInt),
+                                                       (orient_t*) NULL, (float*) &(mpTempFloat), (gforce_t*) NULL),
+            ExpansionDevice(NULL)
+{
+    mpWiimotePtr = NULL;
+}
+
+CWiimote::CWiimote(struct wiimote_t *wmPtr):
+    IR(wmPtr), Buttons((void *) &(wmPtr->btns), (void *) &(wmPtr->btns_held), (void *) &(wmPtr->btns_released)),
+            Accelerometer((accel_t*) &(wmPtr->accel_calib), (vec3b_t*) &(wmPtr->accel),
+                          (int*) &(wmPtr->accel_threshold), (orient_t*) &(wmPtr->orient),
+                          (float*) &(wmPtr->orient_threshold), (gforce_t*) &(wmPtr->gforce)), 
+            ExpansionDevice((struct expansion_t*) &(wmPtr->exp))
+{
+    mpWiimotePtr = wmPtr;
+    logger.SetDeviceAddress(string(GetAddress()));
+}
+
+CWiimote::CWiimote(const CWiimote &copyin) : // Copy constructor to handle pass by value.
+            IR(copyin.mpWiimotePtr),
+            Buttons((void *) &(copyin.mpWiimotePtr->btns), (void *) &(copyin.mpWiimotePtr->btns_held),
+                    (void *) &(copyin.mpWiimotePtr->btns_released)),
+            Accelerometer((accel_t*) &(copyin.mpWiimotePtr->accel_calib), (vec3b_t*) &(copyin.mpWiimotePtr->accel),
+                          (int*) &(copyin.mpWiimotePtr->accel_threshold), (orient_t*) &(copyin.mpWiimotePtr->orient),
+                          (float*) &(copyin.mpWiimotePtr->orient_threshold), (gforce_t*) &(copyin.mpWiimotePtr->gforce)),
+            ExpansionDevice((struct expansion_t*) &(copyin.mpWiimotePtr->exp)), logger(copyin.logger)
+{
+    mpWiimotePtr = copyin.mpWiimotePtr;
+    logger = copyin.logger;
+}
+
+void CWiimote::Disconnected()
+{
+    wiic_disconnected(mpWiimotePtr);
+}
+
+void CWiimote::SetRumbleMode(CWiimote::OnOffSelection State)
+{
+    wiic_rumble(mpWiimotePtr, State);
+}
+
+void CWiimote::ToggleRumble()
+{
+    wiic_toggle_rumble(mpWiimotePtr);
+}
+
+bool CWiimote::isRumbleEnabled()
+{
+    return WIIMOTE_IS_SET(mpWiimotePtr,WIIMOTE_STATE_RUMBLE);
+}
+
+int CWiimote::GetLEDs()
+{
+    return mpWiimotePtr->leds;
+}
+
+void CWiimote::SetLEDs(int LEDs)
+{
+    wiic_set_leds(mpWiimotePtr, LEDs);
+}
+
+float CWiimote::GetBatteryLevel()
+{
+    return mpWiimotePtr->battery_level;
+}
+
+int CWiimote::GetHandshakeState()
+{
+    return mpWiimotePtr->handshake_state;
+}
+
+CWiimote::EventTypes CWiimote::GetEvent()
+{
+    return (CWiimote::EventTypes) mpWiimotePtr->event;
+}
+
+const unsigned char *CWiimote::GetEventBuffer()
+{
+    return mpWiimotePtr->event_buf;
+}
+
+void CWiimote::Log()
+{
+	logger.InitLog();
+	
+	if(logType & WIIC_LOG_ACC) {
+		float x, y, z;
+		Accelerometer.GetGravityVector(x,y,z);
+		logger.LogAcc(x,y,z);
+	}
+	
+	if(logType & WIIC_LOG_GYRO) {			
+		float roll, pitch, yaw;
+		ExpansionDevice.MotionPlus.Gyroscope.GetRates(roll,pitch,yaw);
+		logger.LogGyro(roll,pitch,yaw);
+	}			
+}
+
+void CWiimote::SetMotionSensingMode(CWiimote::OnOffSelection State)
+{
+    wiic_motion_sensing(mpWiimotePtr, State);
+}
+
+void CWiimote::EnableMotionPlus(CWiimote::OnOffSelection State)
+{
+    if(State == CWiimote::ON)
+    	ExpansionDevice.MotionPlus.Connect(mpWiimotePtr);
+    else
+    	ExpansionDevice.MotionPlus.Disconnect(mpWiimotePtr);
+}
+
+void CWiimote::EnableSpeaker(CWiimote::OnOffSelection State)
+{
+    wiic_set_speaker(mpWiimotePtr, State);
+}
+
+void CWiimote::MuteSpeaker(CWiimote::OnOffSelection State)
+{
+    wiic_mute_speaker(mpWiimotePtr, State);
+}
+
+void CWiimote::PlaySound()
+{
+	wiic_sound(mpWiimotePtr);
+}
+
+void CWiimote::ReadData(unsigned char *Buffer, unsigned int Offset, unsigned int Length)
+{
+    wiic_read_data(mpWiimotePtr, Buffer, Offset, Length);
+}
+
+void CWiimote::WriteData(unsigned int Address, unsigned char *Data, unsigned int Length)
+{
+    wiic_write_data(mpWiimotePtr, Address, Data, Length);
+}
+
+void CWiimote::UpdateStatus()
+{
+    wiic_status(mpWiimotePtr);
+}
+
+int CWiimote::GetID()
+{
+    return mpWiimotePtr->unid;
+}
+
+const char* CWiimote::GetAddress()
+{
+    return mpWiimotePtr->bdaddr_str;
+}
+
+int CWiimote::GetState()
+{
+    return mpWiimotePtr->state;
+}
+
+int CWiimote::GetFlags()
+{
+    return mpWiimotePtr->flags;
+}
+
+int CWiimote::SetFlags(int Enable, int Disable)
+{
+    return wiic_set_flags(mpWiimotePtr, Enable, Disable);
+}
+
+void CWiimote::SetSmoothing(bool Smooth)
+{
+	if(Smooth)
+		wiic_set_flags(mpWiimotePtr, WIIC_SMOOTHING, 0);
+	else
+		wiic_set_flags(mpWiimotePtr, 0, WIIC_SMOOTHING);
+}
+
+void CWiimote::Resync()
+{
+    wiic_resync(mpWiimotePtr);
+}
+
+void CWiimote::Disconnect()
+{
+    wiic_disconnect(mpWiimotePtr);
+}
+
+int CWiimote::isUsingACC()
+{
+    return WIIC_USING_ACC(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isUsingEXP()
+{
+    return WIIC_USING_EXP(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isUsingIR()
+{
+    return WIIC_USING_IR(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isUsingMotionPlus()
+{
+	return WIIC_USING_MOTION_PLUS(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isUsingSpeaker()
+{
+    return WIIC_USING_SPEAKER(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isSpeakerMuted()
+{
+    return WIIC_SPEAKER_MUTED(mpWiimotePtr) != 0;
+}
+
+int CWiimote::isLEDSet(int LEDNum)
+{
+    int result = 0;
+
+    switch(LEDNum)
+    {
+        case 1:
+            result = (mpWiimotePtr->leds & LED_1) != 0;
+            break;
+        case 2:
+            result = (mpWiimotePtr->leds & LED_2) != 0;
+            break;
+        case 3:
+            result = (mpWiimotePtr->leds & LED_3) != 0;
+            break;
+        case 4:
+            result = (mpWiimotePtr->leds & LED_4) != 0;
+        default:
+            result = 0;
+    }
+
+    return result;
+}
+
+/*
+ * Wii Class Methods
+ */
+
+CWii::CWii()
+{
+    mpWiimoteArraySize = 4;
+    mpWiimoteArray = wiic_init(mpWiimoteArraySize);
+}
+
+CWii::CWii(int MaxNumWiimotes)
+{
+    mpWiimoteArraySize = MaxNumWiimotes;
+    mpWiimoteArray = wiic_init(mpWiimoteArraySize);
+}
+
+CWii::~CWii()
+{
+    wiic_cleanup((struct wiimote_t**) mpWiimoteArray, mpWiimoteArraySize);
+}
+
+void CWii::RefreshWiimotes()
+{
+    int index;
+
+    // This approach is a bit wasteful but it will work.  The other
+    // option is to force the user to handle disconnect events to remove
+    // wiimotes from the array.
+    mpWiimotesVector.clear();
+
+    for(index = 0; index < mpWiimoteArraySize; index++)
+    {
+        if((mpWiimoteArray[index]->state & WIIMOTE_STATE_CONNECTED) != 0)
+        {
+            CWiimote wm(mpWiimoteArray[index]);
+            mpWiimotesVector.push_back(wm);
+        }
+    }
+}
+
+int CWii::GetNumConnectedWiimotes()
+{
+    int index;
+    int count = 0;
+
+    for(index = 0; index < mpWiimoteArraySize; index++)
+    {
+        if((mpWiimoteArray[index]->state & WIIMOTE_STATE_CONNECTED) != 0)
+            count++;
+    }
+
+    return count;
+}
+
+CWiimote& CWii::GetByID(int UnID, int Refresh)
+{
+    std::vector<CWiimote>::iterator i;
+
+    if(Refresh)
+        RefreshWiimotes();
+
+    for(i = mpWiimotesVector.begin(); i != mpWiimotesVector.end(); ++i)
+    {
+        if((*i).GetID() == UnID)
+            return *i;
+    }
+
+    return *mpWiimotesVector.begin(); // Return the first one if it was not found.
+}
+
+std::vector<CWiimote>& CWii::GetWiimotes(int Refresh)
+{
+    if(Refresh)
+        RefreshWiimotes();
+
+    return mpWiimotesVector;
+}
+
+int CWii::Find(int Timeout)
+{
+    return wiic_find((struct wiimote_t**) mpWiimoteArray, mpWiimoteArraySize, Timeout);
+}
+
+int CWii::LoadRegisteredWiimotes()
+{
+	return wiic_load((struct wiimote_t**) mpWiimoteArray);
+}
+
+/**
+ *
+ * @brief Connects to the found Wii devices.
+ *
+ * @param autoreconnect	[in] Automatically attempt to re-connect a Wii device in case of unexpected disconnection (default is disabled)
+ */
+std::vector<CWiimote>& CWii::Connect(bool autoreconnect)
+{
+    int numConnected = 0;
+    int index;
+
+    mpWiimotesVector.clear();
+
+    numConnected = wiic_connect((struct wiimote_t**) mpWiimoteArray, mpWiimoteArraySize, autoreconnect);
+
+    for(index = 0; index < numConnected; index++)
+    {
+        CWiimote wm(mpWiimoteArray[index]);
+        mpWiimotesVector.push_back(wm);
+    }
+
+    return mpWiimotesVector;
+}
+
+/**
+ *
+ * @brief Finds up to five devices and automatically connect to all of them.
+ *
+ * @param timeout	[in] Timeout for the discovery step (default is 5 seconds) 
+ * @param rumbleAck	[in] Each found and connected device will receive a small rumble ack (deafult is enabled)
+ * @param autoreconnect	[in] Automatically attempt to re-connect a Wii device in case of unexpected disconnection (default is disabled)
+ */
+std::vector<CWiimote>& CWii::FindAndConnect(int timeout, bool rumbleAck, bool autoreconnect)
+{
+    std::vector<CWiimote>::iterator i;
+    int numFound = 0;
+    int index;
+
+    //Find the wiimote
+    numFound = Find(timeout);
+
+    // Search for up to five seconds;
+    cout << "Found " << numFound << " wiimotes" << endl;
+    cout << "Connecting to wiimotes..." << endl;
+
+    // Connect to the wiimote
+    Connect(autoreconnect);
+
+	cout << "Connected to " << (unsigned int)mpWiimotesVector.size() << " wiimotes" << endl;
+
+    // Setup the wiimotes
+    for(index = 0, i = mpWiimotesVector.begin(); i != mpWiimotesVector.end(); ++i, ++index)
+    {
+        // Use a reference to make working with the iterator handy.
+        CWiimote & wiimote = *i;
+
+        //Rumble for 0.2 seconds as a connection ack
+		if(rumbleAck) {
+        	wiimote.SetRumbleMode(CWiimote::ON);
+        	usleep(200000);
+        	wiimote.SetRumbleMode(CWiimote::OFF);
+		}
+    }
+
+	return mpWiimotesVector;
+}
+
+int CWii::Poll()
+{
+	int events = wiic_poll((struct wiimote_t**) mpWiimoteArray, mpWiimoteArraySize);
+
+	// Logging
+	for(std::vector<CWiimote>::iterator i = mpWiimotesVector.begin() ; i != mpWiimotesVector.end() ; ++i)
+		if((*i).isLogEnabled())
+			(*i).Log();
+		
+	return events;
+}
Index: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h	(revision 9780)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h	(revision 9780)
@@ -0,0 +1,559 @@
+/*
+ *    wiicpp.h
+ *
+ *		This file is part of WiiC, written by:
+ *			Gabriele Randelli
+ *			Email: randelli@dis.uniroma1.it
+ *
+ *		Copyright 2010
+ *		
+ *		This file is based on WiiuseCpp, written By:
+ *        James Thomas
+ *        Email: jt@missioncognition.org
+ *
+ *    Copyright 2009
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ *		$Header$
+ *
+ */
+
+#ifndef WIICPP_H_
+#define WIICPP_H_
+
+#include <vector>
+#include <wiicpp/wiic/wiic.h>
+#include <wiicpp/log/dataset.h>
+#include <wiicpp/log/logger.h>
+
+using namespace WiiC;
+
+class CButtonBase
+{
+public:
+    CButtonBase(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr);
+
+    int isPressed(int Button);
+    int isHeld(int Button);
+    int isReleased(int Button);
+    int isJustPressed(int Button);
+
+private:
+    virtual short Cast(void *Ptr) {return *((short *)(Ptr));} // Inlined.
+
+    void *mpBtnsPtr;
+    void *mpBtnsHeldPtr;
+    void *mpBtnsReleasedPtr;
+};
+
+class CButtons : public CButtonBase
+{
+public:
+    enum ButtonDefs
+    {
+        BUTTON_TWO = WIIMOTE_BUTTON_TWO,
+        BUTTON_ONE = WIIMOTE_BUTTON_ONE,
+        BUTTON_B = WIIMOTE_BUTTON_B,
+        BUTTON_A = WIIMOTE_BUTTON_A,
+        BUTTON_MINUS = WIIMOTE_BUTTON_MINUS,
+        BUTTON_HOME = WIIMOTE_BUTTON_HOME,
+        BUTTON_LEFT = WIIMOTE_BUTTON_LEFT,
+        BUTTON_RIGHT = WIIMOTE_BUTTON_RIGHT,
+        BUTTON_DOWN = WIIMOTE_BUTTON_DOWN,
+        BUTTON_UP = WIIMOTE_BUTTON_UP,
+        BUTTON_PLUS = WIIMOTE_BUTTON_PLUS,
+        BUTTON_UNKNOWN = WIIMOTE_BUTTON_UNKNOWN,
+        BUTTON_ALL = WIIMOTE_BUTTON_ALL
+    };
+
+    CButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr);
+};
+
+class CNunchukButtons : public CButtonBase
+{
+public:
+    enum ButtonDefs
+    {
+        BUTTON_Z = NUNCHUK_BUTTON_Z,
+        BUTTON_C = NUNCHUK_BUTTON_C,
+        BUTTON_ALL = NUNCHUK_BUTTON_ALL
+    };
+
+    CNunchukButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr);
+
+private:
+    short Cast(void *Ptr) {return (short)(*((byte *)(Ptr)));} // Inlined using the different type.
+};
+
+class CClassicButtons : public CButtonBase
+{
+public:
+    enum ButtonDefs
+    {
+        BUTTON_X = CLASSIC_CTRL_BUTTON_X,
+        BUTTON_Y = CLASSIC_CTRL_BUTTON_Y,
+        BUTTON_B = CLASSIC_CTRL_BUTTON_B,
+        BUTTON_A = CLASSIC_CTRL_BUTTON_A,
+        BUTTON_MINUS = CLASSIC_CTRL_BUTTON_MINUS,
+        BUTTON_HOME = CLASSIC_CTRL_BUTTON_HOME,
+        BUTTON_LEFT = CLASSIC_CTRL_BUTTON_LEFT,
+        BUTTON_RIGHT = CLASSIC_CTRL_BUTTON_RIGHT,
+        BUTTON_DOWN = CLASSIC_CTRL_BUTTON_DOWN,
+        BUTTON_UP = CLASSIC_CTRL_BUTTON_UP,
+        BUTTON_PLUS = CLASSIC_CTRL_BUTTON_PLUS,
+        BUTTON_ZR = CLASSIC_CTRL_BUTTON_ZR,
+        BUTTON_ZL = CLASSIC_CTRL_BUTTON_ZL,
+        BUTTON_FULL_R = CLASSIC_CTRL_BUTTON_FULL_R,
+        BUTTON_FULL_L = CLASSIC_CTRL_BUTTON_FULL_L,
+        BUTTON_ALL = CLASSIC_CTRL_BUTTON_ALL
+    };
+
+    CClassicButtons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr);
+};
+
+class CGH3Buttons : public CButtonBase
+{
+public:
+    enum ButtonDefs
+    {
+        BUTTON_STRUM_UP = GUITAR_HERO_3_BUTTON_STRUM_UP,
+        BUTTON_STRUM_DOWN = GUITAR_HERO_3_BUTTON_STRUM_DOWN,
+        BUTTON_YELLOW = GUITAR_HERO_3_BUTTON_YELLOW,
+        BUTTON_GREEN = GUITAR_HERO_3_BUTTON_GREEN,
+        BUTTON_BLUE = GUITAR_HERO_3_BUTTON_BLUE,
+        BUTTON_RED = GUITAR_HERO_3_BUTTON_RED,
+        BUTTON_ORANGE = GUITAR_HERO_3_BUTTON_ORANGE,
+        BUTTON_MINUS = GUITAR_HERO_3_BUTTON_MINUS,
+        BUTTON_PLUS = GUITAR_HERO_3_BUTTON_PLUS,
+        BUTTON_ALL = GUITAR_HERO_3_BUTTON_ALL
+    };
+
+    CGH3Buttons(void *ButtonsPtr, void *ButtonsHeldPtr, void *ButtonsReleasedPtr);
+};
+
+class CJoystick
+{
+public:
+    CJoystick(struct joystick_t *JSPtr);
+
+    void GetMaxCal(int &X, int &Y);
+    void SetMaxCal(int X, int Y);
+
+    void GetMinCal(int &X, int &Y);
+    void SetMinCal(int X, int Y);
+
+    void GetCenterCal(int &X, int &Y);
+    void SetCenterCal(int X, int Y);
+
+    void GetPosition(float &Angle, float &Magnitude);
+
+private:
+    struct joystick_t *mpJoystickPtr;
+};
+
+class CAccelerometer
+{
+public:
+    CAccelerometer(struct accel_t *AccelCalPtr,
+                  struct vec3b_t *AccelerationPtr, int *AccelThresholdPtr,
+                  struct orient_t *OrientationPtr, float *OrientationThresholdPtr,
+                  struct gforce_t *GForcePtr);
+
+    float SetSmoothAlpha(float Alpha);
+
+    float GetOrientThreshold();
+    void SetOrientThreshold(float Threshold);
+
+    int GetAccelThreshold();
+    void SetAccelThreshold(int Threshold);
+
+    void GetOrientation(float &Pitch, float &Roll, float &Yaw);
+
+    void GetGravityCalVector(float &X, float &Y, float &Z);
+    void SetGravityCalVector(float X, float Y, float Z);
+
+    void GetGravityVector(float &X, float &Y, float &Z);
+	void GetRawGravityVector(float &X, float &Y, float &Z);
+
+private:
+    struct accel_t *mpAccelCalibPtr;
+    struct vec3b_t *mpAccelPtr;
+    struct orient_t *mpOrientPtr;
+    struct gforce_t *mpGForcePtr;
+    int *mpAccelThresholdPtr;
+    float *mpOrientThresholdPtr;
+};
+
+class CGyroscope
+{
+public:
+	CGyroscope(struct ang3s_t* RawGyro, struct ang3s_t* CalGyro, struct ang3f_t* AngleRate, unsigned char* Mode, struct motion_plus_t* MPPtr, 
+		int* GyroThresholdPtr);
+	void GetRawRates(int& Roll, int& Pitch, int& Yaw);
+	void GetRates(float& Roll, float& Pitch, float& Yaw);
+	void Calibrate();
+    int GetGyroThreshold();
+    void SetGyroThreshold(int Threshold);
+
+private:
+	struct ang3s_t* mpRawGyro;
+	struct ang3s_t* mpCalGyro;
+	struct ang3f_t* mpAngleRate;
+	struct motion_plus_t* mpMPPtr;
+	unsigned char* mpMode;
+	int* mpGyroThresholdPtr;
+};
+
+class CWeightSensor
+{
+public:
+	CWeightSensor(struct pressure_t* RawWeight, struct pressure_t* LowCalWeight, struct pressure_t* MediumCalWeight, struct pressure_t* HighCalWeight, struct pressure_weight_t* Weight, struct balance_board_t* BBPtr);
+	void GetRawWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight);
+	void GetWeight(float& TotalWeight, float& TopLeft, float& TopRight, float& BottomLeft, float& BottomRight);
+	void GetLowCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight);
+   void GetMediumCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight);
+   void GetHighCalWeight(int& TopLeft, int& TopRight, int& BottomLeft, int& BottomRight);
+
+private:
+	struct pressure_t* mpRawWeight;
+	struct pressure_t* mpLowCalWeight;
+	struct pressure_t* mpMediumCalWeight;
+	struct pressure_t* mpHighCalWeight;
+	struct pressure_weight_t* mpWeight;
+	struct balance_board_t* mpBBPtr;
+};
+
+class CIRDot
+{
+public:
+    CIRDot();
+    CIRDot(struct ir_dot_t *DotPtr);
+    CIRDot(const CIRDot & copyin);
+
+    int isVisible();
+    int GetSize();
+    int GetOrder();
+    void GetCoordinate(int &X, int &Y);
+    void GetRawCoordinate(int &X, int &Y);
+
+private:
+    struct ir_dot_t *mpDotPtr;
+};
+
+class CIR
+{
+public:
+    enum BarPositions
+    {
+        BAR_ABOVE = WIIC_IR_ABOVE,
+        BAR_BELOW = WIIC_IR_BELOW
+    };
+
+    enum AspectRatioSelections
+    {
+        ASPECT_4_3 = WIIC_ASPECT_4_3,
+        ASPECT_16_9 = WIIC_ASPECT_16_9
+    };
+
+    enum OnOffSelection
+    {
+        OFF = 0,
+        ON = 1
+    };
+
+    CIR(struct wiimote_t *wmPtr);
+
+    void SetMode(OnOffSelection State);
+    void SetVres(unsigned int x, unsigned int y);
+
+    BarPositions GetBarPositionSetting();
+    void SetBarPosition(BarPositions PositionSelection);
+
+    AspectRatioSelections GetAspectRatioSetting();
+    void SetAspectRatio(AspectRatioSelections AspectRatioSelection );
+
+    void SetSensitivity(int Level);
+    int GetSensitivity();
+
+    int GetNumDots();
+    std::vector<CIRDot>& GetDots();
+
+    void GetOffset(int &X, int &Y);
+    int GetState();
+    void GetCursorPositionAbsolute(int &X, int &Y);
+    void GetCursorPosition(int &X, int &Y);
+    float GetPixelDistance();
+    float GetDistance();
+
+private:
+    struct wiimote_t *mpWiimotePtr;
+    std::vector<CIRDot> mpIRDotsVector;
+};
+
+class CNunchuk
+{
+public:
+    CNunchuk(struct expansion_t *ExpPtr);
+
+    CNunchukButtons Buttons;
+    CJoystick Joystick;
+    CAccelerometer Accelerometer;
+
+private:
+    struct nunchuk_t *mpNunchukPtr;
+};
+
+class CClassic
+{
+public:
+    CClassic(struct expansion_t *ExpPtr);
+
+    float GetLShoulderButton();
+    float GetRShoulderButton();
+
+    CClassicButtons Buttons;
+    CJoystick LeftJoystick;
+    CJoystick RightJoystick;
+
+private:
+    struct classic_ctrl_t *mpClassicPtr;
+};
+
+class CGuitarHero3
+{
+public:
+    CGuitarHero3(struct expansion_t *ExpPtr);
+
+    float GetWhammyBar();
+
+    CGH3Buttons Buttons;
+    CJoystick Joystick;
+
+private:
+    struct guitar_hero_3_t *mpGH3Ptr;
+};
+
+
+class CMotionPlus
+{
+public:
+    CMotionPlus(struct expansion_t* MPPtr);
+
+	void Connect(struct wiimote_t* WiimotePtr);
+	void Disconnect(struct wiimote_t* WiimotePtr);
+	
+    CGyroscope Gyroscope;
+private:
+    struct motion_plus_t* mpMPPtr;
+};
+
+class CBalanceBoard
+{
+public:
+    CBalanceBoard(struct expansion_t* BBPtr);
+	
+    CWeightSensor WeightSensor;
+private:
+    struct balance_board_t* mpBBPtr;
+};
+
+class CExpansionDevice
+{
+public:
+    enum ExpTypes
+    {
+        TYPE_NONE = EXP_NONE,
+        TYPE_NUNCHUK = EXP_NUNCHUK,
+        TYPE_CLASSIC = EXP_CLASSIC,
+        TYPE_GUITAR_HERO_3 = EXP_GUITAR_HERO_3,
+        TYPE_MOTION_PLUS = EXP_MOTION_PLUS,
+		TYPE_BALANCE_BOARD = EXP_BALANCE_BOARD
+    };
+
+    CExpansionDevice(struct expansion_t *ExpPtr);
+
+    ExpTypes GetType();
+
+    CNunchuk Nunchuk;
+    CClassic Classic;
+    CGuitarHero3 GuitarHero3;
+    CMotionPlus MotionPlus;
+	CBalanceBoard BalanceBoard;
+
+private:
+    struct expansion_t *mpExpansionPtr;
+};
+
+
+class CWiimote
+{
+public:
+    enum LEDS
+    {
+        LED_NONE = WIIMOTE_LED_NONE,
+        LED_1 = WIIMOTE_LED_1,
+        LED_2 = WIIMOTE_LED_2,
+        LED_3 = WIIMOTE_LED_3,
+        LED_4 = WIIMOTE_LED_4
+
+    };
+
+    enum Flags
+    {
+        FLAG_SMOOTHING = WIIC_SMOOTHING,
+        FLAG_CONTINUOUS = WIIC_CONTINUOUS,
+        FLAG_ORIENT_THRESH = WIIC_ORIENT_THRESH,
+        FLAG_INIT_FLAGS = WIIC_INIT_FLAGS
+    };
+
+    enum EventTypes
+    {
+        EVENT_NONE = WIIC_NONE,
+        EVENT_EVENT = WIIC_EVENT,
+        EVENT_STATUS = WIIC_STATUS,
+        EVENT_CONNECT = WIIC_CONNECT,
+        EVENT_DISCONNECT = WIIC_DISCONNECT,
+        EVENT_UNEXPECTED_DISCONNECT = WIIC_UNEXPECTED_DISCONNECT,
+        EVENT_READ_DATA = WIIC_READ_DATA,
+        EVENT_NUNCHUK_INSERTED = WIIC_NUNCHUK_INSERTED,
+        EVENT_NUNCHUK_REMOVED = WIIC_NUNCHUK_REMOVED,
+        EVENT_CLASSIC_CTRL_INSERTED = WIIC_CLASSIC_CTRL_INSERTED,
+        EVENT_CLASSIC_CTRL_REMOVED = WIIC_CLASSIC_CTRL_REMOVED,
+        EVENT_GUITAR_HERO_3_CTRL_INSERTED = WIIC_GUITAR_HERO_3_CTRL_INSERTED,
+        EVENT_GUITAR_HERO_3_CTRL_REMOVED = WIIC_GUITAR_HERO_3_CTRL_REMOVED,
+        EVENT_MOTION_PLUS_INSERTED = WIIC_MOTION_PLUS_INSERTED,
+        EVENT_MOTION_PLUS_REMOVED = WIIC_MOTION_PLUS_REMOVED,
+		  EVENT_BALANCE_BOARD_INSERTED = WIIC_BALANCE_BOARD_INSERTED,
+		  EVENT_BALANCE_BOARD_REMOVED = WIIC_BALANCE_BOARD_REMOVED
+    };
+
+    enum OnOffSelection
+    {
+        OFF = 0,
+        ON = 1
+    };
+
+    static const int EVENT_BUFFER_LENGTH = MAX_PAYLOAD;
+
+    CWiimote();
+    CWiimote(struct wiimote_t *wmPtr);
+    CWiimote(const CWiimote & copyin);
+    ~CWiimote() { }
+
+    void Disconnected();
+
+    void SetRumbleMode(OnOffSelection State);
+    void ToggleRumble();
+    bool isRumbleEnabled();
+
+    int GetLEDs();
+    void SetLEDs(int LEDs);
+
+    float GetBatteryLevel();
+
+    int GetHandshakeState();
+
+    EventTypes GetEvent();
+    const unsigned char *GetEventBuffer();
+
+	void SetSmoothing(bool Smooth);
+
+    void SetMotionSensingMode(OnOffSelection State);
+    void EnableMotionPlus(OnOffSelection State);
+
+	/* Logging methods */
+	inline void LogStart(int type =WIIC_LOG_NONE, const string& file ="") { 
+		logType = type;
+		logger.SetLogLevel(WIIC_LOG_START, type, file);
+	}
+	inline void LogStop() { logger.SetLogLevel(WIIC_LOG_STOP); }
+	inline void Log(); 
+	
+	/* Timestamp methods */
+	inline struct timeval GetTimestamp() const { return mpWiimotePtr->timestamp; }
+
+	void EnableSpeaker(OnOffSelection State);
+	void MuteSpeaker(OnOffSelection State);
+	void PlaySound();
+
+    void ReadData(unsigned char *Buffer, unsigned int Offset, unsigned int Length);
+    void WriteData(unsigned int Address, unsigned char *Data, unsigned int Length);
+
+    void UpdateStatus();
+
+    int GetID();
+    const char* GetAddress();
+
+    int GetState();
+
+    int GetFlags();
+    int SetFlags(int Enable, int Disable);
+
+    void Resync();
+
+    void Disconnect();
+
+    int isUsingACC();
+    int isUsingEXP();
+    int isUsingIR();
+    int isUsingSpeaker();
+	int isSpeakerMuted();
+    int isUsingMotionPlus();
+    int isLEDSet(int LEDNum);
+	inline bool isLogEnabled() { return logger.isLogEnabled(); }
+
+    CIR IR;
+    CButtons Buttons;
+    CAccelerometer Accelerometer;
+    CExpansionDevice ExpansionDevice;
+
+    struct wiimote_t *mpWiimotePtr; // Pointer to the wm structure
+private:
+    int mpTempInt;
+    float mpTempFloat;
+    
+	Logger logger;
+	int logType;
+};
+
+class CWii
+{
+public:
+
+    CWii();
+    CWii(int MaxNumCWiimotes);
+    virtual ~CWii();
+
+    int GetNumConnectedWiimotes();
+
+    void RefreshWiimotes();
+
+    CWiimote& GetByID(int ID, int Refresh=1);
+    std::vector<CWiimote>& GetWiimotes(int Refresh=1);
+
+    int Find(int timeout);
+	int LoadRegisteredWiimotes();
+    std::vector<CWiimote>& Connect(bool autoreconnect =false);
+	std::vector<CWiimote>& FindAndConnect(int timeout =5, bool rumbleAck = true, bool autoreconnect =false);
+
+    int Poll();
+
+private:
+    struct wiimote_t **mpWiimoteArray;
+    int mpWiimoteArraySize;
+    std::vector<CWiimote> mpWiimotesVector;
+};
+
+#endif /* WIICPP_H_ */
