void CMySQLQuery::Format( const char *pFormat, ... ) { #define QUERYTEXT_GROWSIZE 1024 // This keeps growing the buffer and calling _vsnprintf until the buffer is // large enough to hold all the data. m_QueryText.SetSize( QUERYTEXT_GROWSIZE ); while ( 1 ) { va_list marker; va_start( marker, pFormat ); int ret = _vsnprintf( m_QueryText.Base(), m_QueryText.Count(), pFormat, marker ); va_end( marker ); if ( ret < 0 ) { m_QueryText.SetSize( m_QueryText.Count() + QUERYTEXT_GROWSIZE ); } else { m_QueryText[ m_QueryText.Count() - 1 ] = 0; break; } } }
static void Graphical_Start() { g_bUseGraphics = VMPI_IsParamUsed( mpi_Graphics ); if ( !g_bUseGraphics ) return; // Setup an event so we'll wait until the window is ready. if ( !g_hCreateEvent ) { g_hCreateEvent = CreateEvent( 0, 0, 0, 0 ); g_hDestroyWindowEvent = CreateEvent( 0, 0, 0, 0 ); g_hDestroyWindowCompletedEvent = CreateEvent( 0, 0, 0, 0 ); InitializeCriticalSection( &g_CS ); } ResetEvent( g_hCreateEvent ); ResetEvent( g_hDestroyWindowCompletedEvent ); g_WUStatus.SetSize( g_WorkUnits.Count() ); for ( int i=0; i < g_WUStatus.Count(); i++ ) g_WUStatus[i].m_iState = 0; // Setup our thread. CreateThread( NULL, 0, ThreadProc, NULL, 0, NULL ); // Wait until the event is signaled. WaitForSingleObject( g_hCreateEvent, INFINITE ); }
void jInit_destination(j_compress_ptr cinfo) { jOut.Purge(); jOut.SetSize(BLOCK_SIZE); cinfo->dest->next_output_byte = &jOut[0]; cinfo->dest->free_in_buffer = jOut.Count(); }
void SetupDispBoxes( const CCoreDispInfo *pListBase, int listSize, CUtlVector<CDispBox> &out ) { out.SetSize( listSize ); for ( int i=0; i < listSize; i++ ) { const CCoreDispInfo *pDisp = &pListBase[i]; // Calculate the bbox for this displacement. Vector vMin( 1e24, 1e24, 1e24 ); Vector vMax( -1e24, -1e24, -1e24 ); for ( int iVert=0; iVert < 4; iVert++ ) { const Vector &vTest = pDisp->GetSurface()->GetPoint( iVert ); VectorMin( vTest, vMin, vMin ); VectorMax( vTest, vMax, vMax ); } // Puff the box out a little. static float flPuff = 0.1f; vMin -= Vector( flPuff, flPuff, flPuff ); vMax += Vector( flPuff, flPuff, flPuff ); out[i].m_Min = vMin; out[i].m_Max = vMax; } }
bool CJobWatchDlg::GetCurrentWorkerText( CUtlVector<char> &text, unsigned long &curMessageIndex ) { text.SetSize( 0 ); unsigned long jobWorkerID; if ( !GetCurJobWorkerID( jobWorkerID ) ) return false; // Now copy all the text out. CMySQLQuery query; if ( curMessageIndex == 0 ) query.Format( "select * from text_messages where JobWorkerID=%lu", jobWorkerID ); else query.Format( "select * from text_messages where JobWorkerID=%lu and MessageIndex >= %lu", jobWorkerID, curMessageIndex ); GetMySQL()->Execute( query ); while ( GetMySQL()->NextRow() ) { const char *pTextStr = GetMySQL()->GetColumnValue( "text" ).String(); int len = strlen( pTextStr ); text.AddMultipleToTail( len, pTextStr ); curMessageIndex = GetMySQL()->GetColumnValue( "MessageIndex" ).UInt32() + 1; } text.AddToTail( 0 ); return true; }
virtual void OnPacketReceived( CTCPPacket *pPacket ) { if ( g_ClientPacket.Count() < pPacket->GetLen() ) g_ClientPacket.SetSize( pPacket->GetLen() ); memcpy( g_ClientPacket.Base(), pPacket->GetData(), pPacket->GetLen() ); g_ClientPacketEvent.SetEvent(); pPacket->Release(); }
void InitMacroTexture( const char *pBSPFilename ) { // Get the world bounds (same ones used by minimaps and level designers know how to use). int i = 0; for (i = 0; i < num_entities; ++i) { char* pEntity = ValueForKey(&entities[i], "classname"); if( !strcmp(pEntity, "worldspawn") ) { GetVectorForKey( &entities[i], "world_mins", g_MacroWorldMins ); GetVectorForKey( &entities[i], "world_maxs", g_MacroWorldMaxs ); break; } } if ( i == num_entities ) { Warning( "MaskOnMacroTexture: can't find worldspawn" ); return; } // Load the macro texture that is mapped onto everything. char mapName[512], vtfFilename[512]; Q_FileBase( pBSPFilename, mapName, sizeof( mapName ) ); Q_snprintf( vtfFilename, sizeof( vtfFilename ), "materials/macro/%s/base.vtf", mapName ); g_pGlobalMacroTextureData = LoadMacroTextureFile( vtfFilename ); // Now load the macro texture for each face. g_FaceMacroTextures.SetSize( numfaces ); for ( int iFace=0; iFace < numfaces; iFace++ ) { g_FaceMacroTextures[iFace] = NULL; if ( iFace < g_FaceMacroTextureInfos.Count() ) { unsigned short stringID = g_FaceMacroTextureInfos[iFace].m_MacroTextureNameID; if ( stringID != 0xFFFF ) { const char *pMacroTextureName = &g_TexDataStringData[ g_TexDataStringTable[stringID] ]; Q_snprintf( vtfFilename, sizeof( vtfFilename ), "%smaterials/%s.vtf", gamedir, pMacroTextureName ); g_FaceMacroTextures[iFace] = FindMacroTexture( vtfFilename ); if ( !g_FaceMacroTextures[iFace] ) { g_FaceMacroTextures[iFace] = LoadMacroTextureFile( vtfFilename ); if ( g_FaceMacroTextures[iFace] ) { g_MacroTextureLookup.Insert( vtfFilename, g_FaceMacroTextures[iFace] ); } } } } } }
void ScratchPad_DrawSphere( IScratchPad3D *pPad, const Vector &vCenter, float flRadius, const Vector &vColor, int nSubDivs ) { CUtlVector<Vector> prevPoints; prevPoints.SetSize( nSubDivs ); // For each vertical slice.. (the top and bottom ones are just a single point). for ( int iSlice=0; iSlice < nSubDivs; iSlice++ ) { float flHalfSliceAngle = M_PI * (float)iSlice / (nSubDivs - 1); if ( iSlice == 0 ) { prevPoints[0] = vCenter + Vector( 0, 0, flRadius ); for ( int z=1; z < prevPoints.Count(); z++ ) prevPoints[z] = prevPoints[0]; } else { for ( int iSubPt=0; iSubPt < nSubDivs; iSubPt++ ) { float flHalfAngle = M_PI * (float)iSubPt / (nSubDivs - 1); float flAngle = flHalfAngle * 2; Vector pt; if ( iSlice == (nSubDivs - 1) ) { pt = vCenter - Vector( 0, 0, flRadius ); } else { pt.x = cos( flAngle ) * sin( flHalfSliceAngle ); pt.y = sin( flAngle ) * sin( flHalfSliceAngle ); pt.z = cos( flHalfSliceAngle ); pt *= flRadius; pt += vCenter; } pPad->DrawLine( CSPVert( pt, vColor ), CSPVert( prevPoints[iSubPt], vColor ) ); prevPoints[iSubPt] = pt; } if ( iSlice != (nSubDivs - 1) ) { for ( int i=0; i < nSubDivs; i++ ) pPad->DrawLine( CSPVert( prevPoints[i], vColor ), CSPVert( prevPoints[(i+1)%nSubDivs], vColor ) ); } } } }
void VMPITracker_Start( int nWorkUnits ) { g_bTrackWorkUnitEvents = (VMPI_IsParamUsed( mpi_TrackEvents ) || VMPI_IsParamUsed( mpi_Graphics )); g_flJobStartTime = Plat_FloatTime(); g_WorkUnits.Purge(); if ( g_bTrackWorkUnitEvents ) { g_WorkUnits.SetSize( nWorkUnits ); } Graphical_Start(); }
void ShowMPIStats( double flTimeSpent, unsigned long nBytesSent, unsigned long nBytesReceived, unsigned long nMessagesSent, unsigned long nMessagesReceived ) { double flKSent = (nBytesSent + 511) / 1024; double flKRecv = (nBytesReceived + 511) / 1024; bool bShowOutput = VMPI_IsParamUsed( mpi_ShowDistributeWorkStats ); bool bOldSuppress = g_bSuppressPrintfOutput; g_bSuppressPrintfOutput = !bShowOutput; Msg( "\n\n--------------------------------------------------------------\n"); Msg( "Total Time : %.2f\n", flTimeSpent ); Msg( "Total Bytes Sent : %dk (%.2fk/sec, %d messages)\n", (int)flKSent, flKSent / flTimeSpent, nMessagesSent ); Msg( "Total Bytes Recv : %dk (%.2fk/sec, %d messages)\n", (int)flKRecv, flKRecv / flTimeSpent, nMessagesReceived ); if ( g_bMPIMaster ) { Msg( "Duplicated WUs : %I64u (%.1f%%)\n", g_nDuplicatedWUs, (float)g_nDuplicatedWUs * 100.0f / g_nWUs ); Msg( "\nWU count by proc:\n" ); int nProcs = VMPI_GetCurrentNumberOfConnections(); CUtlVector<int> sortedProcs; sortedProcs.SetSize( nProcs ); for ( int i=0; i < nProcs; i++ ) sortedProcs[i] = i; qsort( sortedProcs.Base(), nProcs, sizeof( int ), SortByWUCount ); for ( int i=0; i < nProcs; i++ ) { const char *pMachineName = VMPI_GetMachineName( sortedProcs[i] ); Msg( "%s", pMachineName ); char formatStr[512]; Q_snprintf( formatStr, sizeof( formatStr ), "%%%ds %I64u\n", 30 - strlen( pMachineName ), g_wuCountByProcess[ sortedProcs[i] ] ); Msg( formatStr, ":" ); } } Msg( "--------------------------------------------------------------\n\n "); g_bSuppressPrintfOutput = bOldSuppress; }
void Test_InitRandomEntitySpawner( const CCommand &args ) { // Put the list of registered functions into array form for convenience. g_StressEntityRegs.Purge(); for ( CStressEntityReg *pCur=CStressEntityReg::GetListHead(); pCur; pCur=pCur->GetNext() ) g_StressEntityRegs.AddToTail( pCur ); // Create slots for all the entities.. int nSlots = 100; if ( args.ArgC() >= 2 ) nSlots = atoi( args[ 1 ] ); g_StressEntities.Purge(); g_StressEntities.SetSize( nSlots ); Msg( "Test_InitRandomEntitySpawner: created %d slots.\n", nSlots ); }
DWORD WINAPI PortalMCThreadFn( LPVOID p ) { CUtlVector<char> data; data.SetSize( portalbytes + 128 ); DWORD waitTime = 0; while ( WaitForSingleObject( g_MCThreadExitEvent.GetEventHandle(), waitTime ) != WAIT_OBJECT_0 ) { CIPAddr ipFrom; int len = g_pPortalMCSocket->RecvFrom( data.Base(), data.Count(), &ipFrom ); if ( len == -1 ) { waitTime = 20; } else { // These lengths must match exactly what is sent in ReceivePortalFlow. if ( len == 2 + sizeof( g_PortalMCThreadUniqueID ) + sizeof( int ) + portalbytes ) { // Perform more validation... if ( data[0] == VMPI_VVIS_PACKET_ID && data[1] == VMPI_PORTALFLOW_RESULTS ) { if ( *((unsigned long*)&data[2]) == g_PortalMCThreadUniqueID ) { int iWorkUnit = *((int*)&data[6]); if ( iWorkUnit >= 0 && iWorkUnit < g_numportals*2 ) { portal_t *p = sorted_portals[iWorkUnit]; if ( p ) { ++g_nMulticastPortalsReceived; memcpy( p->portalvis, &data[10], portalbytes ); p->status = stat_done; waitTime = 0; } } } } } } } return 0; }
CMacroTextureData* LoadMacroTextureFile( const char *pFilename ) { FileHandle_t hFile = g_pFileSystem->Open( pFilename, "rb" ); if ( hFile == FILESYSTEM_INVALID_HANDLE ) return NULL; // Read the file in. CUtlVector<char> tempData; tempData.SetSize( g_pFileSystem->Size( hFile ) ); g_pFileSystem->Read( tempData.Base(), tempData.Count(), hFile ); g_pFileSystem->Close( hFile ); // Now feed the data into a CUtlBuffer (great...) CUtlBuffer buf; buf.Put( tempData.Base(), tempData.Count() ); // Now make a texture out of it. IVTFTexture *pTex = CreateVTFTexture(); if ( !pTex->Unserialize( buf ) ) Error( "IVTFTexture::Unserialize( %s ) failed.", pFilename ); pTex->ConvertImageFormat( IMAGE_FORMAT_RGBA8888, false ); // Get it in a format we like. // Now convert to a CMacroTextureData. CMacroTextureData *pData = new CMacroTextureData; pData->m_Width = pTex->Width(); pData->m_Height = pTex->Height(); pData->m_ImageData.EnsureCapacity( pData->m_Width * pData->m_Height * 4 ); memcpy( pData->m_ImageData.Base(), pTex->ImageData(), pData->m_Width * pData->m_Height * 4 ); DestroyVTFTexture( pTex ); Msg( "-- LoadMacroTextureFile: %s\n", pFilename ); return pData; }
KeyValues* ReadKeyValuesFile( const char *pFilename ) { // Read in the gameinfo.txt file and null-terminate it. FILE *fp = fopen( pFilename, "rb" ); if ( !fp ) return NULL; CUtlVector<char> buf; fseek( fp, 0, SEEK_END ); buf.SetSize( ftell( fp ) + 1 ); fseek( fp, 0, SEEK_SET ); fread( buf.Base(), 1, buf.Count()-1, fp ); fclose( fp ); buf[buf.Count()-1] = 0; KeyValues *kv = new KeyValues( "" ); if ( !kv->LoadFromBuffer( pFilename, buf.Base() ) ) { kv->deleteThis(); return NULL; } return kv; }
void SnapRemainingVertsToSurface( CCoreDispInfo *pCoreDisp, ddispinfo_t *pDispInfo ) { // First, tesselate the displacement. CUtlVector<unsigned short> indices; CVBSPTesselateHelper helper; helper.m_pIndices = &indices; helper.m_pActiveVerts = pCoreDisp->GetAllowedVerts().Base(); helper.m_pPowerInfo = pCoreDisp->GetPowerInfo(); ::TesselateDisplacement( &helper ); // Figure out which verts are actually referenced in the tesselation. CUtlVector<bool> vertsTouched; vertsTouched.SetSize( pCoreDisp->GetSize() ); memset( vertsTouched.Base(), 0, sizeof( bool ) * vertsTouched.Count() ); for ( int i=0; i < indices.Count(); i++ ) vertsTouched[ indices[i] ] = true; // Generate 2D floating point coordinates for each vertex. We use these to generate // barycentric coordinates, and the scale doesn't matter. CUtlVector<Vector2D> vertCoords; vertCoords.SetSize( pCoreDisp->GetSize() ); for ( int y=0; y < pCoreDisp->GetHeight(); y++ ) { for ( int x=0; x < pCoreDisp->GetWidth(); x++ ) vertCoords[y*pCoreDisp->GetWidth()+x].Init( x, y ); } // Now, for each vert not touched, snap its position to the main surface. for ( int y=0; y < pCoreDisp->GetHeight(); y++ ) { for ( int x=0; x < pCoreDisp->GetWidth(); x++ ) { int index = y * pCoreDisp->GetWidth() + x; if ( !( vertsTouched[index] ) ) { float bcCoords[3]; int iStartVert = -1; if ( FindEnclosingTri( vertCoords[index], vertCoords, indices, &iStartVert, bcCoords ) ) { const Vector &A = pCoreDisp->GetVert( indices[iStartVert+0] ); const Vector &B = pCoreDisp->GetVert( indices[iStartVert+1] ); const Vector &C = pCoreDisp->GetVert( indices[iStartVert+2] ); Vector vNewPos = A*bcCoords[0] + B*bcCoords[1] + C*bcCoords[2]; // This is kind of cheesy, but it gets the job done. Since the CDispVerts store the // verts relative to some other offset, we'll just offset their position instead // of setting it directly. Vector vOffset = vNewPos - pCoreDisp->GetVert( index ); // Modify the mapfile vert. CDispVert *pVert = &g_DispVerts[pDispInfo->m_iDispVertStart + index]; pVert->m_vVector = (pVert->m_vVector * pVert->m_flDist) + vOffset; pVert->m_flDist = 1; // Modify the CCoreDispInfo vert (although it probably won't be used later). pCoreDisp->SetVert( index, vNewPos ); } else { // This shouldn't happen because it would mean that the triangulation that // disp_tesselation.h produced was missing a chunk of the space that the // displacement covers. // It also could indicate a floating-point epsilon error.. check to see if // FindEnclosingTri finds a triangle that -almost- encloses the vert. Assert( false ); } } } } }
/* ============ LoadPortals ============ */ void LoadPortals (char *name) { int i, j; portal_t *p; leaf_t *l; char magic[80]; int numpoints; winding_t *w; int leafnums[2]; plane_t plane; FILE *f; // Open the portal file. if ( g_bUseMPI ) { // If we're using MPI, copy off the file to a temporary first. This will download the file // from the MPI master, then we get to use nice functions like fscanf on it. char tempPath[MAX_PATH], tempFile[MAX_PATH]; if ( GetTempPath( sizeof( tempPath ), tempPath ) == 0 ) { Error( "LoadPortals: GetTempPath failed.\n" ); } if ( GetTempFileName( tempPath, "vvis_portal_", 0, tempFile ) == 0 ) { Error( "LoadPortals: GetTempFileName failed.\n" ); } // Read all the data from the network file into memory. FileHandle_t hFile = g_pFileSystem->Open(name, "r"); if ( hFile == FILESYSTEM_INVALID_HANDLE ) Error( "LoadPortals( %s ): couldn't get file from master.\n", name ); CUtlVector<char> data; data.SetSize( g_pFileSystem->Size( hFile ) ); g_pFileSystem->Read( data.Base(), data.Count(), hFile ); g_pFileSystem->Close( hFile ); // Dump it into a temp file. f = fopen( tempFile, "wt" ); fwrite( data.Base(), 1, data.Count(), f ); fclose( f ); // Open the temp file up. f = fopen( tempFile, "rSTD" ); // read only, sequential, temporary, delete on close } else { f = fopen( name, "r" ); } if ( !f ) Error ("LoadPortals: couldn't read %s\n",name); if (fscanf (f,"%79s\n%i\n%i\n",magic, &portalclusters, &g_numportals) != 3) Error ("LoadPortals: failed to read header"); if (stricmp(magic,PORTALFILE)) Error ("LoadPortals: not a portal file"); Msg ("%4i portalclusters\n", portalclusters); Msg ("%4i numportals\n", g_numportals); if (g_numportals * 2 >= MAX_PORTALS) { Error("The map overflows the max portal count (%d of max %d)!\n", g_numportals, MAX_PORTALS / 2 ); } // these counts should take advantage of 64 bit systems automatically leafbytes = ((portalclusters+63)&~63)>>3; leaflongs = leafbytes/sizeof(long); portalbytes = ((g_numportals*2+63)&~63)>>3; portallongs = portalbytes/sizeof(long); // each file portal is split into two memory portals portals = (portal_t*)malloc(2*g_numportals*sizeof(portal_t)); memset (portals, 0, 2*g_numportals*sizeof(portal_t)); leafs = (leaf_t*)malloc(portalclusters*sizeof(leaf_t)); memset (leafs, 0, portalclusters*sizeof(leaf_t)); originalvismapsize = portalclusters*leafbytes; uncompressedvis = (byte*)malloc(originalvismapsize); vismap = vismap_p = dvisdata; dvis->numclusters = portalclusters; vismap_p = (byte *)&dvis->bitofs[portalclusters]; vismap_end = vismap + MAX_MAP_VISIBILITY; for (i=0, p=portals ; i<g_numportals ; i++) { if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1]) != 3) Error ("LoadPortals: reading portal %i", i); if (numpoints > MAX_POINTS_ON_WINDING) Error ("LoadPortals: portal %i has too many points", i); if ( (unsigned)leafnums[0] > portalclusters || (unsigned)leafnums[1] > portalclusters) Error ("LoadPortals: reading portal %i", i); w = p->winding = NewWinding (numpoints); w->original = true; w->numpoints = numpoints; for (j=0 ; j<numpoints ; j++) { double v[3]; int k; // scanf into double, then assign to vec_t // so we don't care what size vec_t is if (fscanf (f, "(%lf %lf %lf ) " , &v[0], &v[1], &v[2]) != 3) Error ("LoadPortals: reading portal %i", i); for (k=0 ; k<3 ; k++) w->points[j][k] = v[k]; } fscanf (f, "\n"); // calc plane PlaneFromWinding (w, &plane); // create forward portal l = &leafs[leafnums[0]]; if (l->numportals == MAX_PORTALS_ON_LEAF) Error ("Leaf %d (portal %d) with too many portals. Use vbsp -glview to compile, then glview -portal -portalhighlight X or -leafhighlight L to view the problem.", leafnums[0], i ); l->portals[l->numportals] = p; l->numportals++; p->winding = w; VectorSubtract (vec3_origin, plane.normal, p->plane.normal); p->plane.dist = -plane.dist; p->leaf = leafnums[1]; SetPortalSphere (p); p++; // create backwards portal l = &leafs[leafnums[1]]; if (l->numportals == MAX_PORTALS_ON_LEAF) Error ("Leaf %d (portal %d) with too many portals. Use vbsp -glview to compile, then glview -portal -portalhighlight X or -leafhighlight L to view the problem.", leafnums[1], i ); l->portals[l->numportals] = p; l->numportals++; p->winding = NewWinding(w->numpoints); p->winding->numpoints = w->numpoints; for (j=0 ; j<w->numpoints ; j++) { VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]); } p->plane = plane; p->leaf = leafnums[0]; SetPortalSphere (p); p++; } fclose (f); }
// adds all displacement faces as a series of convex objects // UNDONE: Only add the displacements for this model? void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask ) { int dispIndex; // Add each displacement to the grid hash for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ ) { CCoreDispInfo *pDispInfo = &g_CoreDispInfos[ dispIndex ]; mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ]; // not solid for this pass if ( !(pMapDisp->contents & contentsMask) ) continue; int gridIndex = Disp_GridIndex( pDispInfo ); AddToGrid( gridIndex, dispIndex ); } // now make a polysoup for the terrain in each grid for ( int grid = 0; grid < gDispGridList.Count(); grid++ ) { int triCount = 0; CPhysPolysoup *pTerrainPhysics = physcollision->PolysoupCreate(); // iterate the displacements in this grid for ( int listIndex = 0; listIndex < gDispGridList[grid].dispList.Count(); listIndex++ ) { dispIndex = gDispGridList[grid].dispList[listIndex]; CCoreDispInfo *pDispInfo = &g_CoreDispInfos[ dispIndex ]; mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ]; // Get the material id. MaterialSystemMaterial_t matID = GetMatIDFromDisp( pMapDisp ); // Get the triangle count. int nTriCount = pDispInfo->GetTriCount(); if ( nTriCount >= 0xFFFF ) { // if we hit this error, it's probably time to make the grid adaptive (DISP_GRID_SIZEX,etc) Error("Terrain collision overflow!\n"); } // Convert the tristrip into a triangle list. CUtlVector<unsigned short> indices; indices.SetSize( nTriCount * 3 ); for ( int iTri = 0; iTri < nTriCount; ++iTri ) { unsigned short iVert0, iVert1, iVert2; pDispInfo->GetTriIndices( iTri, iVert0, iVert1, iVert2 ); indices[iTri*3] = iVert0; indices[iTri*3+1] = iVert1; indices[iTri*3+2] = iVert2; } Vector tmpVerts[3]; for ( iTri = 0; iTri < nTriCount; ++iTri ) { float flAlphaTotal = 0.0f; for ( int iTriVert = 0; iTriVert < 3; ++iTriVert ) { pDispInfo->GetVert( indices[iTri*3+iTriVert], tmpVerts[iTriVert] ); flAlphaTotal += pDispInfo->GetAlpha( indices[iTri*3+iTriVert] ); } int nProp = g_SurfaceProperties[texinfo[pMapDisp->face.texinfo].texdata]; if ( flAlphaTotal > DISP_ALPHA_PROP_DELTA ) { int nProp2 = GetSurfaceProperties2( matID, "surfaceprop2" ); if ( nProp2 != -1 ) { nProp = nProp2; } } int nMaterialIndex = RemapWorldMaterial( nProp ); physcollision->PolysoupAddTriangle( pTerrainPhysics, tmpVerts[0], tmpVerts[1], tmpVerts[2], nMaterialIndex ); } } // convert the whole grid's polysoup to a collide and store in the collision list CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics ); if ( pCollide ) { collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); } // now that we have the collide, we're done with the soup physcollision->PolysoupDestroy( pTerrainPhysics ); } }
void EmitDispLMAlphaAndNeighbors() { int i; Msg( "Finding displacement neighbors...\n" ); // Do lightmap alpha. g_DispLightmapAlpha.RemoveAll(); // Build the CCoreDispInfos. CUtlVector<dface_t*> faces; // Create the core dispinfos and init them for use as CDispUtilsHelpers. g_CoreDispInfos.SetSize( nummapdispinfo ); for ( i=0; i < nummapdispinfo; i++ ) { g_CoreDispInfos[i].SetDispUtilsHelperInfo( g_CoreDispInfos.Base(), nummapdispinfo ); } faces.SetSize( nummapdispinfo ); for( i = 0; i < numfaces; i++ ) { dface_t *pFace = &dfaces[i]; if( pFace->dispinfo == -1 ) continue; mapdispinfo_t *pMapDisp = &mapdispinfo[pFace->dispinfo]; // Set the displacement's face index. ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; pDisp->m_iMapFace = i; // Get a CCoreDispInfo. All we need is the triangles and lightmap texture coordinates. CCoreDispInfo *pCoreDispInfo = &g_CoreDispInfos[pFace->dispinfo]; DispMapToCoreDispInfo( pMapDisp, pCoreDispInfo, pFace ); faces[pFace->dispinfo] = pFace; } // Generate and export neighbor data. ExportNeighborData( g_CoreDispInfos.Base(), g_dispinfo.Base(), nummapdispinfo ); // Generate and export the active vert lists. ExportAllowedVertLists( g_CoreDispInfos.Base(), g_dispinfo.Base(), nummapdispinfo ); Msg( "Finding lightmap sample positions...\n" ); for ( i=0; i < nummapdispinfo; i++ ) { dface_t *pFace = faces[i]; ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; CCoreDispInfo *pCoreDispInfo = &g_CoreDispInfos[i]; pDisp->m_iLightmapSamplePositionStart = g_DispLightmapSamplePositions.Count(); CalculateLightmapSamplePositions( pCoreDispInfo, pFace, g_DispLightmapSamplePositions ); } StartPacifier( "Displacement Alpha : "); // Build lightmap alphas. int dispCount = 0; // How many we've processed. for( i = 0; i < nummapdispinfo; i++ ) { dface_t *pFace = faces[i]; Assert( pFace->dispinfo == i ); mapdispinfo_t *pMapDisp = &mapdispinfo[pFace->dispinfo]; ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; CCoreDispInfo *pCoreDispInfo = &g_CoreDispInfos[i]; // Allocate space for the alpha values. pDisp->m_iLightmapAlphaStart = g_DispLightmapAlpha.Count(); int nLuxelsToAdd = (pFace->m_LightmapTextureSizeInLuxels[0]+1) * (pFace->m_LightmapTextureSizeInLuxels[1]+1); g_DispLightmapAlpha.AddMultipleToTail( nLuxelsToAdd ); DispUpdateLightmapAlpha( g_CoreDispInfos.Base(), i, (float)dispCount / g_dispinfo.Count(), (float)(dispCount+1) / g_dispinfo.Count(), pDisp, pFace->m_LightmapTextureSizeInLuxels[0], pFace->m_LightmapTextureSizeInLuxels[1] ); ++dispCount; } EndPacifier(); }
int main(int argc, char* argv[]) { SpewOutputFunc( MySpewFunc ); // Figure out a random port to use. CCycleCount cnt; cnt.Sample(); CUniformRandomStream randomStream; randomStream.SetSeed( cnt.GetMicroseconds() ); int iPort = randomStream.RandomInt( 20000, 30000 ); g_ClientPacketEvent.Init( false, false ); // Setup the "server". CHandlerCreator_Server serverHandler; CIPAddr addr( 127, 0, 0, 1, iPort ); ITCPConnectSocket *pListener = ThreadedTCP_CreateListener( &serverHandler, (unsigned short)iPort ); // Setup the "client". CHandlerCreator_Client clientCreator; ITCPConnectSocket *pConnector = ThreadedTCP_CreateConnector( CIPAddr( 127, 0, 0, 1, iPort ), CIPAddr(), &clientCreator ); // Wait for them to connect. while ( !g_pClientSocket ) { if ( !pConnector->Update( &g_pClientSocket ) ) { Error( "Error in client connector!\n" ); } } pConnector->Release(); while ( !g_pServerSocket ) { if ( !pListener->Update( &g_pServerSocket ) ) Error( "Error in server connector!\n" ); } pListener->Release(); // Send some data. __int64 totalBytes = 0; CCycleCount startTime; int iPacket = 1; startTime.Sample(); CUtlVector<char> buf; while ( (GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0 ) { int size = randomStream.RandomInt( 1024*0, 1024*320 ); if ( buf.Count() < size ) buf.SetSize( size ); if ( g_pClientSocket->Send( buf.Base(), size ) ) { // Server receives the data and echoes it back. Verify that the data is good. WaitForSingleObject( g_ClientPacketEvent.GetEventHandle(), INFINITE ); Assert( memcmp( g_ClientPacket.Base(), buf.Base(), size ) == 0 ); totalBytes += size; CCycleCount curTime, elapsed; curTime.Sample(); CCycleCount::Sub( curTime, startTime, elapsed ); double flSeconds = elapsed.GetSeconds(); Msg( "Packet %d, %d bytes, %dk/sec\n", iPacket++, size, (int)(((totalBytes+511)/1024) / flSeconds) ); } } g_pClientSocket->Release(); g_pServerSocket->Release(); return 0; }
static LRESULT CALLBACK TrackerWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch( uMsg ) { case WM_PAINT: { // Do one pass for each color.. HBRUSH hStateColors[ARRAYSIZE( g_StateColors )]; for ( int i=0; i < ARRAYSIZE( hStateColors ); i++ ) hStateColors[i] = CreateSolidBrush( g_StateColors[i] ); // Copy the WU statuses. CUtlVector<CWUStatus> wuStatus; EnterCriticalSection( &g_CS ); g_nLastDrawnChanges = g_nChanges; wuStatus.SetSize( g_WUStatus.Count() ); memcpy( wuStatus.Base(), g_WUStatus.Base(), wuStatus.Count() * sizeof( wuStatus[0] ) ); LeaveCriticalSection( &g_CS ); PAINTSTRUCT ps; HDC hDC = BeginPaint( hwnd, &ps ); for ( int iState=0; iState < ARRAYSIZE( hStateColors ); iState++ ) { HGDIOBJ hOldObj = SelectObject( hDC, hStateColors[iState] ); for ( int iWU=0; iWU < wuStatus.Count(); iWU++ ) { if ( wuStatus[iWU].m_iState != iState ) continue; RECT &rc = wuStatus[iWU].m_Rect; Rectangle( hDC, rc.left, rc.top, rc.right, rc.bottom ); } SelectObject( hDC, hOldObj ); DeleteObject( hStateColors[iState] ); } EndPaint( hwnd, &ps ); } break; case WM_SIZE: { int width = LOWORD( lParam ); int height = HIWORD( lParam ); g_LastSizeX = width; g_LastSizeY = height; // Figure out the rectangles for everything. int nWorkUnits = g_WUStatus.Count(); // What is the max width of the grid elements so they will fit in the width and height. int testSize; for ( testSize=20; testSize > 1; testSize-- ) { int nX = width / testSize; int nY = height / testSize; if ( nX * nY >= nWorkUnits ) break; } static int minTestSize = 3; testSize = max( testSize, minTestSize ); int xPos=0, yPos=0; for ( int i=0; i < nWorkUnits; i++ ) { g_WUStatus[i].m_Rect.left = xPos; g_WUStatus[i].m_Rect.top = yPos; g_WUStatus[i].m_Rect.right = xPos + testSize; g_WUStatus[i].m_Rect.bottom = yPos + testSize; xPos += testSize; if ( (xPos+testSize) > width ) { yPos += testSize; xPos = 0; } } } break; } return DefWindowProc( hwnd, uMsg, wParam, lParam ); }
//----------------------------------------- // // Run BasePortalVis across all available processing nodes // Then collect and redistribute the results. // void RunMPIBasePortalVis() { int i; Msg( "\n\nportalbytes: %d\nNum Work Units: %d\nTotal data size: %d\n", portalbytes, g_numportals*2, portalbytes*g_numportals*2 ); Msg("%-20s ", "BasePortalVis:"); if ( g_bMPIMaster ) StartPacifier(""); VMPI_SetCurrentStage( "RunMPIBasePortalVis" ); // Note: we're aiming for about 1500 portals in a map, so about 3000 work units. g_CPUTime.Init(); double elapsed = DistributeWork( g_numportals * 2, // # work units VMPI_DISTRIBUTEWORK_PACKETID, // packet ID ProcessBasePortalVis, // Worker function to process work units ReceiveBasePortalVis // Master function to receive work results ); if ( g_bMPIMaster ) { EndPacifier( false ); Msg( " (%d)\n", (int)elapsed ); } // // Distribute the results to all the workers. // if ( g_bMPIMaster ) { if ( !fastvis ) { VMPI_SetCurrentStage( "SendPortalResults" ); // Store all the portal results in a temp file and multicast that to the workers. CUtlVector<char> allPortalData; allPortalData.SetSize( g_numportals * 2 * portalbytes * 2 ); char *pOut = allPortalData.Base(); for ( i=0; i < g_numportals * 2; i++) { portal_t *p = &portals[i]; memcpy( pOut, p->portalfront, portalbytes ); pOut += portalbytes; memcpy( pOut, p->portalflood, portalbytes ); pOut += portalbytes; } const char *pVirtualFilename = "--portal-results--"; VMPI_FileSystem_CreateVirtualFile( pVirtualFilename, allPortalData.Base(), allPortalData.Count() ); char cPacketID[2] = { VMPI_VVIS_PACKET_ID, VMPI_BASEPORTALVIS_RESULTS }; VMPI_Send2Chunks( cPacketID, sizeof( cPacketID ), pVirtualFilename, strlen( pVirtualFilename ) + 1, VMPI_PERSISTENT ); } } else { VMPI_SetCurrentStage( "RecvPortalResults" ); // Wait until we've received the filename from the master. while ( g_BasePortalVisResultsFilename.Count() == 0 ) { VMPI_DispatchNextMessage(); } // Open FileHandle_t fp = g_pFileSystem->Open( g_BasePortalVisResultsFilename.Base(), "rb", VMPI_VIRTUAL_FILES_PATH_ID ); if ( !fp ) Error( "Can't open '%s' to read portal info.", g_BasePortalVisResultsFilename.Base() ); for ( i=0; i < g_numportals * 2; i++) { portal_t *p = &portals[i]; p->portalfront = (byte*)malloc (portalbytes); g_pFileSystem->Read( p->portalfront, portalbytes, fp ); p->portalflood = (byte*)malloc (portalbytes); g_pFileSystem->Read( p->portalflood, portalbytes, fp ); p->portalvis = (byte*)malloc (portalbytes); memset (p->portalvis, 0, portalbytes); p->nummightsee = CountBits (p->portalflood, g_numportals*2); } g_pFileSystem->Close( fp ); } if ( !g_bMPIMaster ) { if ( g_iVMPIVerboseLevel >= 1 ) Msg( "\n%% worker CPU utilization during BasePortalVis: %.1f\n", (g_CPUTime.GetSeconds() * 100.0f / elapsed) / numthreads ); } }
void EmitDispLMAlphaAndNeighbors() { int i; Msg( "Finding displacement neighbors...\n" ); // Build the CCoreDispInfos. CUtlVector<dface_t*> faces; // Create the core dispinfos and init them for use as CDispUtilsHelpers. for ( int iDisp = 0; iDisp < nummapdispinfo; ++iDisp ) { CCoreDispInfo *pDisp = new CCoreDispInfo; if ( !pDisp ) { g_CoreDispInfos.Purge(); return; } int nIndex = g_CoreDispInfos.AddToTail(); pDisp->SetListIndex( nIndex ); g_CoreDispInfos[nIndex] = pDisp; } for ( i=0; i < nummapdispinfo; i++ ) { g_CoreDispInfos[i]->SetDispUtilsHelperInfo( g_CoreDispInfos.Base(), nummapdispinfo ); } faces.SetSize( nummapdispinfo ); for( i = 0; i < numfaces; i++ ) { dface_t *pFace = &dfaces[i]; if( pFace->dispinfo == -1 ) continue; mapdispinfo_t *pMapDisp = &mapdispinfo[pFace->dispinfo]; // Set the displacement's face index. ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; pDisp->m_iMapFace = i; // Get a CCoreDispInfo. All we need is the triangles and lightmap texture coordinates. CCoreDispInfo *pCoreDispInfo = g_CoreDispInfos[pFace->dispinfo]; DispMapToCoreDispInfo( pMapDisp, pCoreDispInfo, pFace ); faces[pFace->dispinfo] = pFace; } // Generate and export neighbor data. ExportNeighborData( g_CoreDispInfos.Base(), g_dispinfo.Base(), nummapdispinfo ); // Generate and export the active vert lists. ExportAllowedVertLists( g_CoreDispInfos.Base(), g_dispinfo.Base(), nummapdispinfo ); // Now that we know which vertices are actually going to be around, snap the ones that won't // be around onto the slightly-reduced mesh. This is so the engine's ray test code and // overlay code works right. SnapRemainingVertsToSurface( g_CoreDispInfos.Base(), g_dispinfo.Base(), nummapdispinfo ); Msg( "Finding lightmap sample positions...\n" ); for ( i=0; i < nummapdispinfo; i++ ) { dface_t *pFace = faces[i]; ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; CCoreDispInfo *pCoreDispInfo = g_CoreDispInfos[i]; pDisp->m_iLightmapSamplePositionStart = g_DispLightmapSamplePositions.Count(); CalculateLightmapSamplePositions( pCoreDispInfo, pFace, g_DispLightmapSamplePositions ); } StartPacifier( "Displacement Alpha : "); // Build lightmap alphas. int dispCount = 0; // How many we've processed. for( i = 0; i < nummapdispinfo; i++ ) { dface_t *pFace = faces[i]; Assert( pFace->dispinfo == i ); mapdispinfo_t *pMapDisp = &mapdispinfo[pFace->dispinfo]; ddispinfo_t *pDisp = &g_dispinfo[pFace->dispinfo]; CCoreDispInfo *pCoreDispInfo = g_CoreDispInfos[i]; // Allocate space for the alpha values. pDisp->m_iLightmapAlphaStart = 0; // not used anymore ++dispCount; } EndPacifier(); }