////////////////////////////////////////////////////////////////////////// // initialise //virtual void ScnParticleSystemComponent::initialise( const Json::Value& Object ) { Super::initialise( Object ); // Grab number of particles. NoofParticles_ = Object["noofparticles"].asUInt(); ScnMaterialRef Material = getPackage()->getPackageCrossRef( Object["material"].asUInt() ); if( !CsCore::pImpl()->createResource( BcName::INVALID, getPackage(), MaterialComponent_, Material, scnSPF_PARTICLE_3D ) ) { BcAssertMsg( BcFalse, "Material invalid blah." ); } IsLocalSpace_ = Object["localspace"].asBool(); // Cache texture bounds. ScnTextureRef Texture = Material->getTexture( "aDiffuseTex" ); for( BcU32 Idx = 0; Idx < Texture->noofRects(); ++Idx ) { ScnRect Rect = Texture->getRect( Idx ); UVBounds_.push_back( MaVec4d( Rect.X_, Rect.Y_, Rect.X_ + Rect.W_, Rect.Y_ + Rect.H_ ) ); } WorldTransformParam_ = MaterialComponent_->findParameter( "uWorldTransform" ); BcMemZero( &VertexBuffers_, sizeof( VertexBuffers_ ) ); pParticleBuffer_ = NULL; CurrentVertexBuffer_ = 0; PotentialFreeParticle_ = 0; }
////////////////////////////////////////////////////////////////////////// // Ctor CsFileReaderRPC::CsFileReaderRPC( const std::string& Name ): CsFile( Name ) { BcMemZero( &Header_, sizeof( Header_ ) ); pChunks_ = NULL; pData_ = NULL; }
////////////////////////////////////////////////////////////////////////// // saveDependancy Json::Value CsCore::saveDependancy( const CsDependancy& Dependancy ) { // Json::Value Object( Json::objectValue ); Object[ "filename" ] = *Dependancy.getFileName(); // Encode stats as binary. // NOTE: Endianess isn't taken into account. BcU32 BufferSize = sizeof( FsStats ) * 2; BcChar* pStatsBuffer = new BcChar[ BufferSize ]; base64::base64_encodestate EncodeState; BcMemZero( pStatsBuffer, BufferSize ); BcMemZero( &EncodeState, sizeof( EncodeState ) ); base64::base64_encode_block( reinterpret_cast< const char* >( &Dependancy.getStats() ), sizeof( FsStats ), reinterpret_cast< char* >( pStatsBuffer ), &EncodeState ); Object[ "stats" ] = pStatsBuffer; delete [] pStatsBuffer; return Object; }
//////////////////////////////////////////////////////////////////////////////// // bridge BcBool GaMatchmakingState::sendLocalAddress( const BcChar* pDest ) { BcBool GotPort = BcTrue; if( MappedHandshakeAddr_ == 0 ) { doSTUN(); } if( GotPort ) { // Got a port open, also grab our LAN address. struct in_addr Addr; BcMemZero( &Addr, sizeof( Addr ) ); char HostName[ 128 ]; if( gethostname( HostName, sizeof( HostName ) ) != SOCKET_ERROR ) { struct hostent* pHostEntry = gethostbyname( HostName ); if( pHostEntry != NULL ) { for( int Idx = 0; pHostEntry->h_addr_list[ Idx ] != 0; ++Idx ) { memcpy( &Addr, pHostEntry->h_addr_list[ Idx ], sizeof( struct in_addr ) ); break; } } } // BcChar AddrBuffer[ 256 ]; BcSPrintf( AddrBuffer, "ADDR:%u.%u.%u.%u:%u/%u.%u.%u.%u:%u", Addr.S_un.S_un_b.s_b1, Addr.S_un.S_un_b.s_b2, Addr.S_un.S_un_b.s_b3, Addr.S_un.S_un_b.s_b4, LocalHandshakePort_, ( MappedAddress_.addr >> 24 ) & 0xff, ( MappedAddress_.addr >> 16 ) & 0xff, ( MappedAddress_.addr >> 8 ) & 0xff, ( MappedAddress_.addr ) & 0xff, MappedAddress_.port ); BcPrintf( "Send: %s (%u)\n", AddrBuffer, LocalHandshakePort_ ); // Send message. BcPrintf( "pre-irc_cmd_msg:\n" ); int RetVal = irc_cmd_msg( pSession_, pDest, AddrBuffer ); BcPrintf( "irc_cmd_msg: %u\n", RetVal ); } return GotPort; }
////////////////////////////////////////////////////////////////////////// // Ctor ScnParticleSystemComponent::ScnParticleSystemComponent(): VertexDeclaration_( nullptr ), CurrentVertexBuffer_( 0 ), pParticleBuffer_( nullptr ), NoofParticles_( 0 ), PotentialFreeParticle_( 0 ), Material_( nullptr ), MaterialComponent_( nullptr ), WorldTransformParam_( 0 ), IsLocalSpace_( BcFalse ) { BcMemZero( &VertexBuffers_, sizeof( VertexBuffers_ ) ); }
//////////////////////////////////////////////////////////////////////////////// // Ctor GaMatchmakingState::GaMatchmakingState() { name( "GaMatchmakingState" ); SocketFileDescriptor_ = 0; ClientID_ = BcErrorCode; RemoteHandshakeAddr_ = 0; RemoteHandshakePort_ = 0; LocalHandshakeAddr_ = 0; LocalHandshakePort_ = 0; //MappedHandshakeAddr_ = 0; //MappedHandshakePort_ = 0; LANHandshakeAddr_ = 0; LANHandshakePort_ = 0; HandshakeState_ = HSS_STUN; BcMemZero( &Callbacks_, sizeof( Callbacks_ ) ); Callbacks_.event_connect = event_connect; Callbacks_.event_nick = event_nick; Callbacks_.event_nick = event_quit; Callbacks_.event_join = event_join; Callbacks_.event_part = event_part; Callbacks_.event_mode = event_mode; Callbacks_.event_umode = event_umode; Callbacks_.event_topic = event_topic; Callbacks_.event_kick = event_kick; Callbacks_.event_channel = event_channel; Callbacks_.event_privmsg = event_privmsg; Callbacks_.event_notice = event_notice; Callbacks_.event_channel_notice = event_channel_notice; Callbacks_.event_invite = event_invite; Callbacks_.event_ctcp_req = event_ctcp_req; Callbacks_.event_ctcp_rep = event_ctcp_rep; Callbacks_.event_ctcp_action = event_ctcp_action; Callbacks_.event_unknown = event_unknown; Callbacks_.event_numeric = event_numeric; Callbacks_.event_dcc_chat_req = event_dcc_chat_req; Callbacks_.event_dcc_send_req = event_dcc_send_req; ConnectTimer_ = 0.0f; InviteTimer_ = BcAbs( BcRandom::Global.randReal() ) * 5.0f + 5.0f; HandshakeTimer_ = 0.0f; pSession_ = NULL; #if PLATFORM_WINDOWS BcRandom::Global = BcRandom( ::GetTickCount() ); #endif }
////////////////////////////////////////////////////////////////////////// // initialise //virtual void ScnDebugRenderComponent::initialise( BcU32 NoofVertices ) { Super::initialise(); // NULL internals. BcMemZero( &RenderResources_[ 0 ], sizeof( RenderResources_ ) ); HaveVertexBufferLock_ = BcFalse; // Store number of vertices. NoofVertices_ = NoofVertices; // Which render resource to use. CurrentRenderResource_ = 0; }
////////////////////////////////////////////////////////////////////////// // loadDependancy CsDependancy CsCore::loadDependancy( const Json::Value& Object ) { // Grab props.. BcPath FileName( Object[ "filename" ].asCString() ); std::string StatsB64( Object[ "stats" ].asString() ); // Encode stats as binary. // NOTE: Endianess isn't taken into account. FsStats Stats; base64::base64_decodestate DecodeState; BcMemZero( &DecodeState, sizeof( DecodeState ) ); base64::base64_decode_block( reinterpret_cast< const char* >( StatsB64.c_str() ), StatsB64.size(), reinterpret_cast< char* >( &Stats ), &DecodeState ); return CsDependancy( FileName, Stats ); }
////////////////////////////////////////////////////////////////////////// // onAttach //virtual void ScnParticleSystemComponent::onAttach( ScnEntityWeakRef Parent ) { // Attach a new material component. MaterialComponent_ = Parent->attach< ScnMaterialComponent >( BcName::INVALID, Material_, ScnShaderPermutationFlags::MESH_PARTICLE_3D ); // TODO: Allow different types of geom for this. // TODO: Use index buffer. // Calc what we need. BcU32 NoofVertices = NoofParticles_ * 6; // 2x3 tris. // Create vertex declaration. VertexDeclaration_ = RsCore::pImpl()->createVertexDeclaration( RsVertexDeclarationDesc( 4 ) .addElement( RsVertexElement( 0, 0, 4, RsVertexDataType::FLOAT32, RsVertexUsage::POSITION, 0 ) ) .addElement( RsVertexElement( 0, 16, 4, RsVertexDataType::FLOAT32, RsVertexUsage::TANGENT, 0 ) ) .addElement( RsVertexElement( 0, 32, 2, RsVertexDataType::FLOAT32, RsVertexUsage::TEXCOORD, 0 ) ) .addElement( RsVertexElement( 0, 40, 4, RsVertexDataType::UBYTE_NORM, RsVertexUsage::COLOUR, 0 ) ) ); // Allocate vertex buffers. for( BcU32 Idx = 0; Idx < 2; ++Idx ) { TVertexBuffer& VertexBuffer = VertexBuffers_[ Idx ]; VertexBuffer.pVertexBuffer_ = RsCore::pImpl()->createBuffer( RsBufferDesc( RsBufferType::VERTEX, RsResourceCreationFlags::STREAM, NoofVertices * sizeof( ScnParticleVertex ) ) ); VertexBuffer.UniformBuffer_ = RsCore::pImpl()->createBuffer( RsBufferDesc( RsBufferType::UNIFORM, RsResourceCreationFlags::STREAM, sizeof( VertexBuffer.ObjectUniforms_ ) ) ); } // Allocate particles. pParticleBuffer_ = new ScnParticle[ NoofParticles_ ]; BcMemZero( pParticleBuffer_, sizeof( ScnParticle ) * NoofParticles_ ); Super::onAttach( Parent ); }
////////////////////////////////////////////////////////////////////////// // initialise //virtual void ScnCanvasComponent::initialise( BcU32 NoofVertices ) { Super::initialise(); // NULL internals. BcMemZero( &RenderResources_[ 0 ], sizeof( RenderResources_ ) ); HaveVertexBufferLock_ = BcFalse; // Setup matrix stack with an identity matrix and reserve. MatrixStack_.reserve( 16 ); MatrixStack_.push_back( MaMat4d() ); IsIdentity_ = BcTrue; // Store number of vertices. NoofVertices_ = NoofVertices; // Which render resource to use. CurrentRenderResource_ = 0; }
////////////////////////////////////////////////////////////////////////// // 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(); } }
////////////////////////////////////////////////////////////////////////// // create //virtual void ScnParticleSystemComponent::create() { // TODO: Allow different types of geom for this. // TODO: Use index buffer. // Calc what we need. BcU32 NoofVertices = NoofParticles_ * 6; // 2x3 tris. BcU32 VertexDescriptor = rsVDF_POSITION_XYZ | rsVDF_NORMAL_XYZ | rsVDF_TEXCOORD_UV0 | rsVDF_COLOUR_ABGR8; // Allocate vertex buffers. for( BcU32 Idx = 0; Idx < 2; ++Idx ) { TVertexBuffer& VertexBuffer = VertexBuffers_[ Idx ]; VertexBuffer.pVertexArray_ = new ScnParticleVertex[ NoofVertices ]; VertexBuffer.pVertexBuffer_ = RsCore::pImpl()->createVertexBuffer( RsVertexBufferDesc( VertexDescriptor, NoofVertices ), VertexBuffer.pVertexArray_ ); VertexBuffer.pPrimitive_ = RsCore::pImpl()->createPrimitive( VertexBuffer.pVertexBuffer_, NULL ); } // Allocate particles. pParticleBuffer_ = new ScnParticle[ NoofParticles_ ]; BcMemZero( pParticleBuffer_, sizeof( ScnParticle ) * NoofParticles_ ); Super::create(); }
////////////////////////////////////////////////////////////////////////// // initialise //virtual void ScnParticleSystemComponent::initialise( const Json::Value& Object ) { // Grab number of particles. NoofParticles_ = Object["noofparticles"].asUInt(); BcName MaterialName = Object["material"].asCString(); ScnMaterialRef Material; if( !( CsCore::pImpl()->requestResource( BcName::NONE, MaterialName, Material ) && CsCore::pImpl()->createResource( BcName::NONE, MaterialComponent_, Material, BcErrorCode ) ) ) { BcAssertMsg( BcFalse, "Material invalid blah." ); } WorldTransformParam_ = MaterialComponent_->findParameter( "uWorldTransform" ); // TODO: Allow different types of geom for this. // TODO: Use index buffer. // Calc what we need. BcU32 NoofVertices = NoofParticles_ * 6; // 2x3 tris. BcU32 VertexDescriptor = rsVDF_POSITION_XYZ | rsVDF_NORMAL_XYZ | rsVDF_TEXCOORD_UV0 | rsVDF_COLOUR_RGBA8; // Allocate vertex buffers. for( BcU32 Idx = 0; Idx < 2; ++Idx ) { TVertexBuffer& VertexBuffer = VertexBuffers_[ Idx ]; VertexBuffer.pVertexArray_ = new ScnParticleVertex[ NoofVertices ]; VertexBuffer.pVertexBuffer_ = RsCore::pImpl()->createVertexBuffer( VertexDescriptor, NoofVertices, VertexBuffer.pVertexArray_ ); VertexBuffer.pPrimitive_ = RsCore::pImpl()->createPrimitive( VertexBuffer.pVertexBuffer_, NULL ); } // Allocate particles. pParticleBuffer_ = new ScnParticle[ NoofParticles_ ]; BcMemZero( pParticleBuffer_, sizeof( ScnParticle ) * NoofParticles_ ); // CurrentVertexBuffer_ = 0; }
void ScnCanvasComponent::render( class ScnViewComponent* pViewComponent, RsFrame* pFrame, RsRenderSort Sort ) { // Upload. size_t VertexDataSize = VertexIndex_ * sizeof( ScnCanvasComponentVertex ); if( VertexDataSize > 0 ) { UploadFence_.increment(); RsCore::pImpl()->updateBuffer( RenderResource_.pVertexBuffer_, 0, VertexDataSize, RsResourceUpdateFlags::ASYNC, [ this, VertexDataSize ] ( RsBuffer* Buffer, const RsBufferLock& BufferLock ) { BcAssert( VertexDataSize <= Buffer->getDesc().SizeBytes_ ); BcMemCopy( BufferLock.Buffer_, pWorkingVertices_, VertexDataSize ); UploadFence_.decrement(); } ); } // HUD pass. Sort.Layer_ = 0; Sort.Pass_ = RS_SORT_PASS_MAX; // NOTE: Could do this sort inside of the renderer, but I'm just gonna keep the canvas // as one solid object as to not conflict with other canvas objects when rendered // to the scene. Will not sort by transparency or anything either. //std::stable_sort( PrimitiveSectionList_.begin(), PrimitiveSectionList_.end(), ScnCanvasComponentPrimitiveSectionCompare() ); // Cache last material instance. ScnMaterialComponent* pLastMaterialComponent = NULL; for( BcU32 Idx = 0; Idx < PrimitiveSectionList_.size(); ++Idx ) { auto* PrimitiveSection = &PrimitiveSectionList_[ Idx ]; ScnCanvasComponentRenderNode* pRenderNode = pFrame->newObject< ScnCanvasComponentRenderNode >(); pRenderNode->NoofSections_ = 1;//PrimitiveSectionList_.size(); pRenderNode->pPrimitiveSections_ = pFrame->alloc< ScnCanvasComponentPrimitiveSection >( 1 ); pRenderNode->VertexBuffer_ = RenderResource_.pVertexBuffer_; pRenderNode->VertexDeclaration_ = VertexDeclaration_; // Copy primitive sections in. BcMemZero( pRenderNode->pPrimitiveSections_, sizeof( ScnCanvasComponentPrimitiveSection ) ); *pRenderNode->pPrimitiveSections_ = *PrimitiveSection; // Bind material. // NOTE: We should be binding for every single draw call. We can have the material deal with redundancy internally // if need be. If using multiple canvases we could potentially lose a material bind. //if( pLastMaterialComponent != pRenderNode->pPrimitiveSections_->MaterialComponent_ ) { pLastMaterialComponent = pRenderNode->pPrimitiveSections_->MaterialComponent_; pLastMaterialComponent->bind( pFrame, Sort ); } // Add to frame. //Sort.Layer_ = PrimitiveSection->Layer_; pRenderNode->Sort_ = Sort; pFrame->addRenderNode( pRenderNode ); } // Reset vertices. pVertices_ = pVerticesEnd_ = nullptr; }
////////////////////////////////////////////////////////////////////////// // onHeaderLoaded void CsPackageLoader::onHeaderLoaded( void* pData, BcSize Size ) { // Check we have the right data. BcAssert( pData == &Header_ ); BcAssert( Size == sizeof( Header_ ) ); // Check the header is valid. if( Header_.Magic_ != CsPackageHeader::MAGIC ) { BcPrintf( "CsPackageLoader: Invalid magic number. Not a valid package.\n" ); HasError_ = BcTrue; --PendingCallbackCount_; return; } // Check version number. if( Header_.Version_ != CsPackageHeader::VERSION ) { BcPrintf( "CsPackageLoader: Out of date package. Requires reimport.\n" ); HasError_ = BcTrue; --PendingCallbackCount_; return; } #if PSY_SERVER // Reimport if source file stats changed. const BcPath ImportPackage( CsCore::pImpl()->getPackageImportPath( pPackage_->getName() ) ); FsStats Stats; if( FsCore::pImpl()->fileStats( (*ImportPackage).c_str(), Stats ) ) { if( Header_.SourceFileStatsHash_ != BcHash( reinterpret_cast< BcU8* >( &Stats ), sizeof( Stats ) )) { BcPrintf( "CsPackageLoader: Source file stats have changed.\n" ); HasError_ = BcTrue; --PendingCallbackCount_; return; } } #endif // Allocate all the memory we need up front. pPackageData_ = BcMemAlign( Header_.TotalAllocSize_, Header_.MaxAlignment_ ); // Use this to advance as we need. BcU8* pCurrPackageData = reinterpret_cast< BcU8* >( pPackageData_ ); // Loaded header, now markup the string table, chunks & props. pStringTable_ = reinterpret_cast< BcChar* >( pCurrPackageData ); pCurrPackageData += BcCalcAlignment( Header_.StringTableBytes_, Header_.MinAlignment_ ); pResourceHeaders_ = reinterpret_cast< CsPackageResourceHeader* >( pCurrPackageData ); pCurrPackageData += BcCalcAlignment( Header_.TotalResources_ * sizeof( CsPackageResourceHeader ), Header_.MinAlignment_ ); pChunkHeaders_ = reinterpret_cast< CsPackageChunkHeader* >( pCurrPackageData ); pCurrPackageData += BcCalcAlignment( Header_.TotalChunks_ * sizeof( CsPackageChunkHeader ), Header_.MinAlignment_ ); pChunkData_ = reinterpret_cast< CsPackageChunkData* >( pCurrPackageData ); pCurrPackageData += BcCalcAlignment( Header_.TotalChunks_ * sizeof( CsPackageChunkData ), Header_.MinAlignment_ ); // Clear string table. BcMemZero( pStringTable_, Header_.StringTableBytes_ ); // Clear chunk data. for( BcU32 Idx = 0; Idx < Header_.TotalChunks_; ++Idx ) { pChunkData_[ Idx ].Status_ = csPCS_NOT_LOADED; pChunkData_[ Idx ].Managed_ = BcFalse; pChunkData_[ Idx ].pPackedData_ = NULL; pChunkData_[ Idx ].pUnpackedData_ = NULL; } // Setup file position data. BcU32 Bytes = 0; // Load the string table in. ++PendingCallbackCount_; Bytes = Header_.StringTableBytes_; File_.readAsync( DataPosition_, pStringTable_, Bytes, FsFileOpDelegate::bind< CsPackageLoader, &CsPackageLoader::onStringTableLoaded >( this ) ); DataPosition_ += Bytes; // Load Resources in. ++PendingCallbackCount_; Bytes = Header_.TotalResources_ * sizeof( CsPackageResourceHeader ); File_.readAsync( DataPosition_, pResourceHeaders_, Bytes, FsFileOpDelegate::bind< CsPackageLoader, &CsPackageLoader::onResourceHeadersLoaded >( this ) ); DataPosition_ += Bytes; // Load chunks in. ++PendingCallbackCount_; Bytes = Header_.TotalChunks_ * sizeof( CsPackageChunkHeader ); File_.readAsync( DataPosition_, pChunkHeaders_, Bytes, FsFileOpDelegate::bind< CsPackageLoader, &CsPackageLoader::onChunkHeadersLoaded >( this ) ); DataPosition_ += Bytes; // This callback is complete. --PendingCallbackCount_; }