////////////////////////////////////////////////////////////////////////// // loadJsonFile BcBool CsPackageImporter::loadJsonFile( const BcChar* pFileName, Json::Value& Root ) { BcBool Success = BcFalse; BcFile File; if( File.open( pFileName ) ) { const BcU8* pData = File.readAllBytes(); Json::Reader Reader; if( Reader.parse( (const char*)pData, (const char*)pData + File.size(), Root ) ) { Success = BcTrue; } else { PSY_LOG( "Failed to parse Json:\n %s\n", Reader.getFormatedErrorMessages().c_str() ); BcAssertMsg( BcFalse, "Failed to parse \"%s\", see log for more details.", pFileName ); } BcMemFree( (void*)pData ); } else { BcAssertMsg( BcFalse, "Failed to load \"%s\"", pFileName ); } return Success; }
////////////////////////////////////////////////////////////////////////// // saveDependancy void CsCore::saveDependancies( const BcPath& FileName ) { BcPath DependanciesFileName( FileName ); // Append new extension. DependanciesFileName.append( ".dep" ); // Json::Value Object( Json::arrayValue ); if( DependancyMap_.find( *FileName ) != DependancyMap_.end() ) { CsDependancyList& DependancyList = DependancyMap_[ *FileName ]; for( CsDependancyListIterator It( DependancyList.begin() ); It != DependancyList.end(); ++It ) { Object.append( saveDependancy( (*It) ) ); } } // Output using styled writer. Json::StyledWriter Writer; std::string JsonOutput = Writer.write( Object ); BcFile OutFile; if( OutFile.open( (*DependanciesFileName).c_str(), bcFM_WRITE ) ) { OutFile.write( JsonOutput.c_str(), JsonOutput.size() ); OutFile.close(); } }
////////////////////////////////////////////////////////////////////////// // parseJsonFile BcBool CsCore::parseJsonFile( const BcChar* pFileName, Json::Value& Root ) { BcBool Success = BcFalse; BcFile File; if( File.open( pFileName ) ) { char* pData = new char[ File.size() ]; File.read( pData, File.size() ); Json::Reader Reader; if( Reader.parse( pData, pData + File.size(), Root ) ) { Success = BcTrue; // Add file for monitoring. FsCore::pImpl()->addFileMonitor( pFileName ); } else { BcPrintf( "CsCore: Failed to parse Json:\n %s\n", Reader.getFormatedErrorMessages().c_str() ); } delete [] pData; } return Success; }
////////////////////////////////////////////////////////////////////////// // Gets a plain text file std::string DsTemplate::loadTemplateFile( std::string filename ) { BcFile file; std::string f = filename; file.open( f.c_str() ); // PSY_LOG("Loading file: %s (size: %d)\n", filename.c_str(), file.size()); if ( !file.isOpen() ) return ""; char* data = new char[file.size() + 1]; BcMemZero(data, file.size() + 1); file.read(data, file.size()); std::string output = data; delete data; return output; }
////////////////////////////////////////////////////////////////////////// // loadDependancies void CsCore::loadDependancies( const BcPath& FileName ) { BcPath DependanciesFileName( FileName ); // Append new extension. DependanciesFileName.append( ".dep" ); // Overwrite old dependancy list. DependancyMap_[ *FileName ] = CsDependancyList(); // Open dependancy file. BcFile OutFile; if( OutFile.open( (*DependanciesFileName).c_str(), bcFM_READ ) ) { BcU32 BufferSize = OutFile.size() + 1; BcChar* pJsonData = new BcChar[ BufferSize ]; BcMemZero( pJsonData, BufferSize ); OutFile.read( pJsonData, OutFile.size() ); Json::Value Root; Json::Reader JsonReader; if( JsonReader.parse( pJsonData, pJsonData + OutFile.size(), Root ) ) { // Create a new dependancy list. CsDependancyList DependancyList; // Iterate over all dependancies for file and parse. for( Json::Value::iterator It( Root.begin() ); It != Root.end(); ++It ) { const Json::Value& Value = (*It); CsDependancy Dependancy = loadDependancy( Value ); DependancyList.push_back( Dependancy ); } // Assign. DependancyMap_[ *FileName ] = DependancyList; } OutFile.close(); } }
////////////////////////////////////////////////////////////////////////// // load MdlAnim* MD5AnimLoader::load( const BcChar* FileName, const BcChar* NodeName ) { BcFile File; BcBool Ret; ParseMode_ = PM_MAIN; BcU32 iJoint = 0; BcU32 iBound = 0; BcU32 iFrame = 0; BcU32 iAnimComp = 0; File.open( FileName ); BcChar Buffer[1024]; BcChar Command[1024]; BcChar* pBuffer; // Begin the parsage. while( !File.eof() ) { // Parse a line without the spaces at the start or tabs. { pBuffer = &Buffer[0]; BcChar TheChar = 0; BcBool bAtSentence = BcFalse; while( TheChar != 10 && !File.eof() ) { File.read( &TheChar, 1 ); if ( TheChar != '\t' ) { bAtSentence = BcTrue; } if ( TheChar != 10 && TheChar != 13 && bAtSentence ) { *pBuffer = TheChar; ++pBuffer; Ret = ( pBuffer < ( Buffer + 1024 ) ); BcAssert( Ret ); if( !Ret ) { return NULL; } } } // Terminate it. *pBuffer = 0; ++pBuffer; } sscanf( Buffer, "%s", Command ); if ( BcStrLength( Buffer ) == 0 ) { Command[ 0 ] = 0; } switch( ParseMode_ ) { case PM_MAIN: { if( BcStrCompare( "numJoints", Command ) ) { sscanf( Buffer, "numJoints %u", &nJoints_ ); pJoints_ = new MD5_Joint[ nJoints_ ]; for( BcU32 i = 0; i < nFrames_; ++i ) { pFrames_[ i ].nKeys_ = nJoints_; pFrames_[ i ].pKeys_ = new MD5_Joint[ nJoints_ ]; } } else if( BcStrCompare( "numFrames", Command ) ) { sscanf( Buffer, "numFrames %u", &nFrames_ ); nBounds_ = nFrames_; pFrames_ = new MD5_Frame[ nFrames_ ]; pBounds_ = new MD5_Bound[ nBounds_ ]; } else if( BcStrCompare( "frameRate", Command ) ) { sscanf( Buffer, "frameRate %f", &FrameRate_ ); } else if( BcStrCompare( "numAnimatedComponents", Command ) ) { sscanf( Buffer, "numAnimatedComponents %u", &nAnimComponents_ ); pAnimComponents_ = new BcF32[ nAnimComponents_ ]; } else if( BcStrCompare( "hierarchy", Command ) ) { ParseMode_ = PM_HIERARCHY; iJoint = 0; } else if( BcStrCompare( "bounds", Command ) ) { ParseMode_ = PM_BOUNDS; iBound = 0; } else if( BcStrCompare( "baseframe", Command ) ) { ParseMode_ = PM_BASEFRAME; iJoint = 0; } else if ( BcStrCompare( "frame", Command ) ) { ParseMode_ = PM_FRAME; iJoint = 0; iAnimComp = 0; } } break; case PM_HIERARCHY: { if( BcStrCompare( "}", Command ) ) { ParseMode_ = PM_MAIN; } else { BcAssert( iJoint < nJoints_ ); sscanf( Buffer, "%s %u %u %u", &pJoints_[ iJoint ].Name_[0], &pJoints_[ iJoint ].ParentID_, &pJoints_[ iJoint ].AnimMask_, &pJoints_[ iJoint ].AnimOffset_ ); ++iJoint; } } break; case PM_BOUNDS: { if( BcStrCompare( "}", Command ) ) { ParseMode_ = PM_MAIN; } else { BcAssert( iBound < nBounds_ ); sscanf( Buffer, "( %f %f %f ) ( %f %f %f )", &pBounds_[ iBound ].MinX_, &pBounds_[ iBound ].MinY_, &pBounds_[ iBound ].MinZ_, &pBounds_[ iBound ].MaxX_, &pBounds_[ iBound ].MaxY_, &pBounds_[ iBound ].MaxZ_ ); iBound++; } } break; case PM_BASEFRAME: { if( BcStrCompare( "}", Command ) ) { ParseMode_ = PM_MAIN; } else { BcAssert( iJoint < nJoints_ ); sscanf( Buffer, "( %f %f %f ) ( %f %f %f )", &pJoints_[ iJoint ].TX_, &pJoints_[ iJoint ].TY_, &pJoints_[ iJoint ].TZ_, &pJoints_[ iJoint ].QX_, &pJoints_[ iJoint ].QY_, &pJoints_[ iJoint ].QZ_ ); iJoint++; } } break; case PM_FRAME: { if( BcStrCompare( "}", Command ) ) { // Setup all joints. BcAssert( iFrame < nFrames_ ); MD5_Frame* pFrame = &pFrames_[ iFrame++ ]; for( BcU32 i = 0; i < nJoints_; ++i ) { // Copy from base. pFrame->pKeys_[ i ] = pJoints_[ i ]; // Parse from anim data. BcF32* pData = &pAnimComponents_[ pFrame->pKeys_[ i ].AnimOffset_ ]; BcU32 iVal = 0; BcU32 AnimMask = pFrame->pKeys_[ i ].AnimMask_; if( AnimMask & 1 ) { pFrame->pKeys_[ i ].TX_ = pData[ iVal++ ]; } if( AnimMask & 2 ) { pFrame->pKeys_[ i ].TY_ = pData[ iVal++ ]; } if( AnimMask & 4 ) { pFrame->pKeys_[ i ].TZ_ = pData[ iVal++ ]; } if( AnimMask & 8 ) { pFrame->pKeys_[ i ].QX_ = pData[ iVal++ ]; } if( AnimMask & 16 ) { pFrame->pKeys_[ i ].QY_ = pData[ iVal++ ]; } if( AnimMask & 32 ) { pFrame->pKeys_[ i ].QZ_ = pData[ iVal++ ]; } } ParseMode_ = PM_MAIN; } else { BcF32 Data[]= { 1e6f, 1e6f, 1e6f, 1e6f, 1e6f, 1e6f, }; // NOTE: This may not actually work.. sscanf( Buffer, "%f %f %f %f %f %f", &Data[0], &Data[1], &Data[2], &Data[3], &Data[4], &Data[5] ); // Parse into array. for( BcU32 i = 0; i < 6; ++i ) { if( Data[i] < 1e6f ) { BcAssert( iAnimComp < nAnimComponents_ ); pAnimComponents_[ iAnimComp ] = Data[i]; iAnimComp++; } else { break; } } } } break; } } // Create animation. MdlAnim* pAnimation = new MdlAnim(); // Build up all nodes. for( BcU32 i = 0; i < nJoints_; ++i ) { MdlAnimNode Node; BcStrCopy( Node.Name_, pJoints_[ i ].Name_ ); if( pJoints_[ i ].ParentID_ != -1 ) { BcStrCopy( Node.Parent_, pJoints_[ pJoints_[ i ].ParentID_ ].Name_ ); } else { Node.Parent_[ 0 ] = '\0'; } for( BcU32 j = 0; j < nFrames_; ++j ) { MD5_Joint* pJoint = &pFrames_[ j ].pKeys_[ i ]; MdlAnimKey Key; Key.R_.set( pJoint->QX_, pJoint->QY_, pJoint->QZ_, 0.0f ); Key.S_.set( 1.0f, 1.0f, 1.0f ); Key.T_.set( pJoint->TX_, pJoint->TY_, pJoint->TZ_ ); Key.R_.calcFromXYZ(); Node.KeyList_.push_back( Key ); } pAnimation->addNode( Node ); } // Cleanup nJoints_ = 0; delete [] pJoints_; pJoints_ = NULL; nBounds_ = 0; delete [] pBounds_; pBounds_ = NULL; nAnimComponents_ = 0; delete [] pAnimComponents_; pAnimComponents_ = NULL; for( BcU32 i = 0; i < nFrames_; ++i ) { delete [] pFrames_[ i ].pKeys_; } nFrames_ = 0; delete [] pFrames_; pFrames_ = NULL; // /* BcMat4d RootTransform; RootTransform.identity(); pRootNode->makeRelativeTransform( RootTransform ); */ return pAnimation;//pRootNode; }
//////////////////////////////////////////////////////////////////////////////// // update eSysStateReturn GaMatchmakingState::main() { BcScopedLock< BcMutex > Lock( Lock_ ); BcReal Delta = SysKernel::pImpl()->getFrameTime(); switch( HandshakeState_ ) { case HSS_STUN: { // Only do once. if( MappedHandshakeAddr_ == 0 ) { if( doSTUN() ) { SysID_ = static_cast< BcU32 >( BcHash( (BcU8*)&MappedHandshakeAddr_, sizeof( MappedHandshakeAddr_ ) ) ); // Hash the mapped address to we don't broadcast it. if( MappedHandshakeAddr_ != 0 ) { HandshakeState_ = HSS_IDLE; } } else { HandshakeState_ = HSS_STUN; } } else { HandshakeState_ = HSS_IDLE; } } break; case HSS_IDLE: { ConnectTimer_ -= Delta; if( ConnectTimer_ < 0.0f ) { if( pSession_ == NULL ) { pSession_ = irc_create_session( &Callbacks_ ); } if( pSession_ != NULL && !irc_is_connected( pSession_ ) ) { irc_set_ctx( pSession_, this ); std::string Channel = "#testchannel"; BcFile File; if( File.open( "config.json" ) ) { char* pData = new char[ File.size() ]; File.read( pData, File.size() ); Json::Reader Reader; Json::Value Root; if( Reader.parse( pData, pData + File.size(), Root ) ) { Channel = Root["channel"].asCString(); } delete [] pData; } BcSPrintf( ScreenName_, "%s_%x", "PSY", BcRandom::Global.rand() ); BcSPrintf( Channel_, Channel.c_str() ); // Connect to the server. int RetVal = irc_connect( pSession_, "www.neilo.gd", 8000, NULL, ScreenName_, ScreenName_, ScreenName_ ); if( RetVal == 0 ) { // Start the thread to tick the client. BcThread::start( "EvtBridgeIRC" ); ClientID_ = BcErrorCode; RemoteHandshakeAddr_ = 0; RemoteHandshakePort_ = 0; //LocalHandshakeAddr_ = 0; //LocalHandshakePort_ = 0; //MappedHandshakeAddr_ = 0; //MappedHandshakePort_ = 0; HandshakeState_ = HSS_WAIT_INVITE; } else { BcThread::join(); irc_destroy_session( pSession_ ); pSession_ = NULL; } } } } break; case HSS_WAIT_INVITE: { InviteTimer_ -= Delta; if( InviteTimer_ < 0.0f ) { InviteTimer_ = BcAbs( BcRandom::Global.randReal() ) * 5.0f + 5.0f; // Send play with me message to channel. BcChar PlayBuffer[256]; BcSPrintf( PlayBuffer, "REQ:%u", SysID_ ); irc_cmd_msg( pSession_, Channel_, PlayBuffer ); } } break; case HSS_WAIT_ADDR: { HandshakeTimer_ -= Delta; if( HandshakeTimer_ < 0.0f ) { HandshakeState_ = HSS_WAIT_INVITE; } } break; case HSS_COMPLETE: { BcPrintf("GaMatchmakingState: Complete! ClientID of ours is %u\n", ClientID_); return sysSR_FINISHED; } break; } if( HandshakeState_ != HSS_STUN ) { if( HandshakeState_ != HSS_IDLE && ( pSession_ == NULL || !irc_is_connected( pSession_ ) ) ) { BcSleep( 0.1f ); BcThread::join(); BcSleep( 0.1f ); if( pSession_ != NULL ) { irc_destroy_session( pSession_ ); pSession_ = NULL; } HandshakeState_ = HSS_IDLE; ConnectTimer_ = 10.0f; } } return sysSR_CONTINUE; }
////////////////////////////////////////////////////////////////////////// // load MdlNode* MD5MeshLoader::load( const BcChar* FileName, const BcChar* NodeName ) { BcFile File; BcBool Ret; ParseMode_ = PM_MAIN; BcU32 iJoint = 0; BcU32 iMesh = 0; BcU32 iVert = 0; BcU32 iInd = 0; BcU32 iWeight = 0; if( File.open( FileName ) == BcFalse ) { return NULL; } BcChar Buffer[1024]; BcChar Command[1024]; BcChar* pBuffer; // Begin the parsage. while( !File.eof() ) { // Parse a line without the spaces at the start or tabs. { pBuffer = &Buffer[0]; BcChar TheChar = 0; BcBool bAtSentence = BcFalse; while( TheChar != 10 && !File.eof() ) { File.read( &TheChar, 1 ); if ( TheChar != '\t' ) { bAtSentence = BcTrue; } if ( TheChar != 10 && TheChar != 13 && bAtSentence ) { *pBuffer = TheChar; ++pBuffer; Ret = ( pBuffer < ( Buffer + 1024 ) ); BcAssert( Ret ); if( !Ret ) { return NULL; } } } // Terminate it. *pBuffer = 0; ++pBuffer; } sscanf( Buffer, "%s", Command ); if ( BcStrLength( Buffer ) == 0 ) { Command[ 0 ] = 0; } switch( ParseMode_ ) { case PM_MAIN: { if( BcStrCompare( "numJoints", Command ) ) { sscanf( Buffer, "numJoints %u", &nJoints_ ); pJoints_ = new MD5_Joint[ nJoints_ ]; } else if( BcStrCompare( "numMeshes", Command ) ) { sscanf( Buffer, "numMeshes %u", &nMeshes_ ); pMeshes_ = new MD5_Mesh[ nMeshes_ ]; } else if( BcStrCompare( "joints", Command ) ) { ParseMode_ = PM_JOINTS; } else if( BcStrCompare( "mesh", Command ) ) { ParseMode_ = PM_MESH; iVert = 0; iInd = 0; iWeight = 0; } } break; case PM_JOINTS: { if( BcStrCompare( "}", Command ) ) { ParseMode_ = PM_MAIN; } else { // Parse a joint off. BcAssert( iJoint < nJoints_ ); MD5_Joint* pJoint = &pJoints_[ iJoint ]; sscanf( Buffer, "%s %i ( %f %f %f ) ( %f %f %f )", pJoint->Name_, &pJoint->ParentID_, &pJoint->TX_, &pJoint->TY_, &pJoint->TZ_, &pJoint->QX_, &pJoint->QY_, &pJoint->QZ_ ); ++iJoint; } } break; case PM_MESH: { if( BcStrCompare( "}", Command ) ) { ++iMesh; ParseMode_ = PM_MAIN; } else { BcAssert( iMesh < nMeshes_ ); MD5_Mesh* pMesh = &pMeshes_[ iMesh ]; if ( BcStrCompare( "shader", Command ) ) { sscanf( Buffer, "shader \"%s", pMesh->Shader_ ); BcU32 i = BcStrLength( pMesh->Shader_ ) - 1; pMesh->Shader_[ i ] = '\0'; } else if ( BcStrCompare( "numverts", Command ) ) { sscanf( Buffer, "numverts %u", &pMesh->nVerts_ ); pMesh->pVerts_ = new MD5_Vert[ pMesh->nVerts_ ]; } else if ( BcStrCompare( "vert", Command ) ) { // Parse a vert off BcAssert( iVert < pMesh->nVerts_ ); MD5_Vert* pVert = &pMesh->pVerts_[ iVert ]; sscanf( Buffer, "vert %i ( %f %f ) %i %i", &pVert->Index_, &pVert->U_, &pVert->V_, &pVert->WeightIndex_, &pVert->nWeights_ ); ++iVert; } else if ( BcStrCompare( "numtris", Command ) ) { sscanf( Buffer, "numtris %u", &pMesh->nIndices_ ); pMesh->nIndices_ *= 3; pMesh->pIndices_ = new BcU32[ pMesh->nIndices_ ]; } else if ( BcStrCompare( "tri", Command ) ) { // Parse a vert off BcAssert( iInd < pMesh->nIndices_ ); BcU32 Index; BcU32* pIndex = &pMesh->pIndices_[ iInd ]; sscanf( Buffer, "tri %i %i %i %i", &Index, &pIndex[0], &pIndex[1], &pIndex[2] ); iInd += 3; } else if ( BcStrCompare( "numweights", Command ) ) { sscanf( Buffer, "numweights %u", &pMesh->nWeights_ ); pMesh->pWeights_ = new MD5_Weight[ pMesh->nWeights_ ]; } else if ( BcStrCompare( "weight", Command ) ) { // Parse a vert off BcAssert( iWeight < pMesh->nWeights_ ); MD5_Weight* pWeight = &pMesh->pWeights_[ iWeight ]; sscanf( Buffer, "weight %i %i %f ( %f %f %f )", &pWeight->Index_, &pWeight->JointID_, &pWeight->Weight_, &pWeight->X_, &pWeight->Y_, &pWeight->Z_ ); ++iWeight; } } } break; } } // Now that we are loaded we can build the node graph. MdlNode* pRootNode = new MdlNode(); pRootNode->name( NodeName ); for( BcU32 i = 0; i < nMeshes_; ++i ) { buildBindPose( pRootNode, i ); } // Parent joints up. //if( nJoints_ > 1 ) { for( BcU32 i = 0; i < nJoints_; ++i ) { MD5_Joint* pJoint = &pJoints_[ i ]; MdlNode* pNode = new MdlNode(); pNode->name( pJoint->Name_ ); pNode->type( eNT_JOINT ); // Build the transform and inverse bind pose. BcQuat JointRot( pJoint->QX_, pJoint->QY_, pJoint->QZ_, 0.0f ); JointRot.calcFromXYZ(); BcMat4d JointRotation; BcMat4d JointTranslate; BcMat4d JointTransform; BcMat4d InverseBindpose; JointRot.asMatrix4d( JointRotation ); JointTranslate.identity(); JointTranslate.row3( BcVec4d( pJoint->TX_, pJoint->TY_, pJoint->TZ_, 1.0f ) ); JointTransform = JointRotation * JointTranslate; InverseBindpose = JointTransform; InverseBindpose.inverse(); pNode->absoluteTransform( JointTransform ); pNode->inverseBindpose( InverseBindpose ); if( pJoint->ParentID_ != BcErrorCode ) { pRootNode->parentNode( pNode, pJoints_[ pJoint->ParentID_ ].Name_ ); } else { // Parent to root. pRootNode->parentNode( pNode, pRootNode->name() ); } } } // Cleanup nJoints_ = 0; delete [] pJoints_; pJoints_ = NULL; for( BcU32 i = 0; i < nMeshes_; ++i ) { delete [] pMeshes_[ i ].pIndices_; delete [] pMeshes_[ i ].pVerts_; delete [] pMeshes_[ i ].pWeights_; } nMeshes_ = 0; delete [] pMeshes_; pMeshes_ = NULL; // BcMat4d RootTransform; RootTransform.identity(); pRootNode->makeRelativeTransform( RootTransform ); return pRootNode; }