[Orxonox-commit 5115] r9780 - in code/branches/wiimote: cmake cmake/tools src/external src/external/wiicpp src/external/wiicpp/log src/external/wiicpp/wiic src/external/wiicpp/wiicpp src/libraries/core/input
georgr at orxonox.net
georgr at orxonox.net
Mon Nov 11 16:35:43 CET 2013
Author: georgr
Date: 2013-11-11 16:35:43 +0100 (Mon, 11 Nov 2013)
New Revision: 9780
Added:
code/branches/wiimote/cmake/tools/FindBluetooth.cmake
code/branches/wiimote/src/external/wiicpp/
code/branches/wiimote/src/external/wiicpp/CMakeLists.txt
code/branches/wiimote/src/external/wiicpp/log/
code/branches/wiimote/src/external/wiicpp/log/accsample.cpp
code/branches/wiimote/src/external/wiicpp/log/accsample.h
code/branches/wiimote/src/external/wiicpp/log/dataset.cpp
code/branches/wiimote/src/external/wiicpp/log/dataset.h
code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp
code/branches/wiimote/src/external/wiicpp/log/gyrosample.h
code/branches/wiimote/src/external/wiicpp/log/logger.cpp
code/branches/wiimote/src/external/wiicpp/log/logger.h
code/branches/wiimote/src/external/wiicpp/log/sample.h
code/branches/wiimote/src/external/wiicpp/log/training.cpp
code/branches/wiimote/src/external/wiicpp/log/training.h
code/branches/wiimote/src/external/wiicpp/wiic/
code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt
code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c
code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h
code/branches/wiimote/src/external/wiicpp/wiic/classic.c
code/branches/wiimote/src/external/wiicpp/wiic/classic.h
code/branches/wiimote/src/external/wiicpp/wiic/definitions.h
code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c
code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h
code/branches/wiimote/src/external/wiicpp/wiic/events.c
code/branches/wiimote/src/external/wiicpp/wiic/events.h
code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c
code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h
code/branches/wiimote/src/external/wiicpp/wiic/io.c
code/branches/wiimote/src/external/wiicpp/wiic/io.h
code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h
code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m
code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c
code/branches/wiimote/src/external/wiicpp/wiic/ir.c
code/branches/wiimote/src/external/wiicpp/wiic/ir.h
code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c
code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h
code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c
code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h
code/branches/wiimote/src/external/wiicpp/wiic/speaker.c
code/branches/wiimote/src/external/wiicpp/wiic/speaker.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic.c
code/branches/wiimote/src/external/wiicpp/wiic/wiic.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h
code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h
code/branches/wiimote/src/external/wiicpp/wiicpp/
code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt
code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp
code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h
Modified:
code/branches/wiimote/cmake/LibraryConfig.cmake
code/branches/wiimote/src/external/CMakeLists.txt
code/branches/wiimote/src/libraries/core/input/WiiMote.cc
Log:
WiiCpp library successfully (?) added - won't work without libbluetooth-dev
Modified: code/branches/wiimote/cmake/LibraryConfig.cmake
===================================================================
--- code/branches/wiimote/cmake/LibraryConfig.cmake 2013-11-11 15:13:02 UTC (rev 9779)
+++ code/branches/wiimote/cmake/LibraryConfig.cmake 2013-11-11 15:35:43 UTC (rev 9780)
@@ -124,6 +124,7 @@
FIND_PACKAGE(Vorbis REQUIRED)
FIND_PACKAGE(ALUT REQUIRED)
FIND_PACKAGE(ZLIB REQUIRED)
+FIND_PACKAGE(Bluetooth REQUIRED)
IF(WIN32)
FIND_PACKAGE(DbgHelp)
Added: code/branches/wiimote/cmake/tools/FindBluetooth.cmake
===================================================================
--- code/branches/wiimote/cmake/tools/FindBluetooth.cmake (rev 0)
+++ code/branches/wiimote/cmake/tools/FindBluetooth.cmake 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,25 @@
+IF(LINUX)
+ MESSAGE(STATUS 'sewpertest')
+ FIND_PATH(BLUETOOTH_INCLUDE_DIR bluetooth.h /home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth)
+ FIND_LIBRARY(BLUETOOTH_LIBRARY NAMES bluetooth PATHS /usr/lib/x86_64-linux-gnu /home/georgr/libbluetooth-dev/libbluetooth-dev/usr/lib/x86_64-linux-gnu)
+ MESSAGE(STATUS "sewpertest 2 ${BLUETOOTH_LIBRARY}")
+ MESSAGE(STATUS "sewpertest 3 ${BLUETOOTH_INCLUDE_DIR}")
+ IF(BLUETOOTH_INCLUDE_DIR AND BLUETOOTH_LIBRARY)
+ SET(BLUETOOTH_FOUND TRUE)
+ ENDIF(BLUETOOTH_INCLUDE_DIR AND BLUETOOTH_LIBRARY)
+ENDIF(LINUX)
+
+IF(APPLE)
+ SET(BLUETOOTH_LIBRARY "-framework IOBluetooth")
+ SET(BLUETOOTH_FOUND TRUE)
+ENDIF(APPLE)
+
+IF (BLUETOOTH_FOUND)
+ IF (NOT Bluetooth_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Bluetooth: ${BLUETOOTH_LIBRARY}")
+ ENDIF (NOT Bluetooth_FIND_QUIETLY)
+ELSE (BLUETOOTH_FOUND)
+ IF (Bluetooth_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find Bluetooth. Please install Bluetooth package")
+ ENDIF (Bluetooth_FIND_REQUIRED)
+ENDIF (BLUETOOTH_FOUND)
Property changes on: code/branches/wiimote/cmake/tools/FindBluetooth.cmake
___________________________________________________________________
Added: svn:executable
+ *
Modified: code/branches/wiimote/src/external/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/CMakeLists.txt 2013-11-11 15:13:02 UTC (rev 9779)
+++ code/branches/wiimote/src/external/CMakeLists.txt 2013-11-11 15:35:43 UTC (rev 9780)
@@ -31,3 +31,6 @@
ENDIF()
ADD_SUBDIRECTORY(ois)
ADD_SUBDIRECTORY(tinyxml)
+IF(LINUX)
+ADD_SUBDIRECTORY(wiicpp)
+ENDIF(LINUX)
Added: code/branches/wiimote/src/external/wiicpp/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/CMakeLists.txt (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/CMakeLists.txt 2013-11-11 15:35:43 UTC (rev 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)
+
Property changes on: code/branches/wiimote/src/external/wiicpp/CMakeLists.txt
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/log/accsample.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/accsample.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/accsample.cpp 2013-11-11 15:35:43 UTC (rev 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;
+}
Added: code/branches/wiimote/src/external/wiicpp/log/accsample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/accsample.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/accsample.h 2013-11-11 15:35:43 UTC (rev 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
+
Added: code/branches/wiimote/src/external/wiicpp/log/dataset.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/dataset.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/dataset.cpp 2013-11-11 15:35:43 UTC (rev 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;
+}
+
+
Added: code/branches/wiimote/src/external/wiicpp/log/dataset.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/dataset.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/dataset.h 2013-11-11 15:35:43 UTC (rev 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
Added: code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/gyrosample.cpp 2013-11-11 15:35:43 UTC (rev 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;
+}
Added: code/branches/wiimote/src/external/wiicpp/log/gyrosample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/gyrosample.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/gyrosample.h 2013-11-11 15:35:43 UTC (rev 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
Added: code/branches/wiimote/src/external/wiicpp/log/logger.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/logger.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/logger.cpp 2013-11-11 15:35:43 UTC (rev 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;
+}
Added: code/branches/wiimote/src/external/wiicpp/log/logger.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/logger.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/logger.h 2013-11-11 15:35:43 UTC (rev 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
Added: code/branches/wiimote/src/external/wiicpp/log/sample.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/sample.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/sample.h 2013-11-11 15:35:43 UTC (rev 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
+
Added: code/branches/wiimote/src/external/wiicpp/log/training.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/training.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/training.cpp 2013-11-11 15:35:43 UTC (rev 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();
+}
Added: code/branches/wiimote/src/external/wiicpp/log/training.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/log/training.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/log/training.h 2013-11-11 15:35:43 UTC (rev 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
Added: code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt 2013-11-11 15:35:43 UTC (rev 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)
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/CMakeLists.txt
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c 2013-11-11 15:35:43 UTC (rev 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));
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h 2013-11-11 15:35:43 UTC (rev 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/balanceboard.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/classic.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/classic.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/classic.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,185 @@
+/*
+ * classic.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/classic.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/classic.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/classic.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/classic.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,56 @@
+/*
+ * classic.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/classic.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/definitions.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/definitions.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/definitions.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,70 @@
+/*
+ * definitions.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/definitions.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,197 @@
+/*
+ * dynamics.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,59 @@
+/*
+ * dynamics.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/events.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/events.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/events.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,941 @@
+/*
+ * events.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/events.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/events.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/events.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/events.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,57 @@
+/*
+ * events.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/events.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,168 @@
+/*
+ * guitar_hero_3.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,65 @@
+/*
+ * guitar_hero_3.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/guitar_hero_3.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/io.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,122 @@
+/*
+ * io.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+ }
+ }
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/io.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/io.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,59 @@
+/*
+ * io.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/io.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h 2013-11-11 15:35:43 UTC (rev 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"
+
+ at 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;
+
+ at end
+
+ at 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;
+ at end
+
+#endif /* IO_MAC_H */
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m 2013-11-11 15:35:43 UTC (rev 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;
+
+ at 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];
+}
+
+ at end
+
+ at 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]);
+}
+
+
+ at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,341 @@
+/*
+ * io_nix.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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__ */
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/ir.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/ir.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/ir.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,742 @@
+/*
+ * ir.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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) );
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/ir.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/ir.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/ir.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/ir.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,59 @@
+/*
+ * ir.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
+
+
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/ir.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c 2013-11-11 15:35:43 UTC (rev 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h 2013-11-11 15:35:43 UTC (rev 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/motionplus.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,209 @@
+/*
+ * nunchuck.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,56 @@
+/*
+ * nunchuck.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/nunchuk.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/speaker.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/speaker.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/speaker.c 2013-11-11 15:35:43 UTC (rev 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);
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/speaker.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/speaker.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/speaker.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/speaker.h 2013-11-11 15:35:43 UTC (rev 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
+
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/speaker.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic.c
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic.c (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic.c 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,720 @@
+/*
+ * wiic.c
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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);
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic.c
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,86 @@
+/*
+ * wiic.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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 */
+
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,33 @@
+/*
+ * wiic_doc.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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.
+ *
+ *
+ */
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic_doc.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,98 @@
+/*
+ * wiic_functions.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic_functions.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,232 @@
+/*
+ * wiic_internal.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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 */
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic_internal.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,243 @@
+/*
+ * wiic_macros.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic_macros.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,474 @@
+/*
+ * wiic_structs.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at 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;
Property changes on: code/branches/wiimote/src/external/wiicpp/wiic/wiic_structs.h
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt 2013-11-11 15:35:43 UTC (rev 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}
+
+)
+
Property changes on: code/branches/wiimote/src/external/wiicpp/wiicpp/CMakeLists.txt
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,997 @@
+/*
+ * wiicpp.cpp
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at dis.uniroma1.it
+ *
+ * Copyright 2010
+ *
+ * This file is based on WiiuseCpp, written By:
+ * James Thomas
+ * Email: jt at 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 ©in) // 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 ©in) : // 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;
+}
Property changes on: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.cpp
___________________________________________________________________
Added: svn:executable
+ *
Added: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h
===================================================================
--- code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h (rev 0)
+++ code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h 2013-11-11 15:35:43 UTC (rev 9780)
@@ -0,0 +1,559 @@
+/*
+ * wiicpp.h
+ *
+ * This file is part of WiiC, written by:
+ * Gabriele Randelli
+ * Email: randelli at dis.uniroma1.it
+ *
+ * Copyright 2010
+ *
+ * This file is based on WiiuseCpp, written By:
+ * James Thomas
+ * Email: jt at 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_ */
Property changes on: code/branches/wiimote/src/external/wiicpp/wiicpp/wiicpp.h
___________________________________________________________________
Added: svn:executable
+ *
Modified: code/branches/wiimote/src/libraries/core/input/WiiMote.cc
===================================================================
--- code/branches/wiimote/src/libraries/core/input/WiiMote.cc 2013-11-11 15:13:02 UTC (rev 9779)
+++ code/branches/wiimote/src/libraries/core/input/WiiMote.cc 2013-11-11 15:35:43 UTC (rev 9780)
@@ -1,6 +1,7 @@
#include "WiiMote.h"
#include "core/CoreIncludes.h"
#include "core/command/ConsoleCommand.h"
+#include <wiicpp/wiicpp/wiicpp.h>
namespace orxonox
{
@@ -8,7 +9,7 @@
const std::string WiiMote::deviceName = "WiiMote";
void WiiMote::update(const Clock& time)
{
- orxout()<<"fegit";
+ orxout()<<"fegit\n";
}
void WiiMote::clearBuffers()
More information about the Orxonox-commit
mailing list