pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r3054 - trunk/pingus/src/input2


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3054 - trunk/pingus/src/input2
Date: Sun, 2 Sep 2007 02:13:12 +0200

Author: grumbel
Date: 2007-09-02 02:13:11 +0200 (Sun, 02 Sep 2007)
New Revision: 3054

Added:
   trunk/pingus/src/input2/wiimote.cpp
   trunk/pingus/src/input2/wiimote.hpp
   trunk/pingus/src/input2/wiimote_driver.cpp
Modified:
   trunk/pingus/src/input2/SConstruct
   trunk/pingus/src/input2/manager.cpp
   trunk/pingus/src/input2/wiimote_driver.hpp
Log:
- added basic Wiimote support (no IR or Accel right now)

Modified: trunk/pingus/src/input2/SConstruct
===================================================================
--- trunk/pingus/src/input2/SConstruct  2007-09-01 23:50:28 UTC (rev 3053)
+++ trunk/pingus/src/input2/SConstruct  2007-09-02 00:13:11 UTC (rev 3054)
@@ -1,7 +1,9 @@
 ##  -*- python -*-
 
 env = Environment(CCFLAGS  = ['-O0', '-Wall', '-Werror', '-g'],
-                  CPPPATH  = ['..', '../..'])
+                  CPPPATH  = ['..', '../..'],
+                  CPPDEFINES = ['HAVE_CWIID'],
+                  LIBS = ['cwiid'])
 
 env.ParseConfig('sdl-config  --cflags --libs')
 env['LIBS'] += ['SDL_image', 'SDL_mixer', 'png']
@@ -12,9 +14,12 @@
     'controller.cpp',
     'core_driver.cpp',
     'usbmouse_driver.cpp',
+    'wiimote_driver.cpp',
+    'wiimote.cpp',
     'sdl_driver.cpp',
     'manager.cpp',
     '../file_reader.cpp',
+    '../string_util.cpp',
     '../path_manager.cpp',
     '../pingus_error.cpp',
     '../lisp/parser.cpp',

Modified: trunk/pingus/src/input2/manager.cpp
===================================================================
--- trunk/pingus/src/input2/manager.cpp 2007-09-01 23:50:28 UTC (rev 3053)
+++ trunk/pingus/src/input2/manager.cpp 2007-09-02 00:13:11 UTC (rev 3054)
@@ -25,6 +25,9 @@
 #include "sdl_driver.hpp"
 #include "core_driver.hpp"
 #include "usbmouse_driver.hpp"
+#ifdef HAVE_CWIID
+#  include "wiimote_driver.hpp"
+#endif 
 #include "manager.hpp"
 
 namespace Input {
@@ -140,7 +143,7 @@
                   if (button)
                     ctrl_button->add_button(button);
                   else
-                    std::cout << "Manager: button: Couldn't create button" << 
j->get_name() << std::endl;
+                    std::cout << "Manager: button: Couldn't create button " << 
j->get_name() << std::endl;
                 }
             }
           else if (StringUtil::has_suffix(i->get_name(), "axis"))
@@ -154,7 +157,7 @@
                   if (axis)
                     ctrl_axis->add_axis(axis);
                   else
-                    std::cout << "Manager: axis: Couldn't create axis" << 
j->get_name() << std::endl;
+                    std::cout << "Manager: axis: Couldn't create axis " << 
j->get_name() << std::endl;
                 }
             }
           else
@@ -207,6 +210,10 @@
         driver = new CoreDriver(this);
       } else if (name == "usbmouse") {
         driver = new USBMouseDriver();
+#ifdef HAVE_CWIID
+      } else if (name == "wiimote") {
+        driver = new WiimoteDriver();
+#endif
       } else {
         std::cout << "Manager: Unknown driver: " << name << std::endl;
         return 0;

Added: trunk/pingus/src/input2/wiimote.cpp
===================================================================
--- trunk/pingus/src/input2/wiimote.cpp 2007-09-01 23:50:28 UTC (rev 3053)
+++ trunk/pingus/src/input2/wiimote.cpp 2007-09-02 00:13:11 UTC (rev 3054)
@@ -0,0 +1,503 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+**
+**  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 2
+**  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, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#include <iostream>
+#include <assert.h>
+#include <pthread.h>
+#include "math.hpp"
+#include "wiimote.hpp"
+
+Wiimote* wiimote = 0;
+
+#ifdef HAVE_CWIID
+
+void
+Wiimote::init()
+{
+  if (!wiimote)
+    wiimote = new Wiimote();
+}
+
+void
+Wiimote::deinit()
+{
+  delete wiimote;
+  wiimote = 0;
+}
+
+Wiimote::Wiimote()
+  : m_wiimote(0),
+    m_rumble(false),
+    m_led_state(0),
+    m_nunchuk_btns(0),
+    m_nunchuk_stick_x(0),
+    m_nunchuk_stick_y(0),
+    m_buttons(0)
+{
+  pthread_mutex_init(&mutex, NULL);
+
+  assert(wiimote == 0);
+  wiimote = this;
+  
+  cwiid_set_err(&Wiimote::err_callback);
+}
+
+Wiimote::~Wiimote()
+{
+  disconnect();
+  pthread_mutex_destroy(&mutex);
+}
+
+void
+Wiimote::connect()
+{
+  assert(m_wiimote == 0);
+
+  /* Connect to any wiimote */
+  bdaddr_t bdaddr = *BDADDR_ANY;
+
+  /* Connect to address in string WIIMOTE_BDADDR */
+  /* str2ba(WIIMOTE_BDADDR, &bdaddr); */
+
+  /* Connect to the wiimote */
+  printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
+
+  if (!(m_wiimote = cwiid_connect(&bdaddr, CWIID_FLAG_MESG_IFC))) 
+    {
+      fprintf(stderr, "Unable to connect to wiimote\n");
+    }
+  else 
+    {
+      std::cout << "Wiimote connected: " << m_wiimote << std::endl;
+      if (cwiid_set_mesg_callback(m_wiimote, &Wiimote::mesg_callback)) {
+        std::cerr << "Unable to set message callback" << std::endl;
+      }
+
+      if (cwiid_command(m_wiimote, CWIID_CMD_RPT_MODE, 
+                        CWIID_RPT_STATUS  |
+                        CWIID_RPT_NUNCHUK |
+                        CWIID_RPT_ACC     |
+                        CWIID_RPT_BTN))
+        {
+          std::cerr << "Wiimote: Error setting report mode" << std::endl;
+        }
+
+      { // read calibration data
+       uint8_t buf[7];
+
+        if (cwiid_read(m_wiimote, CWIID_RW_EEPROM, 0x16, 7, buf))
+          {
+            std::cout << "Wiimote: Unable to retrieve accelerometer 
calibration" << std::endl;
+          }
+        else
+          {
+            wiimote_zero.x = buf[0];
+            wiimote_zero.y = buf[1];
+            wiimote_zero.z = buf[2];
+
+            wiimote_one.x  = buf[4];
+            wiimote_one.y  = buf[5];
+            wiimote_one.z  = buf[6];
+          }
+
+        if (cwiid_read(m_wiimote, CWIID_RW_REG | CWIID_RW_DECODE, 0xA40020, 7, 
buf))
+          {
+            std::cout << "Wiimote: Unable to retrieve wiimote accelerometer 
calibration" << std::endl;
+          }
+        else
+          {
+            nunchuk_zero.x = buf[0];
+            nunchuk_zero.y = buf[1];
+            nunchuk_zero.z = buf[2];
+            
+            nunchuk_one.x  = buf[4];
+            nunchuk_one.y  = buf[5];
+            nunchuk_one.z  = buf[6];
+          }
+
+        std::cout << "Wiimote Calibration: "
+                  << (int)wiimote_zero.x << ", "
+                  << (int)wiimote_zero.x << ", "
+                  << (int)wiimote_zero.x << " - "
+                  << (int)wiimote_one.x << ", "
+                  << (int)wiimote_one.x << ", "
+                  << (int)wiimote_one.x << std::endl;
+
+        std::cout << "Nunchuk Calibration: "
+                  << (int)nunchuk_zero.x << ", "
+                  << (int)nunchuk_zero.x << ", "
+                  << (int)nunchuk_zero.x << " - "
+                  << (int)nunchuk_one.x << ", "
+                  << (int)nunchuk_one.x << ", "
+                  << (int)nunchuk_one.x << std::endl;
+          
+      }
+    }
+}
+
+void
+Wiimote::disconnect()
+{
+  if (m_wiimote)
+    {
+      cwiid_disconnect(m_wiimote);
+      m_wiimote = 0;
+    }
+}
+
+void
+Wiimote::set_led(unsigned char led_state)
+{
+  if (m_led_state != led_state)
+    {
+      //std::cout << "Wiimote: " << (int)m_led_state << std::endl;
+      m_led_state = led_state;
+
+      if (cwiid_command(m_wiimote, CWIID_CMD_LED, m_led_state)) {
+        fprintf(stderr, "Error setting LEDs \n");
+      }
+    }
+}
+
+void
+Wiimote::set_led(int num, bool state)
+{
+  assert(num >= 1 && num <= 4);
+
+  int new_led_state = m_led_state;
+  if (state)
+    new_led_state |= (1 << (num-1));
+  else // (!state)
+    new_led_state &= ~(1 << (num-1));
+
+  set_led(new_led_state);
+}
+
+void
+Wiimote::set_rumble(bool r)
+{
+  if (r != m_rumble)
+    {
+      m_rumble = r;
+
+      if (cwiid_command(m_wiimote, CWIID_CMD_RUMBLE, m_rumble)) {
+        std::cerr << "Error setting rumble" << std::endl;
+      }
+    }
+}
+
+void
+Wiimote::add_button_event(int device, int button, bool down)
+{
+  // std::cout << "Wiimote::add_button_event: " << device << " " << button << 
" " << down << std::endl;
+  WiimoteEvent event;
+
+  event.type = WiimoteEvent::WIIMOTE_BUTTON_EVENT;
+  event.button.device = 0;
+  event.button.button = button;
+  event.button.down   = down;
+
+  events.push_back(event);
+}
+
+void
+Wiimote::add_axis_event(int device, int axis, float pos)
+{
+  //std::cout << "Wiimote::add_axis_event: " << device << " " << axis << " " 
<< pos << std::endl;
+
+  WiimoteEvent event;
+
+  event.type = WiimoteEvent::WIIMOTE_AXIS_EVENT;
+  event.axis.device = 0;
+  event.axis.axis = axis;
+  event.axis.pos  = pos;
+
+  events.push_back(event); 
+}
+
+void
+Wiimote::add_acc_event(int device, int accelerometer, float x, float y, float 
z)
+{
+  WiimoteEvent event;
+
+  event.type = WiimoteEvent::WIIMOTE_ACC_EVENT;
+  event.acc.device = 0;
+  event.acc.accelerometer = accelerometer;
+  event.acc.x = x;
+  event.acc.y = y;
+  event.acc.z = z;
+
+  events.push_back(event);  
+}
+
+
+void
+Wiimote::on_status(const cwiid_status_mesg& msg)
+{
+  printf("Status Report: battery=%d extension=", msg.battery);
+  switch (msg.ext_type)
+    {
+    case CWIID_EXT_NONE:
+      printf("none");
+      break;
+
+    case CWIID_EXT_NUNCHUK:
+      printf("Nunchuk");
+      break;
+
+    case CWIID_EXT_CLASSIC:
+      printf("Classic Controller");
+      break;
+
+    default:
+      printf("Unknown Extension");
+      break;
+    }
+  printf("\n");
+}
+
+void
+Wiimote::on_error(const cwiid_error_mesg& msg)
+{
+  std::cout << "On Error" << std::endl;
+
+  if (m_wiimote)
+    {
+      if (cwiid_disconnect(m_wiimote)) 
+        {
+          fprintf(stderr, "Error on wiimote disconnect\n");
+          m_wiimote = 0;
+        }
+    }
+}
+
+void
+Wiimote::on_button(const cwiid_btn_mesg& msg)
+{
+#define CHECK_BTN(btn, num) if (changes & btn) add_button_event(0, num, 
m_buttons & btn)
+
+  uint16_t changes = m_buttons ^ msg.buttons;
+  m_buttons = msg.buttons;
+ 
+  CHECK_BTN(CWIID_BTN_A, 0);
+  CHECK_BTN(CWIID_BTN_B, 1);
+
+  CHECK_BTN(CWIID_BTN_LEFT,  2);
+  CHECK_BTN(CWIID_BTN_RIGHT, 3);
+  CHECK_BTN(CWIID_BTN_UP,    4);
+  CHECK_BTN(CWIID_BTN_DOWN,  5);
+
+  CHECK_BTN(CWIID_BTN_PLUS,  6);
+  CHECK_BTN(CWIID_BTN_HOME,  7);
+  CHECK_BTN(CWIID_BTN_MINUS, 8);
+
+  CHECK_BTN(CWIID_BTN_1,  9);
+  CHECK_BTN(CWIID_BTN_2, 10);
+}
+
+void
+Wiimote::on_acc(const cwiid_acc_mesg& msg)
+{
+  //printf("Acc Report: x=%d, y=%d, z=%d\n", msg.acc[0], msg.acc[1], 
msg.acc[2]);
+
+  add_acc_event(0, 0, 
+                (msg.acc[0] - wiimote_zero.x) / float(wiimote_one.x - 
wiimote_zero.x),
+                (msg.acc[1] - wiimote_zero.y) / float(wiimote_one.y - 
wiimote_zero.y),
+                (msg.acc[2] - wiimote_zero.z) / float(wiimote_one.z - 
wiimote_zero.z));
+}
+
+void
+Wiimote::on_ir(const cwiid_ir_mesg& msg)
+{
+  printf("IR Report: ");
+  for (int i = 0; i < CWIID_IR_SRC_COUNT; ++i)
+    {
+      if (msg.src[i].valid) {
+        printf("(%d,%d) ", msg.src[i].pos[0], msg.src[i].pos[1]);
+      }
+    }
+}
+
+/** Convert value to float while taking calibration data, left/center/right 
into account */
+inline float to_float(uint8_t min, 
+                      uint8_t center, 
+                      uint8_t max, 
+                      uint8_t value)
+{
+  if (value < center)
+    {
+      return Math::clamp(-1.0f, -(center - value) / float(center - min), 1.0f);
+    }
+  else if (value > center)
+    {
+      return Math::clamp(-1.0f, (value - center) / float(max - center), 1.0f);
+    }
+  else 
+    {
+      return 0.0f;
+    }
+}
+
+void
+Wiimote::on_nunchuck(const cwiid_nunchuk_mesg& msg)
+{
+  uint8_t changes = m_nunchuk_btns ^ msg.buttons;
+  m_nunchuk_btns  = msg.buttons;
+
+#define CHECK_NCK_BTN(btn, num) if (changes & btn) add_button_event(0, num, 
m_nunchuk_btns & btn)
+      
+  CHECK_NCK_BTN(CWIID_NUNCHUK_BTN_Z, 11);
+  CHECK_NCK_BTN(CWIID_NUNCHUK_BTN_C, 12);
+  
+  // FIXME: Read real calibration data, instead of hardcoded one
+  float nunchuk_stick_x =  to_float(37, 129, 231, msg.stick[0]);
+  float nunchuk_stick_y = -to_float(22, 119, 213, msg.stick[1]);
+
+  if (m_nunchuk_stick_x != nunchuk_stick_x)
+    {
+      m_nunchuk_stick_x = nunchuk_stick_x;
+      add_axis_event(0, 0, m_nunchuk_stick_x);
+    } 
+
+  if (m_nunchuk_stick_y != nunchuk_stick_y)
+    {
+      m_nunchuk_stick_y = nunchuk_stick_y;
+      add_axis_event(0, 1, m_nunchuk_stick_y);
+    }
+
+  add_acc_event(0, 1, 
+                (msg.acc[0] - nunchuk_zero.x) / float(nunchuk_one.x - 
nunchuk_zero.x),
+                (msg.acc[1] - nunchuk_zero.y) / float(nunchuk_one.y - 
nunchuk_zero.y),
+                (msg.acc[2] - nunchuk_zero.z) / float(nunchuk_one.z - 
nunchuk_zero.z));
+  if (0)
+    printf("Nunchuk Report: btns=%.2X stick=(%3d,%3d) (%5.2f, %5.2f) acc.x=%d 
acc.y=%d acc.z=%d\n", 
+           msg.buttons,
+           msg.stick[0], msg.stick[1], 
+           m_nunchuk_stick_x,
+           m_nunchuk_stick_y,
+           msg.acc[0], msg.acc[1], msg.acc[2]);
+}
+
+void
+Wiimote::on_classic(const cwiid_classic_mesg& msg)
+{
+  printf("Classic Report: btns=%.4X l_stick=(%d,%d) r_stick=(%d,%d) "
+         "l=%d r=%d\n", msg.buttons,
+         msg.l_stick[0], msg.l_stick[1],
+         msg.r_stick[0], msg.r_stick[1],
+         msg.l, msg.r);
+}
+
+std::vector<WiimoteEvent>
+Wiimote::pop_events()
+{
+  pthread_mutex_lock(&mutex);
+  std::vector<WiimoteEvent> ret = events;
+  events.clear();
+  pthread_mutex_unlock(&mutex);
+  return ret;
+}
+
+// Callback function that get called by the Wiimote thread
+void
+Wiimote::err(cwiid_wiimote_t* w, const char *s, va_list ap)
+{
+  pthread_mutex_lock(&mutex);
+
+  if (w) 
+    printf("%d:", cwiid_get_id(w));
+  else 
+    printf("-1:");
+
+  vprintf(s, ap);
+  printf("\n");  
+
+  pthread_mutex_unlock(&mutex);
+}
+
+void
+Wiimote::mesg(cwiid_wiimote_t* w, int mesg_count, union cwiid_mesg mesg[])
+{
+  pthread_mutex_lock(&mutex);
+
+  //std::cout << "StatusCallback: " << w << " " << mesg_count << std::endl;
+  for (int i=0; i < mesg_count; i++)
+    {
+      switch (mesg[i].type) 
+        {
+        case CWIID_MESG_STATUS:
+          wiimote->on_status(mesg[i].status_mesg);
+          break;
+
+        case CWIID_MESG_BTN:
+          wiimote->on_button(mesg[i].btn_mesg);
+          break;
+
+        case CWIID_MESG_ACC:
+          wiimote->on_acc(mesg[i].acc_mesg);
+          break;
+
+        case CWIID_MESG_IR:
+          wiimote->on_ir(mesg[i].ir_mesg);
+          break;
+
+        case CWIID_MESG_NUNCHUK:
+          wiimote->on_nunchuck(mesg[i].nunchuk_mesg);
+          break;
+
+        case CWIID_MESG_CLASSIC:
+          wiimote->on_classic(mesg[i].classic_mesg);
+          break;
+
+        case CWIID_MESG_ERROR:
+          wiimote->on_error(mesg[i].error_mesg);
+          break;
+
+        default:
+          printf("Wiimote: Unknown Report");
+          break;
+        }
+    }
+
+  pthread_mutex_unlock(&mutex);
+}
+
+// static callback functions
+  
+void
+Wiimote::err_callback(cwiid_wiimote_t* w, const char *s, va_list ap)
+{
+  wiimote->err(w, s, ap);
+}
+
+void
+Wiimote::mesg_callback(cwiid_wiimote_t* w, int mesg_count, union cwiid_mesg 
mesg[])
+{
+  wiimote->mesg(w, mesg_count, mesg);
+}
+
+#endif // HAVE_CWIID
+
+/* EOF */


Property changes on: trunk/pingus/src/input2/wiimote.cpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: trunk/pingus/src/input2/wiimote.hpp
===================================================================
--- trunk/pingus/src/input2/wiimote.hpp 2007-09-01 23:50:28 UTC (rev 3053)
+++ trunk/pingus/src/input2/wiimote.hpp 2007-09-02 00:13:11 UTC (rev 3054)
@@ -0,0 +1,148 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+**
+**  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 2
+**  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, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#ifndef HEADER_WIIMOTE_HPP
+#define HEADER_WIIMOTE_HPP
+
+#ifdef HAVE_CWIID
+
+#include <vector>
+#include "cwiid.h"
+
+struct WiimoteButtonEvent
+{
+  int  device;
+  int  button;
+  bool down; 
+};
+
+struct WiimoteAxisEvent
+{
+  int   device;
+  int   axis;
+  float pos;
+};
+
+struct WiimoteAccEvent
+{
+  int   device;
+  int   accelerometer;
+  float x;
+  float y;
+  float z;
+};
+
+struct WiimoteEvent
+{
+  enum { WIIMOTE_AXIS_EVENT, WIIMOTE_ACC_EVENT, WIIMOTE_BUTTON_EVENT } type;
+  union {
+    WiimoteAxisEvent   axis;
+    WiimoteButtonEvent button;
+    WiimoteAccEvent    acc;
+  };
+};
+
+struct AccCalibration
+{
+  uint8_t x;
+  uint8_t y;
+  uint8_t z;
+};
+
+/** */
+class Wiimote
+{
+public:
+  static void err_callback(cwiid_wiimote_t*, const char *s, va_list ap);
+  static void mesg_callback(cwiid_wiimote_t*, int mesg_count, union cwiid_mesg 
mesg[]);
+
+  static void init();
+  static void deinit();
+
+private:
+  pthread_mutex_t  mutex;
+  cwiid_wiimote_t* m_wiimote;
+  bool             m_rumble;
+  unsigned char    m_led_state;
+  uint8_t          m_nunchuk_btns;
+  float            m_nunchuk_stick_x;
+  float            m_nunchuk_stick_y;
+  uint16_t         m_buttons;
+
+  AccCalibration wiimote_zero;
+  AccCalibration wiimote_one;
+
+  AccCalibration nunchuk_zero;
+  AccCalibration nunchuk_one;
+
+  std::vector<WiimoteEvent> events;
+
+  void add_button_event(int device, int button, bool down);
+  void add_axis_event(int device, int axis, float pos);
+  void add_acc_event(int device, int accelerometer, float x, float y, float z);
+
+public:
+  Wiimote();
+  ~Wiimote();
+  
+  void connect();
+  void disconnect();
+
+  void set_led(int num, bool state);
+  void set_led(unsigned char led_state);
+  unsigned char get_led() const { return m_led_state; }
+
+  void set_rumble(bool t);
+  bool get_rumble() const { return m_rumble; }
+
+  std::vector<WiimoteEvent> pop_events();
+
+  bool is_connected() const { return m_wiimote != 0; }
+
+  // Callback functions
+  void on_status  (const cwiid_status_mesg& msg);
+  void on_error   (const cwiid_error_mesg& msg);
+  void on_button  (const cwiid_btn_mesg& msg);
+  void on_acc     (const cwiid_acc_mesg& msg);
+  void on_ir      (const cwiid_ir_mesg& msg);
+  void on_nunchuck(const cwiid_nunchuk_mesg& msg);
+  void on_classic (const cwiid_classic_mesg& msg);
+  
+  void mesg(cwiid_wiimote_t*, int mesg_count, union cwiid_mesg mesg[]);
+  void err(cwiid_wiimote_t*, const char *s, va_list ap);
+
+private:
+  Wiimote(const Wiimote&);
+  Wiimote& operator=(const Wiimote&);
+};
+
+#endif // HAVE_CWIID
+
+class Wiimote;
+extern Wiimote* wiimote;
+
+#endif
+
+/* EOF */


Property changes on: trunk/pingus/src/input2/wiimote.hpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: trunk/pingus/src/input2/wiimote_driver.cpp
===================================================================
--- trunk/pingus/src/input2/wiimote_driver.cpp  2007-09-01 23:50:28 UTC (rev 
3053)
+++ trunk/pingus/src/input2/wiimote_driver.cpp  2007-09-02 00:13:11 UTC (rev 
3054)
@@ -0,0 +1,227 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+**
+**  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 2
+**  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, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#include "string_util.hpp"
+#include "wiimote.hpp"
+#include "wiimote_driver.hpp"
+
+namespace Input {
+
+WiimoteDriver::WiimoteDriver()
+{
+  Wiimote::init();
+  wiimote->connect();
+}
+
+WiimoteDriver::~WiimoteDriver()
+{
+  Wiimote::deinit();
+}
+
+void
+WiimoteDriver::update(float delta)
+{
+  if (!wiimote || !wiimote->is_connected())
+    return;
+
+  std::vector<WiimoteEvent> events = wiimote->pop_events();
+  for(std::vector<WiimoteEvent>::iterator i = events.begin(); i != 
events.end(); ++i)
+    {
+      WiimoteEvent& event = *i;
+      if (event.type == WiimoteEvent::WIIMOTE_BUTTON_EVENT)
+        {
+          //if (event.button.down)
+          //  std::cout << event.button.button << std::endl;
+                  
+          for (std::vector<ButtonBinding>::const_iterator j = 
button_bindings.begin();
+               j != button_bindings.end();
+               ++j)
+            {
+              if (event.button.button == j->button)
+                {
+                  j->binding->set_state(event.button.down ? BUTTON_PRESSED : 
BUTTON_RELEASED);
+                }
+            }
+        }
+      else if (event.type == WiimoteEvent::WIIMOTE_AXIS_EVENT)
+        {
+          for (std::vector<AxisBinding>::const_iterator j = 
axis_bindings.begin();
+               j != axis_bindings.end(); ++j)
+            {
+              if (event.axis.axis == j->axis)
+                {
+                  j->binding->set_state(event.axis.pos);
+                }
+            }
+        }
+#if 0
+      else if (event.type == WiimoteEvent::WIIMOTE_ACC_EVENT)
+        {
+          if (event.acc.accelerometer == 0)
+            {
+              if (0)
+                printf("%d - %6.3f %6.3f %6.3f\n",  
+                       event.acc.accelerometer,
+                       event.acc.x,
+                       event.acc.y,
+                       event.acc.z);
+                 
+              float roll = atan(event.acc.x/event.acc.z);
+              if (event.acc.z <= 0.0) {
+                roll += M_PI * ((event.acc.x > 0.0) ? 1 : -1);
+              }
+              roll *= -1;
+
+              float pitch = atan(event.acc.y/event.acc.z*cos(roll));
+
+              add_axis_event(X2_AXIS, math::mid(-1.0f, -float(pitch / M_PI), 
1.0f));
+              add_axis_event(Y2_AXIS, math::mid(-1.0f, -float(roll  / M_PI), 
1.0f));
+
+              std::cout << boost::format("%|6.3f| %|6.3f|") % pitch % roll << 
std::endl;
+            }
+        }
+      else
+        {
+          assert(!"Never reached");
+        }
+#endif
+    }
+}
+
+Button*
+WiimoteDriver::create_button(const FileReader& reader, Control* parent) 
+{
+  std::string button;
+  if (reader.get_name() == "wiimote:button")
+    {
+      if (!reader.read_string("button", button))
+        {
+          std::cout << "WiimoteDriver: 'button' tag missing" << std::endl;
+          return 0;
+        }
+      else
+        {
+          button = StringUtil::to_lower(button);
+          int button_id = 0;
+          if (button == "a")
+            button_id = 0;
+          else if (button == "b")
+            button_id = 1;
+          else if (button == "dpad-left")
+            button_id = 2;
+          else if (button == "dpad-right")
+            button_id = 3;
+          else if (button == "dpad-up")
+            button_id = 4;
+          else if (button == "dpad-down")
+            button_id = 5;
+          else if (button == "+" || button == "plus")
+            button_id = 6;
+          else if (button == "home")
+            button_id = 7;
+          else if (button == "-" || button == "minus")
+            button_id = 8;
+          else if (button == "1")
+            button_id = 9;
+          else if (button == "2")
+            button_id = 10;
+          else if (button == "nunchuck:z")
+            button_id = 11;
+          else if (button == "nunchuck:c")
+            button_id = 12;
+          else
+            {
+              std::cout << "Error: WiimoteDriver: unknown button: " << button 
<< std::endl;
+              return 0;
+            }
+
+          ButtonBinding binding;
+          binding.binding = new Button(parent);
+          binding.button = button_id;
+          button_bindings.push_back(binding);
+
+          return binding.binding;
+        }
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+Axis*
+WiimoteDriver::create_axis(const FileReader& reader, Control* parent) 
+{
+  std::string axis;
+  if (reader.get_name() == "wiimote:axis")
+    {
+      if (!reader.read_string("axis", axis))
+        {
+          std::cout << "WiimoteDriver: 'axis' tag missing" << std::endl;
+          return 0;
+        }
+      else
+        {
+          axis = StringUtil::to_lower(axis);
+          int axis_id = 0;
+          if (axis == "nunchuck:x")
+            axis_id = 0;
+          else if (axis == "nunchuck:y")
+            axis_id = 0;
+          else
+            {
+              std::cout << "WiimoteDriver: unknown axis name: " << axis << 
std::endl;
+              return 0;
+            }
+
+          AxisBinding binding;
+          binding.binding = new Axis(parent);
+          binding.axis = axis_id;
+          axis_bindings.push_back(binding);
+
+          return binding.binding;
+        }
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+Scroller*
+WiimoteDriver::create_scroller(const FileReader& reader, Control* parent) 
+{
+  return 0; 
+}
+
+Pointer*
+WiimoteDriver::create_pointer (const FileReader& reader, Control* parent)
+{
+  return 0; 
+}
+
+} // namespace Input
+
+/* EOF */


Property changes on: trunk/pingus/src/input2/wiimote_driver.cpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/pingus/src/input2/wiimote_driver.hpp
===================================================================
--- trunk/pingus/src/input2/wiimote_driver.hpp  2007-09-01 23:50:28 UTC (rev 
3053)
+++ trunk/pingus/src/input2/wiimote_driver.hpp  2007-09-02 00:13:11 UTC (rev 
3054)
@@ -22,15 +22,43 @@
 #ifndef HEADER_WIIMOTE_DRIVER_HPP
 #define HEADER_WIIMOTE_DRIVER_HPP
 
+#include "driver.hpp"
+
+namespace Input {
+
 /** */
-class WiimoteDriver
+class WiimoteDriver : public Driver
 {
+private: 
+  struct ButtonBinding {
+    Button* binding;
+    int button;
+  };
+
+  struct AxisBinding {
+    Axis* binding;
+    int axis;
+  };
+
+  std::vector<ButtonBinding> button_bindings;
+  std::vector<AxisBinding>   axis_bindings;
+
 public:
   WiimoteDriver();
+  ~WiimoteDriver();
 
   void update(float delta);
+
+  std::string get_name() const { return "wiimote"; }
+  
+  Button*   create_button  (const FileReader& reader, Control* parent);
+  Axis*     create_axis    (const FileReader& reader, Control* parent);
+  Scroller* create_scroller(const FileReader& reader, Control* parent);
+  Pointer*  create_pointer (const FileReader& reader, Control* parent);
 };
 
+} // namespace Input
+
 #endif
 
 /* EOF */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]