//----------------------------------------------------------------------------- // Purpose: Allocs a single block of memory from the pool, zeroes the memory before returning // Input : amount - //----------------------------------------------------------------------------- void *CMemoryPool::AllocZero( unsigned int amount ) { void *mem = Alloc( amount ); if ( mem ) { V_memset( mem, 0x00, amount ); } return mem; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CReplayScreenshotTaker::CReplayScreenshotTaker( IViewRender *pViewRender, CViewSetup &view ) : m_pViewRender( pViewRender ), m_View( view ) { m_pUnpaddedPixels = NULL; m_pPaddedPixels = NULL; m_pVTFPixels = NULL; m_pVTFTexture = NULL; m_pBuffer = NULL; if ( !m_pScreenshotTarget ) return; m_aPaddedDims[ 0 ] = m_pScreenshotTarget->GetActualWidth(); m_aPaddedDims[ 1 ] = m_pScreenshotTarget->GetActualHeight(); g_pClientReplayContext->GetScreenshotManager()->GetUnpaddedScreenshotSize( m_aUnpaddedDims[ 0 ], m_aUnpaddedDims[ 1 ] ); // Calculate sizes int nUnpaddedSize = 3 * m_aUnpaddedDims[ 0 ] * m_aUnpaddedDims[ 1 ]; int nPaddedSize = 3 * m_aPaddedDims[ 0 ] * m_aPaddedDims[ 1 ]; // Allocate for padded & unpadded pixel data m_pUnpaddedPixels = new uint8[ nUnpaddedSize ]; m_pPaddedPixels = new uint8[ nPaddedSize ]; // White out the entire padded image V_memset( m_pPaddedPixels, 255, nPaddedSize ); // Create the VTF #ifndef _X360 IVTFTexture *pVTFTexture = CreateVTFTexture(); const int nFlags = TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_SRGB; if ( !pVTFTexture->Init( m_aPaddedDims[ 0 ], m_aPaddedDims[ 1 ], 1, IMAGE_FORMAT_RGB888, nFlags, 1, 1 ) ) return; m_pVTFTexture = pVTFTexture; #else m_pVTFTexture = NULL; #endif // _X360 // Allocate pixels for the output buffer int nVTFSize = 1024 + ( 3 * m_aPaddedDims[ 0 ] * m_aPaddedDims[ 1 ] ); m_pVTFPixels = new uint8[ nVTFSize ]; m_pBuffer = new CUtlBuffer( m_pVTFPixels, nVTFSize ); }
// Sets the length (used to serialize into the buffer ) void CUtlString::SetLength( int nLen ) { if ( nLen > 0 ) { #ifdef _DEBUG int prevLen = m_pString ? Length() : 0; #endif AllocMemory( nLen ); #ifdef _DEBUG if ( nLen > prevLen ) { V_memset( m_pString + prevLen, 0xEB, nLen - prevLen ); } #endif } else { Purge(); } }
void CViewRender::WriteSaveGameScreenshotOfSize( const char *pFilename, int width, int height, bool bCreatePowerOf2Padded/*=false*/, bool bWriteVTF/*=false*/ ) { #ifndef _X360 CMatRenderContextPtr pRenderContext( materials ); pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PushMatrix(); pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->PushMatrix(); g_bRenderingScreenshot = true; // Push back buffer on the stack with small viewport pRenderContext->PushRenderTargetAndViewport( NULL, 0, 0, width, height ); // render out to the backbuffer CViewSetup viewSetup = GetView ( STEREO_EYE_MONO ); viewSetup.x = 0; viewSetup.y = 0; viewSetup.width = width; viewSetup.height = height; viewSetup.fov = ScaleFOVByWidthRatio( viewSetup.fov, ( (float)width / (float)height ) / ( 4.0f / 3.0f ) ); viewSetup.m_bRenderToSubrectOfLargerScreen = true; // draw out the scene // Don't draw the HUD or the viewmodel RenderView( viewSetup, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, 0 ); // get the data from the backbuffer and save to disk // bitmap bits unsigned char *pImage = ( unsigned char * )malloc( width * height * 3 ); // Get Bits from the material system pRenderContext->ReadPixels( 0, 0, width, height, pImage, IMAGE_FORMAT_RGB888 ); // Some stuff to be setup dependent on padded vs. not padded int nSrcWidth, nSrcHeight; unsigned char *pSrcImage; // Create a padded version if necessary unsigned char *pPaddedImage = NULL; if ( bCreatePowerOf2Padded ) { // Setup dimensions as needed int nPaddedWidth = SmallestPowerOfTwoGreaterOrEqual( width ); int nPaddedHeight = SmallestPowerOfTwoGreaterOrEqual( height ); // Allocate int nPaddedImageSize = nPaddedWidth * nPaddedHeight * 3; pPaddedImage = ( unsigned char * )malloc( nPaddedImageSize ); // Zero out the entire thing V_memset( pPaddedImage, 255, nPaddedImageSize ); // Copy over each row individually for ( int nRow = 0; nRow < height; ++nRow ) { unsigned char *pDst = pPaddedImage + 3 * ( nRow * nPaddedWidth ); const unsigned char *pSrc = pImage + 3 * ( nRow * width ); V_memcpy( pDst, pSrc, 3 * width ); } // Setup source data nSrcWidth = nPaddedWidth; nSrcHeight = nPaddedHeight; pSrcImage = pPaddedImage; } else { // Use non-padded info nSrcWidth = width; nSrcHeight = height; pSrcImage = pImage; } // allocate a buffer to write the tga into CUtlBuffer buffer; bool bWriteResult; if ( bWriteVTF ) { // Create and initialize a VTF texture IVTFTexture *pVTFTexture = CreateVTFTexture(); const int nFlags = TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_SRGB; if ( pVTFTexture->Init( nSrcWidth, nSrcHeight, 1, IMAGE_FORMAT_RGB888, nFlags, 1, 1 ) ) { // Copy the image data over to the VTF unsigned char *pDestBits = pVTFTexture->ImageData(); int nDstSize = nSrcWidth * nSrcHeight * 3; V_memcpy( pDestBits, pSrcImage, nDstSize ); // Allocate output buffer int iMaxVTFSize = 1024 + ( nSrcWidth * nSrcHeight * 3 ); void *pVTF = malloc( iMaxVTFSize ); buffer.SetExternalBuffer( pVTF, iMaxVTFSize, 0 ); // Serialize to the buffer bWriteResult = pVTFTexture->Serialize( buffer ); // Free the VTF texture DestroyVTFTexture( pVTFTexture ); } else { bWriteResult = false; } } else { // Write TGA format to buffer int iMaxTGASize = 1024 + ( nSrcWidth * nSrcHeight * 4 ); void *pTGA = malloc( iMaxTGASize ); buffer.SetExternalBuffer( pTGA, iMaxTGASize, 0 ); bWriteResult = TGAWriter::WriteToBuffer( pSrcImage, buffer, nSrcWidth, nSrcHeight, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_RGB888 ); } if ( !bWriteResult ) { Error( "Couldn't write bitmap data snapshot.\n" ); } free( pImage ); free( pPaddedImage ); // async write to disk (this will take ownership of the memory) char szPathedFileName[_MAX_PATH]; Q_snprintf( szPathedFileName, sizeof(szPathedFileName), "//MOD/%s", pFilename ); filesystem->AsyncWrite( szPathedFileName, buffer.Base(), buffer.TellPut(), true ); // restore our previous state pRenderContext->PopRenderTargetAndViewport(); pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PopMatrix(); pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->PopMatrix(); g_bRenderingScreenshot = false; #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CRecastMesh::Build( CMapMesh *pMapMesh ) { double fStartTime = Plat_FloatTime(); Reset(); // Clean any existing data BuildContext ctx; ctx.enableLog( true ); dtStatus status; V_memset(&m_cfg, 0, sizeof(m_cfg)); // Init cache rcCalcBounds( pMapMesh->GetVerts(), pMapMesh->GetNumVerts(), m_cfg.bmin, m_cfg.bmax ); rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height); int gw = 0, gh = 0; rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cellSize, &gw, &gh); const int ts = (int)m_tileSize; const int tw = (gw + ts-1) / ts; const int th = (gh + ts-1) / ts; // Max tiles and max polys affect how the tile IDs are caculated. // There are 22 bits available for identifying a tile and a polygon. int tileBits = rcMin((int)dtIlog2(dtNextPow2(tw*th*EXPECTED_LAYERS_PER_TILE)), 14); if (tileBits > 14) tileBits = 14; int polyBits = 22 - tileBits; m_maxTiles = 1 << tileBits; m_maxPolysPerTile = 1 << polyBits; // Generation params. m_cfg.cs = m_cellSize; m_cfg.ch = m_cellHeight; m_cfg.walkableSlopeAngle = m_agentMaxSlope; m_cfg.walkableHeight = (int)ceilf(m_agentHeight / m_cfg.ch); m_cfg.walkableClimb = (int)floorf(m_agentMaxClimb / m_cfg.ch); m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs); m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize); m_cfg.maxSimplificationError = m_edgeMaxError; m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly; m_cfg.tileSize = (int)m_tileSize; m_cfg.borderSize = m_cfg.walkableRadius + 3; // Reserve enough padding. m_cfg.width = m_cfg.tileSize + m_cfg.borderSize*2; m_cfg.height = m_cfg.tileSize + m_cfg.borderSize*2; m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist; m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError; // Tile cache params. dtTileCacheParams tcparams; memset(&tcparams, 0, sizeof(tcparams)); rcVcopy(tcparams.orig, m_cfg.bmin); tcparams.cs = m_cellSize; tcparams.ch = m_cellHeight; tcparams.width = (int)m_tileSize; tcparams.height = (int)m_tileSize; tcparams.walkableHeight = m_agentHeight; tcparams.walkableRadius = m_agentRadius; tcparams.walkableClimb = m_agentMaxClimb; tcparams.maxSimplificationError = m_edgeMaxError; tcparams.maxTiles = tw*th*EXPECTED_LAYERS_PER_TILE; tcparams.maxObstacles = 2048; dtFreeTileCache(m_tileCache); m_tileCache = dtAllocTileCache(); if (!m_tileCache) { ctx.log(RC_LOG_ERROR, "buildTiledNavigation: Could not allocate tile cache."); return false; } status = m_tileCache->init(&tcparams, m_talloc, m_tcomp, m_tmproc); if (dtStatusFailed(status)) { ctx.log(RC_LOG_ERROR, "buildTiledNavigation: Could not init tile cache."); return false; } dtFreeNavMesh(m_navMesh); m_navMesh = dtAllocNavMesh(); if (!m_navMesh) { ctx.log(RC_LOG_ERROR, "buildTiledNavigation: Could not allocate navmesh."); return false; } dtNavMeshParams params; memset(¶ms, 0, sizeof(params)); rcVcopy(params.orig, m_cfg.bmin); params.tileWidth = m_tileSize*m_cellSize; params.tileHeight = m_tileSize*m_cellSize; params.maxTiles = m_maxTiles; params.maxPolys = m_maxPolysPerTile; status = m_navMesh->init(¶ms); if (dtStatusFailed(status)) { ctx.log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh."); return false; } status = m_navQuery->init( m_navMesh, RECAST_NAVQUERY_MAXNODES ); if (dtStatusFailed(status)) { ctx.log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh query"); return false; } // Preprocess tiles. ctx.resetTimers(); m_cacheLayerCount = 0; m_cacheCompressedSize = 0; m_cacheRawSize = 0; for (int y = 0; y < th; ++y) { for (int x = 0; x < tw; ++x) { TileCacheData tiles[MAX_LAYERS]; memset(tiles, 0, sizeof(tiles)); int ntiles = rasterizeTileLayers(&ctx, pMapMesh, x, y, m_cfg, tiles, MAX_LAYERS); for (int i = 0; i < ntiles; ++i) { TileCacheData* tile = &tiles[i]; status = m_tileCache->addTile(tile->data, tile->dataSize, DT_COMPRESSEDTILE_FREE_DATA, 0); if (dtStatusFailed(status)) { dtFree(tile->data); tile->data = 0; continue; } m_cacheLayerCount++; m_cacheCompressedSize += tile->dataSize; m_cacheRawSize += calcLayerBufferSize(tcparams.width, tcparams.height); } } } // Build initial meshes ctx.startTimer(RC_TIMER_TOTAL); for (int y = 0; y < th; ++y) for (int x = 0; x < tw; ++x) m_tileCache->buildNavMeshTilesAt(x,y, m_navMesh); ctx.stopTimer(RC_TIMER_TOTAL); m_cacheBuildTimeMs = ctx.getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f; m_cacheBuildMemUsage = ((LinearAllocator *)m_talloc)->high; const dtNavMesh* nav = m_navMesh; int navmeshMemUsage = 0; for (int i = 0; i < nav->getMaxTiles(); ++i) { const dtMeshTile* tile = nav->getTile(i); if (tile->header) navmeshMemUsage += tile->dataSize; } DevMsg( "CRecastMesh: Generated navigation mesh %s in %f seconds\n", m_Name.Get(), Plat_FloatTime() - fStartTime ); return true; }
static cache_ragdoll_t *ParseRagdollIntoCache( CStudioHdr *pStudioHdr, vcollide_t *pCollide, int modelIndex ) { IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide ); cache_ragdollsolid_t solidList[RAGDOLL_MAX_ELEMENTS]; cache_ragdollconstraint_t constraintList[RAGDOLL_MAX_ELEMENTS]; solid_t solid; int constraintCount = 0; int solidCount = 0; cache_ragdoll_t cache; V_memset( &cache, 0, sizeof(cache) ); while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); if ( !strcmpi( pBlock, "solid" ) ) { pParse->ParseSolid( &solid, &g_SolidSetup ); cache_ragdollsolid_t *pSolid = &solidList[solidCount]; pSolid->boneIndex = Studio_BoneIndexByName( pStudioHdr, solid.name ); if ( pSolid->boneIndex >= 0 ) { pSolid->collideIndex = solid.index; pSolid->surfacePropIndex = physprops->GetSurfaceIndex( solid.surfaceprop ); if ( pSolid->surfacePropIndex < 0 ) { pSolid->surfacePropIndex = physprops->GetSurfaceIndex( "default" ); } pSolid->params = solid.params; pSolid->params.enableCollisions = false; solidCount++; } else { Msg( "ParseRagdollIntoCache: Couldn't Lookup Bone %s\n", solid.name ); } } else if ( !strcmpi( pBlock, "ragdollconstraint" ) ) { constraint_ragdollparams_t constraint; pParse->ParseRagdollConstraint( &constraint, NULL ); if( constraint.childIndex != constraint.parentIndex && constraint.childIndex >= 0 && constraint.parentIndex >= 0) { cache_ragdollconstraint_t *pOut = &constraintList[constraintCount]; constraintCount++; V_memcpy( pOut->axes, constraint.axes, sizeof(constraint.axes) ); pOut->parentIndex = constraint.parentIndex; pOut->childIndex = constraint.childIndex; Studio_CalcBoneToBoneTransform( pStudioHdr, solidList[constraint.childIndex].boneIndex, solidList[constraint.parentIndex].boneIndex, pOut->constraintToAttached ); } } else if ( !strcmpi( pBlock, "collisionrules" ) ) { ragdollcollisionrules_t rules; IPhysicsCollisionSet *pSet = physics->FindOrCreateCollisionSet( modelIndex, pCollide->solidCount ); rules.Defaults(physics, pSet); pParse->ParseCollisionRules( &rules, NULL ); cache.pCollisionSet = rules.pCollisionSet; } else if ( !strcmpi( pBlock, "animatedfriction") ) { pParse->ParseRagdollAnimatedFriction( &cache.animfriction, NULL ); } else { pParse->SkipBlock(); } } physcollision->VPhysicsKeyParserDestroy( pParse ); cache.solidCount = solidCount; cache.constraintCount = constraintCount; return CreateRagdollCache( pCollide, solidList, constraintList, &cache ); }
void CPlayerSpawnCache::Reset() { V_memset( &m_Data, 0, sizeof( m_Data ) ); }