Andrew n marshall wrote:
// [BMLR] Get command from renderer and external programs vector<string>* BoneBusClient::GetCommand() { std::string result = ""; if ( m_sockTCP != NULL ) { fd_set SocketSet; FD_ZERO(&SocketSet); ...

Crud...  Okay, it the last three methods of this file:


Anm
/*
   This file is part of VHMsg written by Edward Fast at 
   University of Southern California's Institute for Creative Technologies.
   http://www.ict.usc.edu
   Copyright 2008 Edward Fast, University of Southern California

   VHMsg is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   VHMsg 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 Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with VHMsg.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <winsock.h>
#include <string>

#include "bonebus.h"


using std::string;
using std::vector;


BoneBusCharacter::BoneBusCharacter( const bool useFaceBones, SOCKET sockUDP, 
sockaddr_in toAddrUDP, SOCKET sockTCP )
{
   m_sockUDP = sockUDP;
   m_toAddrUDP = toAddrUDP;
   m_sockTCP = sockTCP;


   NetworkMapBoneNames( m_boneNameMap, useFaceBones );

   if ( !useFaceBones )
      NetworkMapVisemeNames( m_visemeNameMap );
}


BoneBusCharacter::~BoneBusCharacter()
{
}


void BoneBusCharacter::StartSendBoneRotations()
{
   m_bulkBoneRotations.numBoneRotations = 0;
}


void BoneBusCharacter::EndSendBoneRotations()
{
   if ( m_bulkBoneRotations.numBoneRotations <= 0 )
   {
      return;
   }

   int packetSize = BulkBoneRotationsHeaderSize + ( sizeof( BulkBoneRotation ) 
* m_bulkBoneRotations.numBoneRotations );

   //printf( "Rotation Packet size: %d\n", packetSize );

   int bytesSent;
   bytesSent = sendto( m_sockUDP, (const char *)&m_bulkBoneRotations, 
packetSize, 0, (SOCKADDR*)&m_toAddrUDP, sizeof( m_toAddrUDP ) );
   if ( bytesSent < 0 )
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if ( bytesSent > 0 )
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusCharacter::AddBoneRotation( const char * boneName, const float w, 
const float x, const float y, const float z )
{
   int packetSize = BulkBoneRotationsHeaderSize + ( sizeof( BulkBoneRotation ) 
* m_bulkBoneRotations.numBoneRotations );

   if ( packetSize > 2000 )
   {
      //return;
      EndSendBonePositions();
      StartSendBoneRotations();
      packetSize = BulkBoneRotationsHeaderSize + ( sizeof( BulkBoneRotation ) * 
m_bulkBoneRotations.numBoneRotations );
   }

   BoneNameMapIter iter = m_boneNameMap.find( boneName );

   if ( iter == m_boneNameMap.end() )
   {
      return;
   }

   BoneNameMapData & data = iter->second;

   // check to see if we've sent this data before
   // if we have, send it again to account for packet loss
   // and then don't send it again until the bone has moved
   if ( data.cacheQuatW == w &&
         data.cacheQuatX == x &&
         data.cacheQuatY == y &&
         data.cacheQuatZ == z )
   {
      data.cacheQuatHits++;

      if ( data.cacheQuatHits > 1 )
      {
         //return;
      }
   }
   else
   {
      data.cacheQuatW = w;
      data.cacheQuatX = x;
      data.cacheQuatY = y;
      data.cacheQuatZ = z;
      data.cacheQuatHits = 0;
   }


   BulkBoneRotation * item = &m_bulkBoneRotations.bones[ 
m_bulkBoneRotations.numBoneRotations ];

   item->boneId = data.networkId;
   item->rot_w  = w;
   item->rot_x  = x;
   item->rot_y  = y;
   item->rot_z  = z;

   m_bulkBoneRotations.numBoneRotations++;
}


void BoneBusCharacter::StartSendBonePositions()
{
   m_bulkBonePositions.charId           = m_charId;
   m_bulkBonePositions.numBonePositions = 0;
}


void BoneBusCharacter::EndSendBonePositions()
{
   if ( m_bulkBonePositions.numBonePositions <= 0 )
   {
      return;
   }

   int packetSize = BulkBonePositionsHeaderSize + ( sizeof( BulkBonePosition ) 
* m_bulkBonePositions.numBonePositions );

   //printf( "Position Packet size: %d\n", packetSize );

   int bytesSent;
   bytesSent = sendto( m_sockUDP, (const char *)&m_bulkBonePositions, 
packetSize, 0, (SOCKADDR*)&m_toAddrUDP, sizeof( m_toAddrUDP ) );
   if ( bytesSent < 0 )
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if ( bytesSent > 0 )
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusCharacter::AddBonePosition( const char * boneName, const float x, 
const float y, const float z )
{
   int packetSize = BulkBonePositionsHeaderSize + ( sizeof( BulkBonePosition ) 
* m_bulkBonePositions.numBonePositions );

   if ( packetSize > 2000 )
   {
      //return;
      EndSendBonePositions();
      StartSendBonePositions();
      packetSize = BulkBonePositionsHeaderSize + ( sizeof( BulkBonePosition ) * 
m_bulkBonePositions.numBonePositions );
   }


   BoneNameMapIter iter = m_boneNameMap.find( boneName );

   if ( iter == m_boneNameMap.end() )
   {
      return;
   }

   BoneNameMapData & data = iter->second;

   // check to see if we've sent this data before
   // if we have, send it again to account for packet loss
   // and then don't send it again until the bone has moved
   if ( data.cachePosX == x &&
         data.cachePosY == y &&
         data.cachePosZ == z )
   {
      data.cachePosHits++;

      if ( data.cachePosHits > 1 )
      {
         //return;
      }
   }
   else
   {
      data.cachePosX = x;
      data.cachePosY = y;
      data.cachePosZ = z;
      data.cachePosHits = 0;
   }


   BulkBonePosition * item = &m_bulkBonePositions.bones[ 
m_bulkBonePositions.numBonePositions ];

   item->boneId = data.networkId;
   item->pos_x  = x;
   item->pos_y  = y;
   item->pos_z  = z;

   m_bulkBonePositions.numBonePositions++;
}


void BoneBusCharacter::SetViseme( const char * viseme, const float weight, 
const float blendTime )
{
   if ( m_visemeNameMap.find( viseme ) == m_visemeNameMap.end() )
   {
      return;
   }

   char b[ 512 ];
   int  blen;
   sprintf( b, "SetActorViseme|%d|%d|%f|%f;", m_charId, m_visemeNameMap[ viseme 
], weight, blendTime );
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusCharacter::SetPosition( const float x, const float y, const float z 
)
{
   // check to see if we've sent this data before
   // if we have, send it again to account for packet loss
   // and then don't send it again until the bone has moved
   if ( m_cachePosX == x &&
         m_cachePosY == y &&
         m_cachePosZ == z )
   {
      m_cachePosHits++;

      if ( m_cachePosHits > 1 )
      {
         return;
      }
   }
   else
   {
      m_cachePosX = x;
      m_cachePosY = y;
      m_cachePosZ = z;
      m_cachePosHits = 0;
   }


   //printf( "Calling 'SetActorPos %d %f %f %f'\n", character->charId, x, y, z 
);

   char b[ 512 ];
   int  blen;
   sprintf( b, "SetActorPos|%d|%f|%f|%f;", m_charId, x, y, z );
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusCharacter::SetRotation( const float w, const float x, const float 
y, const float z )
{
   // check to see if we've sent this data before
   // if we have, send it again to account for packet loss
   // and then don't send it again until the bone has moved
   if ( m_cacheQuatW == w &&
         m_cacheQuatX == x &&
         m_cacheQuatY == y &&
         m_cacheQuatZ == z )
   {
      m_cacheQuatHits++;

      if ( m_cacheQuatHits > 1 )
      {
         return;
      }
   }
   else
   {
      m_cacheQuatW = w;
      m_cacheQuatX = x;
      m_cacheQuatY = y;
      m_cacheQuatZ = z;
      m_cacheQuatHits = 0;
   }


   //printf( "Calling 'SetActorRot %d %f %f %f %f'\n", character->charId, w, x, 
y, z );

   char b[ 512 ];
   int  blen;
   sprintf( b, "SetActorRot|%d|%f|%f|%f|%f;", m_charId, w, x, y, z );
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusCharacter::NetworkMapBoneNames( BoneNameMap & boneNameMap, const 
bool faceBones )
{
   boneNameMap.clear();

   // smartbody doctor
   boneNameMap[ "skeleton" ]        = BoneNameMapData( 1 );
   boneNameMap[ "base" ]            = BoneNameMapData(  2 );
   boneNameMap[ "l_hip" ]           = BoneNameMapData(  3 );
   boneNameMap[ "l_knee" ]          = BoneNameMapData(  4 );
   boneNameMap[ "l_ankle" ]         = BoneNameMapData(  5 );
   boneNameMap[ "l_forefoot" ]      = BoneNameMapData(  6 );
   boneNameMap[ "l_toe" ]           = BoneNameMapData(  7 );
   boneNameMap[ "r_hip" ]           = BoneNameMapData(  8 );
   boneNameMap[ "r_knee" ]          = BoneNameMapData(  9 );
   boneNameMap[ "r_ankle" ]         = BoneNameMapData( 10 );
   boneNameMap[ "r_forefoot" ]      = BoneNameMapData( 11 );
   boneNameMap[ "r_toe" ]           = BoneNameMapData( 12 );
   boneNameMap[ "spine1" ]          = BoneNameMapData( 13 );
   boneNameMap[ "spine2" ]          = BoneNameMapData( 14 );
   boneNameMap[ "spine3" ]          = BoneNameMapData( 15 );
   boneNameMap[ "spine4" ]          = BoneNameMapData( 16 );
   boneNameMap[ "spine5" ]          = BoneNameMapData( 17 );
   boneNameMap[ "skullbase" ]       = BoneNameMapData( 18 );

   if ( faceBones )
   {
      boneNameMap[ "face_top_parent" ]    = BoneNameMapData( 19 );
      boneNameMap[ "brow_parent_left" ]   = BoneNameMapData( 20 );
      boneNameMap[ "brow01_left" ]        = BoneNameMapData( 21 );
      boneNameMap[ "brow02_left" ]        = BoneNameMapData( 22 );
      boneNameMap[ "brow03_left" ]        = BoneNameMapData( 23 );
      boneNameMap[ "brow04_left" ]        = BoneNameMapData( 24 );
      boneNameMap[ "brow_parent_right" ]  = BoneNameMapData( 25 );
      boneNameMap[ "brow01_right" ]       = BoneNameMapData( 26 );
      boneNameMap[ "brow02_right" ]       = BoneNameMapData( 27 );
      boneNameMap[ "brow03_right" ]       = BoneNameMapData( 28 );
      boneNameMap[ "brow05_right" ]       = BoneNameMapData( 29 );
      boneNameMap[ "ear_left" ]           = BoneNameMapData( 30 );
      boneNameMap[ "eyeball_left" ]       = BoneNameMapData( 31 );
      boneNameMap[ "upper_nose_left" ]    = BoneNameMapData( 32 );
      boneNameMap[ "lower_nose_left" ]    = BoneNameMapData( 33 );
      boneNameMap[ "upper_nose_right" ]   = BoneNameMapData( 34 );
      boneNameMap[ "lower_nose_right" ]   = BoneNameMapData( 35 );
      boneNameMap[ "lower_eyelid_right" ] = BoneNameMapData( 36 );
      boneNameMap[ "upper_eyelid_right" ] = BoneNameMapData( 37 );
      boneNameMap[ "eyeball_right" ]      = BoneNameMapData( 38 );
      boneNameMap[ "ear_right" ]          = BoneNameMapData( 39 );
      boneNameMap[ "lower_eyelid_left" ]  = BoneNameMapData( 40 );
      boneNameMap[ "upper_eyelid_left" ]  = BoneNameMapData( 41 );
      boneNameMap[ "joint18" ]            = BoneNameMapData( 42 );
      boneNameMap[ "face_bottom_parent" ] = BoneNameMapData( 43 );
      boneNameMap[ "Jaw" ]             = BoneNameMapData( 44 );
      boneNameMap[ "Jaw_back" ]        = BoneNameMapData( 45 );
      boneNameMap[ "Jaw_front" ]       = BoneNameMapData( 46 );
      boneNameMap[ "Lip_bttm_mid" ]    = BoneNameMapData( 47 );
      boneNameMap[ "Lip_bttm_right" ]  = BoneNameMapData( 48 );
      boneNameMap[ "Lip_bttm_left" ]   = BoneNameMapData( 49 );
      boneNameMap[ "Tongue_back" ]     = BoneNameMapData( 50 );
      boneNameMap[ "Tongue_mid" ]      = BoneNameMapData( 51 );
      boneNameMap[ "Tongue_front" ]    = BoneNameMapData( 52 );
      boneNameMap[ "Lip_top_left" ]    = BoneNameMapData( 53 );
      boneNameMap[ "Lip_top_right" ]   = BoneNameMapData( 54 );
      boneNameMap[ "Cheek_low_right" ] = BoneNameMapData( 55 );
      boneNameMap[ "Cheek_up_right" ]  = BoneNameMapData( 56 );
      boneNameMap[ "cheek_low_left" ]  = BoneNameMapData( 57 );
      boneNameMap[ "Cheek_up_left" ]   = BoneNameMapData( 58 );
      boneNameMap[ "Lip_out_left" ]    = BoneNameMapData( 59 );
      boneNameMap[ "Lip_out_right" ]   = BoneNameMapData( 60 );
      boneNameMap[ "Lip_top_mid" ]     = BoneNameMapData( 61 );
   }
   else
   {
      boneNameMap[ "eyeball_left" ]       = BoneNameMapData( 31 );
      boneNameMap[ "eyeball_right" ]      = BoneNameMapData( 38 );
   }

   boneNameMap[ "l_sternoclavicular" ] = BoneNameMapData( 62 );
   boneNameMap[ "l_acromioclavicular" ] = BoneNameMapData( 63 );
   boneNameMap[ "l_shoulder" ]      = BoneNameMapData( 64 );
   boneNameMap[ "l_elbow" ]         = BoneNameMapData( 65 );
   boneNameMap[ "l_forearm" ]       = BoneNameMapData( 66 );
   boneNameMap[ "l_wrist" ]         = BoneNameMapData( 67 );
   boneNameMap[ "l_pinky1" ]        = BoneNameMapData( 68 );
   boneNameMap[ "l_pinky2" ]        = BoneNameMapData( 69 );
   boneNameMap[ "l_pinky3" ]        = BoneNameMapData( 70 );
   boneNameMap[ "l_pinky4" ]        = BoneNameMapData( 71 );
   boneNameMap[ "l_ring1" ]         = BoneNameMapData( 72 );
   boneNameMap[ "l_ring2" ]         = BoneNameMapData( 73 );
   boneNameMap[ "l_ring3" ]         = BoneNameMapData( 74 );
   boneNameMap[ "l_ring4" ]         = BoneNameMapData( 75 );
   boneNameMap[ "l_middle1" ]       = BoneNameMapData( 76 );
   boneNameMap[ "l_middle2" ]       = BoneNameMapData( 77 );
   boneNameMap[ "l_middle3" ]       = BoneNameMapData( 78 );
   boneNameMap[ "l_middle4" ]       = BoneNameMapData( 79 );
   boneNameMap[ "l_index1" ]        = BoneNameMapData( 80 );
   boneNameMap[ "l_index2" ]        = BoneNameMapData( 81 );
   boneNameMap[ "l_index3" ]        = BoneNameMapData( 82 );
   boneNameMap[ "l_index4" ]        = BoneNameMapData( 83 );
   boneNameMap[ "l_thumb1" ]        = BoneNameMapData( 84 );
   boneNameMap[ "l_thumb2" ]        = BoneNameMapData( 85 );
   boneNameMap[ "l_thumb3" ]        = BoneNameMapData( 86 );
   boneNameMap[ "l_thumb4" ]        = BoneNameMapData( 87 );
   boneNameMap[ "r_sternoclavicular" ] = BoneNameMapData( 88 );
   boneNameMap[ "r_acromioclavicular" ] = BoneNameMapData( 89 );
   boneNameMap[ "r_shoulder" ]      = BoneNameMapData( 90 );
   boneNameMap[ "r_elbow" ]         = BoneNameMapData( 91 );
   boneNameMap[ "r_forearm" ]       = BoneNameMapData( 92 );
   boneNameMap[ "r_wrist" ]         = BoneNameMapData( 93 );
   boneNameMap[ "r_pinky1" ]        = BoneNameMapData( 94 );
   boneNameMap[ "r_pinky2" ]        = BoneNameMapData( 95 );
   boneNameMap[ "r_pinky3" ]        = BoneNameMapData( 96 );
   boneNameMap[ "r_pinky4" ]        = BoneNameMapData( 97 );
   boneNameMap[ "r_ring1" ]         = BoneNameMapData( 98 );
   boneNameMap[ "r_ring2" ]         = BoneNameMapData( 99 );
   boneNameMap[ "r_ring3" ]         = BoneNameMapData( 100 );
   boneNameMap[ "r_ring4" ]         = BoneNameMapData( 101 );
   boneNameMap[ "r_middle1" ]       = BoneNameMapData( 102 );
   boneNameMap[ "r_middle2" ]       = BoneNameMapData( 103 );
   boneNameMap[ "r_middle3" ]       = BoneNameMapData( 104 );
   boneNameMap[ "r_middle4" ]       = BoneNameMapData( 105 );
   boneNameMap[ "r_index1" ]        = BoneNameMapData( 106 );
   boneNameMap[ "r_index2" ]        = BoneNameMapData( 107 );
   boneNameMap[ "r_index3" ]        = BoneNameMapData( 108 );
   boneNameMap[ "r_index4" ]        = BoneNameMapData( 109 );
   boneNameMap[ "r_thumb1" ]        = BoneNameMapData( 110 );
   boneNameMap[ "r_thumb2" ]        = BoneNameMapData( 111 );
   boneNameMap[ "r_thumb3" ]        = BoneNameMapData( 112 );
   boneNameMap[ "r_thumb4" ]        = BoneNameMapData( 113 );
}


void BoneBusCharacter::NetworkMapVisemeNames( VisemeNameMap & visemeNameMap )
{
   visemeNameMap.clear();

   // smartbody doctor
   visemeNameMap[ "EE" ]  = 5;
   visemeNameMap[ "Er" ]  = 6;
   visemeNameMap[ "Ih" ]  = 7;
   visemeNameMap[ "Ao" ]  = 8;
   visemeNameMap[ "oh" ]  = 9;
   visemeNameMap[ "OO" ]  = 10;
   visemeNameMap[ "Z" ]   = 11;
   visemeNameMap[ "j" ]   = 12;
   visemeNameMap[ "f" ]   = 13;
   visemeNameMap[ "Th" ]  = 14;
   visemeNameMap[ "D" ]   = 15;
   visemeNameMap[ "BMP" ] = 16;
   visemeNameMap[ "NG" ]  = 17;
   visemeNameMap[ "R" ]   = 18;
   visemeNameMap[ "KG" ]  = 19;

   visemeNameMap[ "brow_rt_up" ] = 20;
   visemeNameMap[ "brow_lf_up" ] = 21;
   visemeNameMap[ "blink_rt" ]   = 22;
   //visemeNameMap[ "blink_rt" ]   = 23;
   visemeNameMap[ "blink_lf" ]   = 24;
   //visemeNameMap[ "blink_lf" ]   = 25;

   visemeNameMap[ "angry" ]     = 26;
   visemeNameMap[ "surprised" ] = 27;
   visemeNameMap[ "thinking" ]  = 28;

   visemeNameMap[ "blink" ] = 29;
   //visemeNameMap[ "blink" ] = 30;
   //visemeNameMap[ "blink" ] = 31;
   //visemeNameMap[ "blink" ] = 32;

   visemeNameMap[ "unit4_inner_brow_lowerer" ] = 33;
   visemeNameMap[ "unit1_inner_brow_raiser" ]  = 34;
   visemeNameMap[ "unit2_outer_brow_raiser" ]  = 35;
   visemeNameMap[ "unit5_upper_lid_raiser" ]   = 36;
   visemeNameMap[ "unit1_plus_unit4" ]         = 37;
   visemeNameMap[ "unit1_plus_unit2" ]         = 38;
   visemeNameMap[ "unit1_unit2_unit4" ]        = 39;
   visemeNameMap[ "unit6_eye_squint" ]         = 40;

   visemeNameMap[ "unit12_smile_mouth" ]      = 41;
   visemeNameMap[ "unit25_lip_parser" ]       = 42;
   visemeNameMap[ "unit26_jaw_drop" ]         = 43;
   visemeNameMap[ "unit27_jaw_stretch_open" ] = 44;
   visemeNameMap[ "unit20_mouth_stretch" ]    = 45;

   visemeNameMap[ "unit38_nostril_dilator" ]      = 46;
   visemeNameMap[ "unit7_lid_tightener" ]         = 47;
   visemeNameMap[ "unit9_nose_wrinkle" ]          = 48;
   visemeNameMap[ "unit10_upper_lip_raiser" ]     = 49;
   visemeNameMap[ "unit15_lip_corner_depressor" ] = 50;
   visemeNameMap[ "unit23_lip_tightener" ]        = 51;
   visemeNameMap[ "unit39_nostril_compressor" ]   = 52;
}



BoneBusClient::BoneBusClient()
{
   m_wsaStartupCalled = false;
   m_sockUDP = NULL;
   m_sockTCP = NULL;
}


BoneBusClient::~BoneBusClient()
{
   CloseConnection();
}


bool BoneBusClient::OpenConnection( const char * server )
{
   // TODO: cleanup udp if tcp error

   if ( strcmp( server, "" ) == 0 )
      return false;

   WSADATA wsaData;
   int err = WSAStartup( MAKEWORD(2,2), &wsaData );
   if ( err != 0 )
   {
      printf( "WSAStartup failed. Code: %d\n", err );
      return false;
   }

   m_wsaStartupCalled = true;

   m_sockUDP = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
   if ( m_sockUDP == INVALID_SOCKET )
   {
      printf( "Couldn't create socket.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      m_sockUDP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   // see if we're specifying a host by name or by number
   if ( isalpha( server[ 0 ] ) )
   {
      hostent * host = gethostbyname( server );
      if ( host == NULL )
      {
         printf( "gethostbyname() failed.\n" );
         int errnum = WSAGetLastError();
         printf( "socket error: %d\n", errnum );
         closesocket( m_sockUDP );
         m_sockUDP = NULL;
         WSACleanup();
         m_wsaStartupCalled = false;
         return false;
      }

      m_toAddrUDP.sin_family = AF_INET;
      m_toAddrUDP.sin_addr = *( (in_addr *)host->h_addr );
      m_toAddrUDP.sin_port = htons( NETWORK_PORT_UDP );
   }
   else
   {
      m_toAddrUDP.sin_family = AF_INET;
      m_toAddrUDP.sin_addr.s_addr = inet_addr( server );
      m_toAddrUDP.sin_port = htons( NETWORK_PORT_UDP );
   }


   m_sockTCP = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
   if ( m_sockTCP == INVALID_SOCKET )
   {
      printf( "Couldn't create socket2.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      m_sockTCP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   // see if we're specifying a host by name or by number
   if ( isalpha( server[ 0 ] ) )
   {
      hostent * host = gethostbyname( server );
      if ( host == NULL )
      {
         printf( "gethostbyname() failed.\n" );
         int errnum = WSAGetLastError();
         printf( "socket error: %d\n", errnum );
         closesocket( m_sockTCP );
         m_sockTCP = NULL;
         WSACleanup();
         m_wsaStartupCalled = false;
         return false;
      }

      m_toAddrTCP.sin_family = AF_INET;
      m_toAddrTCP.sin_addr = *( (in_addr *)host->h_addr );
      m_toAddrTCP.sin_port = htons( NETWORK_PORT_TCP );
   }
   else
   {
      m_toAddrTCP.sin_family = AF_INET;
      m_toAddrTCP.sin_addr.s_addr = inet_addr( server );
      m_toAddrTCP.sin_port = htons( NETWORK_PORT_TCP );
   }


   {
      int ret;
      ret = connect( m_sockTCP, (SOCKADDR*)&m_toAddrTCP, sizeof( m_toAddrTCP ) 
);
      if ( ret < 0 )
      {
         printf( "connect() failed.\n" );
         int errnum = WSAGetLastError();
         printf( "socket error: %d\n", errnum );
         closesocket( m_sockTCP );
         m_sockTCP = NULL;
         WSACleanup();
         m_wsaStartupCalled = false;
         return false;
      }
   }

   return true;
}


bool BoneBusClient::CloseConnection()
{
   if ( m_sockUDP )
   {
      closesocket( m_sockUDP );
      m_sockUDP = NULL;
   }

   if ( m_sockTCP )
   {
      closesocket( m_sockTCP );
      m_sockTCP = NULL;
   }


   if ( m_wsaStartupCalled )
   {
      WSACleanup();
      m_wsaStartupCalled = false;
   }

   return true;
}


bool BoneBusClient::Update()
{
   return true;
}


BoneBusCharacter * BoneBusClient::CreateCharacter( const char * charName, const 
char * objectClass, const bool useFaceBones )
{
   if ( !IsOpen() )
   {
      return NULL;
   }

   // TODO:  This creates a unique_id based on the size of the list
   //        This will fail if we operate multiple Smartbody processes at the 
same time
   //        We'll get the same ID.  Need to come up with an algorithm that 
will handle this.

   if ( m_characterNameMap.find( charName ) == m_characterNameMap.end() )
   {
      m_characterNameMap[ charName ] = (int)m_characterNameMap.size() + 1;
   }

   BoneBusCharacter * character = new BoneBusCharacter( useFaceBones, 
m_sockUDP, m_toAddrUDP, m_sockTCP );

   character->m_name   = charName;
   character->m_charId = m_characterNameMap[ charName ];

   //NetworkMapBoneNames( character->m_boneNameMap, useFaceBones );
   //
   //if ( !useFaceBones )
   //   NetworkMapVisemeNames( character->m_visemeNameMap );

   character->m_bulkBoneRotations.packetId = 0x10;
   character->m_bulkBoneRotations.charId   = character->m_charId;
   character->m_bulkBoneRotations.numBoneRotations = 0;
   character->m_bulkBoneRotations.numBonePositions_unused = 0;
   memset( character->m_bulkBoneRotations.bones, 0, 
sizeof(character->m_bulkBoneRotations.bones) );

   character->m_bulkBonePositions.packetId = 0x11;
   character->m_bulkBonePositions.charId   = character->m_charId;
   character->m_bulkBonePositions.numBonePositions = 0;
   memset( character->m_bulkBonePositions.bones, 0, 
sizeof(character->m_bulkBonePositions.bones) );

   character->m_cachePosX = 0;
   character->m_cachePosY = 0;
   character->m_cachePosZ = 0;
   character->m_cachePosHits = 0;
   character->m_cacheQuatW = 1;
   character->m_cacheQuatX = 0;
   character->m_cacheQuatY = 0;
   character->m_cacheQuatZ = 0;
   character->m_cacheQuatHits = 0;


   if ( m_sockTCP != NULL )
   {
      printf( "Calling 'CreateActor %d %s %s %d'\n", character->m_charId, 
objectClass, charName, 1 );

      char b[ 512 ];
      int  blen;
      sprintf( b, "CreateActor|%d|%s|%s|%d;", character->m_charId, objectClass, 
charName, 1 );
      blen = (int)strlen( b );

      int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
      if ( bytesSent < 0 )
      {
         int errnum = WSAGetLastError();
         printf( "socket error: %d\n", errnum );
         //fprintf( fp, "socket error: %d\n", errnum );
      }
      if ( bytesSent > 0 )
      {
         //printf( "send: %ld\n", bytesSent );
         //fprintf( fp, "send: %ld\n", bytesSent );
      }
   }


   m_characterDataMap[ character->m_charId ] = character;

   return character;
}


bool BoneBusClient::DeleteCharacter( BoneBusCharacter * character )
{
   if ( IsOpen() )
   {
      printf( "Calling 'DeleteActor %d'\n", character->m_charId );

      char b[ 512 ];
      int  blen;
      sprintf( b, "DeleteActor|%d;", character->m_charId );
      blen = (int)strlen( b );

      int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
      if ( bytesSent < 0 )
      {
         int errnum = WSAGetLastError();
         printf( "socket error: %d\n", errnum );
         //fprintf( fp, "socket error: %d\n", errnum );
      }
      if ( bytesSent > 0 )
      {
         //printf( "send: %ld\n", bytesSent );
         //fprintf( fp, "send: %ld\n", bytesSent );
      }
   }


   m_characterDataMap.erase( character->m_charId );
   m_characterNameMap.erase( character->m_name );

   delete character;
   character = NULL;

   return true;
}


BoneBusCharacter * BoneBusClient::FindCharacter( const int charID )
{
   return m_characterDataMap[ charID ];
}


BoneBusCharacter * BoneBusClient::FindCharacterByName( const char * name )
{
   CharacterDataMap::const_iterator it;
   for ( it = m_characterDataMap.begin(); it != m_characterDataMap.end(); it++ )
   {
      if ( (*it).second->m_name == (string)name )
      {
         return (*it).second;
      }
   }

   return NULL;
}


void BoneBusClient::SetCameraPosition( const float x, const float y, const 
float z )
{
   if ( !IsOpen() )
   {
      return;
   }

   char b[ 512 ];
   int  blen;
   sprintf( b, "SetActorPos|%d|%f|%f|%f;", -1, x, y, z );
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusClient::SetCameraRotation( const float w, const float x, const 
float y, const float z )
{
   if ( !IsOpen() )
   {
      return;
   }

   char b[ 512 ];
   int  blen;
   sprintf( b, "SetActorRot|%d|%f|%f|%f|%f;", -1, w, x, y, z );
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusClient::ExecScript( const char * command )
{
   if ( !IsOpen() )
   {
      return;
   }

   ExecScriptData data;
   data.packetID = 0x04;
   strcpy( data.command, command );  // watch buffer length!

   int bytesSent;
   bytesSent = sendto( m_sockUDP, (const char *)&data, sizeof( data ), 0, 
(SOCKADDR*)&m_toAddrUDP, sizeof( m_toAddrUDP ) );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusClient::SendPlaySound( const char * sound_file )
{
   if ( !IsOpen() )
   {
      return;
   }

   char b[512];
   int  blen;

   //printf( "Calling 'PlaySoundDynamic %s'\n", filename );

   sprintf( b, "PlaySoundDynamic|%s;", sound_file);
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}


void BoneBusClient::SendStopSound( const char * sound_file )
{
   if ( !IsOpen() )
   {
      return;
   }

   char b[512];
   int  blen;

   //printf( "Calling 'StopSoundDynamic %s'\n", filename );

   sprintf( b, "StopSoundDynamic|%s;", sound_file);
   blen = (int)strlen( b );

   int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
   if (bytesSent < 0)
   {
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      //fprintf( fp, "socket error: %d\n", errnum );
   }
   if (bytesSent > 0)
   {
      //printf( "send: %ld\n", bytesSent );
      //fprintf( fp, "send: %ld\n", bytesSent );
   }
}



BoneBusServer::BoneBusServer()
{
   m_sockUDP = NULL;
   m_sockTCP = NULL;
   m_wsaStartupCalled = false;
   m_onClientConnectFunc = NULL;
   m_onClientConnectUserData = NULL;
   m_onClientDisconnectFunc = NULL;
   m_onClientDisconnectUserData = NULL;
   m_onCreateCharacterFunc = NULL;
   m_onCreateCharacterUserData = NULL;
   m_onDeleteCharacterFunc = NULL;
   m_onDeleteCharacterUserData = NULL;
   m_onSetCharacterPositionFunc = NULL;
   m_onSetCharacterPositionUserData = NULL;
   m_onSetCharacterRotationFunc = NULL;
   m_onSetCharacterRotationUserData = NULL;
   m_onBoneRotationsFunc = NULL;
   m_onBoneRotationsUserData = NULL;
   m_onBonePositionsFunc = NULL;
   m_onBonePositionsUserData = NULL;
}


BoneBusServer::~BoneBusServer()
{
   CloseConnection();
}


bool BoneBusServer::OpenConnection()
{
   // TODO: cleanup udp if tcp error

   WSADATA wsaData;
   int err = WSAStartup( MAKEWORD(2,2), &wsaData );
   if ( err != 0 )
   {
      printf( "WSAStartup failed. Code: %d\n", err );
      return false;
   }

   m_wsaStartupCalled = true;


   m_sockUDP = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
   if ( m_sockUDP == INVALID_SOCKET )
   {
      printf( "Couldn't create socket.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      m_sockUDP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   // Bind
   m_addrUDP.sin_addr.s_addr = INADDR_ANY; 
   m_addrUDP.sin_family = AF_INET; 
   m_addrUDP.sin_port = htons( NETWORK_PORT_UDP ); 
   memset( m_addrUDP.sin_zero, 0, sizeof( m_addrUDP.sin_zero ) ); 

   if ( bind( m_sockUDP, (const sockaddr *)&m_addrUDP, sizeof( m_addrUDP ) ) == 
SOCKET_ERROR )
   {
      printf( "bind() failed.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      closesocket( m_sockUDP );
      m_sockUDP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   u_long nonBlocking = 1;
   ioctlsocket( m_sockUDP, FIONBIO, &nonBlocking );



   m_sockTCP = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
   if ( m_sockTCP == INVALID_SOCKET )
   {
      printf( "Couldn't create socket tcp.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      m_sockTCP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   int reuseAddr = 1;
   setsockopt( m_sockTCP, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseAddr, sizeof( 
int ) );


   m_addrTCP.sin_family      = AF_INET;
   m_addrTCP.sin_addr.s_addr = INADDR_ANY;
   m_addrTCP.sin_port        = htons( NETWORK_PORT_TCP );
   memset( m_addrTCP.sin_zero, 0, sizeof( m_addrTCP.sin_zero ) ); 

   if ( bind( m_sockTCP, (sockaddr *)&m_addrTCP, sizeof( m_addrTCP ) ) == 
SOCKET_ERROR )
   {
      printf( "bind() failed.\n" );
      int errnum = WSAGetLastError();
      printf( "socket error: %d\n", errnum );
      closesocket( m_sockTCP );
      m_sockTCP = NULL;
      WSACleanup();
      m_wsaStartupCalled = false;
      return false;
   }


   {
   u_long nonBlocking = 1;
   ioctlsocket( m_sockTCP, FIONBIO, &nonBlocking );
   }


   listen( m_sockTCP, 10 );


   return true;
}


bool BoneBusServer::CloseConnection()
{
   if ( m_sockUDP )
   {
      closesocket( m_sockUDP );
      m_sockUDP = NULL;
   }

   if ( m_sockTCP )
   {
      closesocket( m_sockTCP );
      m_sockTCP = NULL;
   }


   if ( m_wsaStartupCalled )
   {
      WSACleanup();
      m_wsaStartupCalled = false;
   }

   return true;
}


bool BoneBusServer::Update()
{
   if ( !IsOpen() )
   {
      return false;
   }

   {
      fd_set readfds;
      FD_ZERO( &readfds );
      FD_SET( m_sockTCP, &readfds );
      timeval timeout = { 0, 0 };  // return immediately
      int error = select( 0, &readfds, 0, 0, &timeout );   // 1st parameter 
ignored by winsock
      if ( error == SOCKET_ERROR )
      {
         printf( "TCP - Error checking status\n" );
      }
      else if ( error != 0 )
      {
         int newSock;
         sockaddr_in newToAddr;

         int i = sizeof( sockaddr_in );
         newSock = (int)accept( m_sockTCP, (sockaddr *)&newToAddr, &i );

         u_long nonBlocking = 1;
         ioctlsocket( newSock, FIONBIO, &nonBlocking );

         m_sockConnectionsTCP.push_back( newSock );

         //printf( "New Connection!\n" );

         if ( m_onClientConnectFunc )
         {
            string clientIP = inet_ntoa( newToAddr.sin_addr );
            m_onClientConnectFunc( clientIP, m_onClientConnectUserData );
         }
      }
   }


   for ( int i = 0; i < (int)m_sockConnectionsTCP.size(); i++ )
   {
      int tcpDataPending;

      SOCKET s = m_sockConnectionsTCP[ i ];

      fd_set readfds;
      FD_ZERO( &readfds );
      FD_SET( s, &readfds );
      timeval timeout = { 0, 0 };  // return immediately
      int error = select( 0, &readfds, 0, 0, &timeout );   // 1st parameter 
ignored by winsock
      if ( error == SOCKET_ERROR )
      {
         //printf( "TCP - Error checking status\n" );
         tcpDataPending = 0;
      }
      else if ( error == 0 )
      {
         tcpDataPending = 0;
      }
      else
      {
         tcpDataPending = 1;
      }


      if ( tcpDataPending )
      {
         char str[ 1000 ];
         memset( str, 0, sizeof( char ) * 1000 );

         int bytesReceived = recv( (SOCKET)s, str, sizeof( str ) - 1, 0 );
         if ( bytesReceived > 0 )
         {
            str[ bytesReceived ] = 0;

            string recvStr = str;

            OutputDebugString( string( recvStr + "\n" ).c_str() );


            vector< string > tokens;
            Tokenize( recvStr, tokens, ";" );

            for ( int t = 0; t < (int)tokens.size(); t++ )
            {
               vector< string > msgTokens;
               Tokenize( tokens[ t ], msgTokens, "|" );

               if ( msgTokens.size() > 0 )
               {
                  if ( msgTokens[ 0 ] == "CreateActor" )
                  {
                     if ( msgTokens.size() > 4 )
                     {
                        string charIdStr = msgTokens[ 1 ];
                        int charId       = atoi( charIdStr.c_str() );
                        string uClass    = msgTokens[ 2 ];
                        string name      = msgTokens[ 3 ];
                        int skeletonType = atoi( msgTokens[ 4 ].c_str() );

                        if ( m_onCreateCharacterFunc )
                        {
                           m_onCreateCharacterFunc( charId, uClass, name, 
skeletonType, m_onClientConnectUserData );
                        }
                     }
                  }
                  else if ( msgTokens[ 0 ] == "DeleteActor" )
                  {
                     if ( msgTokens.size() > 1 )
                     {
                        string charIdStr = msgTokens[ 1 ];
                        int charId       = atoi( charIdStr.c_str() );

                        if ( m_onDeleteCharacterFunc )
                        {
                           m_onDeleteCharacterFunc( charId, 
m_onDeleteCharacterUserData );
                        }
                     }
                  }
                  else if ( msgTokens[ 0 ] == "SetActorPos" )
                  {
                     if ( msgTokens.size() > 4 )
                     {
                        string charIdStr = msgTokens[ 1 ];
                        int charId       = atoi( charIdStr.c_str() );
                        float x          = (float)atof( msgTokens[ 2 ].c_str() 
);
                        float y          = (float)atof( msgTokens[ 3 ].c_str() 
);
                        float z          = (float)atof( msgTokens[ 4 ].c_str() 
);

                        if ( m_onSetCharacterPositionFunc )
                        {
                           m_onSetCharacterPositionFunc( charId, x, y, z, 
m_onSetCharacterPositionUserData );
                        }
                     }
                  }
                  else if ( msgTokens[ 0 ] == "SetActorRot" )
                  {
                     if ( msgTokens.size() > 5 )
                     {
                        string charIdStr = msgTokens[ 1 ];
                        int charId       = atoi( charIdStr.c_str() );
                        float w          = (float)atof( msgTokens[ 2 ].c_str() 
);
                        float x          = (float)atof( msgTokens[ 3 ].c_str() 
);
                        float y          = (float)atof( msgTokens[ 4 ].c_str() 
);
                        float z          = (float)atof( msgTokens[ 5 ].c_str() 
);

                        if ( m_onSetCharacterRotationFunc )
                        {
                           m_onSetCharacterRotationFunc( charId, w, x, y, z, 
m_onSetCharacterRotationUserData );
                        }
                     }
                  }
                  else if ( msgTokens[ 0 ] == "SetActorViseme" )
                  {
                     if ( msgTokens.size() > 4 )
                     {
                        string charIdStr = msgTokens[ 1 ];
                        int charId       = atoi( charIdStr.c_str() );
                        string visemeStr = msgTokens[ 2 ];
                        int visemeId     = atoi( visemeStr.c_str() );
                        float weight     = (float)atof( msgTokens[ 3 ].c_str() 
);
                        float blendTime  = (float)atof( msgTokens[ 4 ].c_str() 
);

                        //if ( m_onSetCharacterVisemeFunc )
                        //{
                        //   m_onSetCharacterVisemeFunc( charId, visemeId, 
weight, blendTime, m_onSetCharacterVisemeUserData );
                        //}
                     }
                  }
               }
            }
         }
      }
   }


   int udpDataPending;

   fd_set readfds;
   FD_ZERO( &readfds );
   FD_SET( m_sockUDP, &readfds );
   timeval timeout = { 0, 0 };  // return immediately
   int error = select( 0, &readfds, 0, 0, &timeout );   // 1st parameter 
ignored by winsock
   if ( error == SOCKET_ERROR )
   {
      //printf( "TCP - Error checking status\n" );
      udpDataPending = 0;
   }
   else if ( error == 0 )
   {
      udpDataPending = 0;
   }
   else
   {
      udpDataPending = 1;
   }


   int dataReceived = 0;

   char buffer[ 2048 ] = {0};
   int bytesReceived = 1;

   while ( bytesReceived > 0 )
   {
      bytesReceived = 0;
      dataReceived = 0;

      if ( udpDataPending )
      {
         sockaddr_in fromAddr;
         int fromAddrSize = sizeof(sockaddr_in);
         //char buffer[ 2048 ];
         //memset( buffer, 0, 2048 );

         bytesReceived = recvfrom( m_sockUDP, buffer, 2047 * sizeof(char), 0, 
(sockaddr *)&fromAddr, &fromAddrSize );
         if ( bytesReceived < 0 )
         {
            //Warning( "Could not receive datagram\n" );
            dataReceived = 0;
         }
         else
         {
            dataReceived = 1;
         }
      }


      if ( dataReceived && ( bytesReceived > 3 ) )
      {
         int opcode = ((int *)buffer)[ 0 ];

         if ( opcode == 0x10 )
         {
            //printf( "BULK_BONE_DATA\n" );

            BulkBoneRotations * bulkBoneRotations;

            bulkBoneRotations = (BulkBoneRotations *)buffer;

            if ( m_onBoneRotationsFunc )
            {
               m_onBoneRotationsFunc( bulkBoneRotations, 
m_onBoneRotationsUserData );
            }
         }
         else if ( opcode == 0x11 )
         {
            //printf( "BULK_POSITION_DATA\n" );

            BulkBonePositions * bulkBonePositions;

            bulkBonePositions = (BulkBonePositions *)buffer;

            if ( m_onBonePositionsFunc )
            {
               m_onBonePositionsFunc( bulkBonePositions, 
m_onBonePositionsUserData );
            }
         }
      }
   }

   return true;
}


// taken from: 
http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
void BoneBusServer::Tokenize( const string & str, vector<string> & tokens, 
const string & delimiters )
{
   // Skip delimiters at beginning.
   string::size_type lastPos = str.find_first_not_of( delimiters, 0 );

   // Find first "non-delimiter".
   string::size_type pos = str.find_first_of( delimiters, lastPos );

   while ( string::npos != pos || string::npos != lastPos )
   {
      // Found a token, add it to the vector.
      tokens.push_back( str.substr( lastPos, pos - lastPos ) );

      // Skip delimiters.  Note the "not_of"
      lastPos = str.find_first_not_of( delimiters, pos );

      // Find next "non-delimiter"
      pos = str.find_first_of( delimiters, lastPos );
   }
}

// [BMLR] Get command from renderer and external programs
vector<string>* BoneBusClient::GetCommand()
{
        std::string result = "";
        if ( m_sockTCP != NULL )
        {
                fd_set SocketSet;
                FD_ZERO(&SocketSet);
                FD_SET(m_sockTCP, &SocketSet);
                TIMEVAL SelectTime = {0, 0};
                int error = select(m_sockTCP + 1, &SocketSet, 0, 0, 
&SelectTime);

                if (error > 0)
                {
                        char b[10000]; // Todo: use a while loop instead
                        int bytesRecv = recv(m_sockTCP, b, sizeof(b), 0);
                        if (bytesRecv > 0)
                        {
                                result.append(b);
                                result = result.substr(0, bytesRecv);
                        }
                }
        }
        if (result.length() > 0)
        {
                vector<string>* results = new vector<string>();
                BoneBusServer::Tokenize(result, *results, "\r\r\r"); // we use 
\r\r\r as a separator between commands :)
                return results;
        }
        return NULL;
}

// [BMLR] Send text to speak to the renderer
void BoneBusClient::SendSpeakText( const unsigned int msgNumber, const char * 
agent, const char * text )
{
        if ( !IsOpen() )
        {
                return;
        }

        char b[512];
        int  blen;

        sprintf( b, "SpeakText|%d|%s|%s;", msgNumber, agent, text);
        blen = (int)strlen( b );

        int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
        if (bytesSent < 0)
        {
                int errnum = WSAGetLastError();
                printf( "socket error: %d\n", errnum );
        }
}

// [BMLR] Sends create pawn requests to renderer
void BoneBusClient::SendCreatePawn(std::string name, double locx, double locy, 
double locz)
{
        if ( !IsOpen() )
        {
                return;
        }

        char b[1024];
        int  blen;

        sprintf( b, "CreatePawn|%s|%f|%f|%f;", name.c_str(), (float)locx, 
(float)locy, (float)locz);
        blen = (int)strlen( b );

        int bytesSent = send( m_sockTCP, (const char *)b, blen, 0 );
        if (bytesSent < 0)
        {
                int errnum = WSAGetLastError();
                printf( "socket error: %d\n", errnum );
        }
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Smartbody-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/smartbody-developer

Reply via email to