Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

GamepadController.cc

Go to the documentation of this file.
00001 #include <cassert>
00002 
00003 #include "GamepadController.h"
00004 #include "Behaviors/Controller.h"
00005 #include "Shared/Gamepad.h"
00006 #include <stdio.h>
00007 
00008 using namespace std;
00009 
00010 REGISTER_BEHAVIOR_MENU_OPT(GamepadController,"TekkotsuMon", BEH_START|BEH_NONEXCLUSIVE);
00011 
00012 GamepadController* GamepadController::theOne = NULL;
00013 
00014 // XXX: This would more accurately be a static assertion
00015 void GamepadController::checkInputMapping(int thisVal, int enumVal) {
00016   assert((thisVal - X_BUTTON + GamepadSrcID::gamepadXButtonSrcID) == enumVal);
00017 }
00018 
00019 void GamepadController::processInput(unsigned char *buf) {
00020   // Exract the input parameter
00021   float param;
00022   unsigned char *paramp = (unsigned char *) &param;
00023 
00024 
00025   unsigned char input = buf[0];
00026   /*
00027   std::cout << " buf=["
00028             << (int)buf[0] << " "
00029             << (int)buf[1] << " "
00030             << (int)buf[2] << " "
00031             << (int)buf[3] << " "
00032             << (int)buf[4] << "]" << std::endl;
00033   */
00034 
00035 #if defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN
00036   paramp[0] = buf[1];
00037   paramp[1] = buf[2];
00038   paramp[2] = buf[3];
00039   paramp[3] = buf[4];
00040 #else
00041   paramp[0] = buf[4];
00042   paramp[1] = buf[3];
00043   paramp[2] = buf[2];
00044   paramp[3] = buf[1];
00045 #endif
00046 
00047   // Check for invalid input
00048   if (input < X_BUTTON || input > R_BUMPER) {
00049     if ( input != 0 )
00050       std::cout << "Invalid gamepad input index'" << (int)buf[0] << "'\n";
00051     return;
00052   }
00053 
00054   // There is a direct mapping from input indicator values to sourceids
00055   int sid = input - X_BUTTON + GamepadSrcID::gamepadXButtonSrcID;
00056   EventBase::EventTypeID_t tid = EventBase::statusETID;
00057 
00058   // Check whether we should change the event TypeID
00059   if (input >= X_BUTTON && input <= SELECT_BUTTON) {
00060     if (param == 0) tid = EventBase::deactivateETID;
00061     else tid = EventBase::activateETID;
00062   }
00063 
00064   // Post the event
00065   erouter->postEvent(EventBase::buttonEGID, sid, tid, 0, "Gamepad Event", param);
00066 }
00067 
00068 void GamepadController::start() {
00069   // std::cout << "->->->->->->   Gamepad controller start" << std::endl;
00070   BehaviorBase::start();
00071   erouter->addListener(this, EventBase::runtimeEGID);
00072 
00073   theLastOne = theOne;
00074   theOne = this;
00075   inputsock = wireless->socket(Socket::SOCK_STREAM, 2048, 2048);
00076   sock = inputsock->sock;
00077   wireless->setReceiver(sock, input_callback);
00078   wireless->setDaemon(sock, true);
00079   wireless->listen(sock, config->main.gamepadControl_port);
00080 }
00081 
00082 void GamepadController::shutdown() {
00083   //Turn off timers
00084   erouter->removeListener(this);
00085   if (sock > 0) {
00086     wireless->setDaemon(sock, false);
00087     wireless->close(sock);
00088     inputsock = NULL;
00089     sock = -1;
00090   }
00091   theOne = theLastOne;
00092 }
00093 
00094 void GamepadController::stop() {
00095   // std::cout << "->->->->->->   Gamepad controller stop" << std::endl;
00096   shutdown();
00097   BehaviorBase::stop();
00098 }
00099 
00100 int GamepadController::input_callback(char* buf, int bytes) {
00101   static char cb_buf[5];
00102   static int cb_buf_filled;
00103 
00104   // If there's an incomplete command in the command buffer, fill
00105   // up as much of the command buffer as we can and then execute it
00106   // if possible
00107   if(cb_buf_filled) {
00108     while((cb_buf_filled < 5) && bytes) {
00109     cb_buf[cb_buf_filled++] = *buf++; // copy incoming buffer byte
00110     --bytes;        // decrement remaining byte ct.
00111     }
00112     // did we fill it? if so, execute! and mark buffer empty.
00113     if(cb_buf_filled == 5) {
00114       if (GamepadController::theOne)
00115         GamepadController::theOne->processInput((unsigned char*) cb_buf);
00116       cb_buf_filled = 0;
00117     }
00118   }
00119 
00120   // now execute all complete bytes in the incoming buffer
00121   while(bytes >= 5) {
00122     if (GamepadController::theOne)
00123       GamepadController::theOne->processInput((unsigned char *) buf);
00124     bytes -= 5;
00125     buf += 5;
00126   }
00127 
00128   // finally, store all remaining bytes in the command buffer
00129   while(bytes) {
00130     cb_buf[cb_buf_filled++] = *buf++;
00131     --bytes;
00132   }
00133 
00134   return 0;
00135 }
00136 
00137 /*! @file
00138  * @brief Implements GamepadController, listens for gamepad inputs and posts events appropriately
00139  * @author asf
00140  * @author med
00141  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:41 2016 by Doxygen 1.6.3