//----------------------------------------------------------------------------- // XBX_InitConsoleMonitor // //----------------------------------------------------------------------------- void CXboxConsole::InitConsoleMonitor( bool bWaitForConnect ) { if ( XBX_NoXBDM() ) return; // create our events g_xbx_dbgValidEvent = CreateEvent( XBOX_DONTCARE, TRUE, FALSE, NULL ); g_xbx_dbgCmdCompleteEvent = CreateEvent( XBOX_DONTCARE, FALSE, FALSE, NULL ); // register our command handler with the debug monitor HRESULT hr = DmRegisterCommandProcessor( XBX_DBGCOMMANDPREFIX, _DebugCommandHandler ); if ( FAILED( hr ) ) { XBX_Error( "XBX_InitConsoleMonitor: failed to register command processor" ); } // user can have output bypass slave thread g_xbx_bDoSyncOutput = CommandLine()->FindParm( "-syncoutput" ) != 0; // create a slave thread to do delayed VXConsole transactions ThreadId_t threadID; g_xbx_hDebugThread = CreateSimpleThread( _DebugThreadFunc, NULL, &threadID, 16*1024 ); ThreadSetDebugName( threadID, "DebugThread" ); ThreadSetAffinity( g_xbx_hDebugThread, XBOX_PROCESSOR_5 ); if ( bWaitForConnect ) { XBX_DebugString( XBX_CLR_DEFAULT, "Waiting For VXConsole Connection...\n" ); WaitForSingleObject( g_xbx_dbgValidEvent, INFINITE ); } }
//--------------------------------------------------------------------------------- // Purpose: called when the plugin is loaded, load the interface we need from the engine //--------------------------------------------------------------------------------- bool WebSpecPlugin::Load( CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory ) { ConnectTier1Libraries( &interfaceFactory, 1 ); playerInfoManager = (IPlayerInfoManager *)gameServerFactory(INTERFACEVERSION_PLAYERINFOMANAGER,NULL); if ( !playerInfoManager ) { Warning( "[WebSpec] Unable to load PlayerInfoManager!\n" ); return false; } gameEventManager = (IGameEventManager *)interfaceFactory(INTERFACEVERSION_GAMEEVENTSMANAGER,NULL); if( !gameEventManager ) { Warning( "[WebSpec] Unable to load GameEventManager!\n" ); return false; } engine = (IVEngineServer *)interfaceFactory(INTERFACEVERSION_VENGINESERVER, NULL); if (!engine) { Warning("[WebSpec] Unable to load VEngineServer!\n"); return false; } serverGameEnts = (IServerGameEnts *)gameServerFactory(INTERFACEVERSION_SERVERGAMEENTS, NULL); if (!serverGameEnts) { Warning("[WebSpec] Unable to load ServerGameEnts!\n"); return false; } serverGameDLL = (IServerGameDLL *)gameServerFactory("ServerGameDLL008", NULL); // ServerGameDLL008 for TF2, not in hl2sdk-ob-valve if (!serverGameDLL) { return false; } gameEventManager->AddListener(this, true); //Init global variables gpGlobals = playerInfoManager->GetGlobalVars(); ws_teamName[0] = MAKE_STRING("BLU"); ws_teamName[1] = MAKE_STRING("RED"); ws_teamReadyState[0] = false; ws_teamReadyState[1] = false; WSOffsets::PrepareOffsets(); //Init WebSocket server lws_context_creation_info *lwsInfo = new lws_context_creation_info(); lwsInfo->port = wsPort; lwsInfo->iface = NULL; lwsInfo->protocols = wsProtocols; lwsInfo->extensions = libwebsocket_get_internal_extensions(); lwsInfo->ssl_cert_filepath = NULL; lwsInfo->ssl_private_key_filepath = NULL; lwsInfo->ssl_ca_filepath = NULL; lwsInfo->gid = -1; lwsInfo->uid = -1; lwsInfo->options = 0; lwsInfo->user = NULL; lwsInfo->ka_time = 0; wsContext = libwebsocket_create_context(lwsInfo); if (wsContext == NULL) Msg("[WebSpec] failed to init libwebsockets\n"); //Start WebSpec server ws_shouldListen = true; WSServerThreadParams_t *params = new WSServerThreadParams_t; params->ctx = wsContext; CreateSimpleThread( WSServerThread, params ); g_lastUpdateTime = gpGlobals->curtime; //Everything seems ok! Msg("%s loaded!\n", PLUGIN_DESCRIPTION); //Register cvars ConVar_Register( 0 ); return true; }
FloatBitMap_t *FloatBitMap_t::ComputeSelfShadowedBumpmapFromHeightInAlphaChannel( float bump_scale, int nrays_to_trace_per_pixel, uint32 nOptionFlags ) const { // first, add all the triangles from the height map to the "world". // we will make multiple copies to handle wrapping int tcnt = 1; Vector * verts; Vector * normals; ComputeVertexPositionsAndNormals( bump_scale, & verts, & normals ); RayTracingEnvironment rtEnv; rtEnv.Flags |= RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS; // save some ram if ( nrays_to_trace_per_pixel ) { rtEnv.MakeRoomForTriangles( ( 1 + 2 * NREPS_TILE ) * ( 1 + 2 * NREPS_TILE ) * 2 * Height * Width ); // now, add a whole mess of triangles to trace against for( int tilex =- NREPS_TILE; tilex <= NREPS_TILE; tilex++ ) for( int tiley =- NREPS_TILE; tiley <= NREPS_TILE; tiley++ ) { int min_x = 0; int max_x = Width - 1; int min_y = 0; int max_y = Height - 1; if ( tilex < 0 ) min_x = Width / 2; if ( tilex > 0 ) max_x = Width / 2; if ( tiley < 0 ) min_y = Height / 2; if ( tiley > 0 ) max_y = Height / 2; for( int y = min_y; y <= max_y; y++ ) for( int x = min_x; x <= max_x; x++ ) { Vector ofs( tilex * Width, tiley * Height, 0 ); int x1 = ( x + 1 ) % Width; int y1 = ( y + 1 ) % Height; Vector v0 = verts[x + y * Width]; Vector v1 = verts[x1 + y * Width]; Vector v2 = verts[x1 + y1 * Width]; Vector v3 = verts[x + y1 * Width]; v0.x = x; v0.y = y; v1.x = x + 1; v1.y = y; v2.x = x + 1; v2.y = y + 1; v3.x = x; v3.y = y + 1; v0 += ofs; v1 += ofs; v2 += ofs; v3 += ofs; rtEnv.AddTriangle( tcnt++, v0, v1, v2, Vector( 1, 1, 1 ) ); rtEnv.AddTriangle( tcnt++, v0, v3, v2, Vector( 1, 1, 1 ) ); } } //printf("added %d triangles\n",tcnt-1); ReportProgress("Creating kd-tree",0,0); rtEnv.SetupAccelerationStructure(); // ok, now we have built a structure for ray intersection. we will take advantage // of the SSE ray tracing code by intersecting rays as a batch. } // We need to calculate for each vertex (i.e. pixel) of the heightmap, how "much" of the world // it can see in each basis direction. we will do this by sampling a sphere of rays around the // vertex, and using dot-product weighting to measure the lighting contribution in each basis // direction. note that the surface normal is not used here. The surface normal will end up // being reflected in the result because of rays being blocked when they try to pass through // the planes of the triangles touching the vertex. // note that there is no reason inter-bounced lighting could not be folded into this // calculation. FloatBitMap_t * ret = new FloatBitMap_t( Width, Height ); Vector *trace_directions=new Vector[nrays_to_trace_per_pixel]; DirectionalSampler_t my_sphere_sampler; for( int r=0; r < nrays_to_trace_per_pixel; r++) { Vector trace_dir=my_sphere_sampler.NextValue(); // trace_dir=Vector(1,0,0); trace_dir.z=fabs(trace_dir.z); // upwards facing only trace_directions[ r ]= trace_dir; } volatile SSBumpCalculationContext ctxs[32]; ctxs[0].m_pRtEnv =& rtEnv; ctxs[0].ret_bm = ret; ctxs[0].src_bm = this; ctxs[0].nrays_to_trace_per_pixel = nrays_to_trace_per_pixel; ctxs[0].bump_scale = bump_scale; ctxs[0].trace_directions = trace_directions; ctxs[0].normals = normals; ctxs[0].min_y = 0; ctxs[0].max_y = Height - 1; ctxs[0].m_nOptionFlags = nOptionFlags; int nthreads = min( 32, GetCPUInformation().m_nPhysicalProcessors ); ThreadHandle_t waithandles[32]; int starty = 0; int ystep = Height / nthreads; for( int t = 0;t < nthreads; t++ ) { if ( t ) memcpy( (void * ) ( & ctxs[t] ), ( void * ) & ctxs[0], sizeof( ctxs[0] )); ctxs[t].thread_number = t; ctxs[t].min_y = starty; if ( t != nthreads - 1 ) ctxs[t].max_y = min( Height - 1, starty + ystep - 1 ); else ctxs[t].max_y = Height - 1; waithandles[t]= CreateSimpleThread( SSBumpCalculationThreadFN, ( SSBumpCalculationContext * ) & ctxs[t] ); starty += ystep; } for(int t=0;t<nthreads;t++) { ThreadJoin( waithandles[t] ); } if ( nOptionFlags & SSBUMP_MOD2X_DETAIL_TEXTURE ) { const float flOutputScale = 0.5 * ( 1.0 / .57735026 ); // normalize so that a flat normal yields 0.5 // scale output weights by color channel for( int nY = 0; nY < Height; nY++ ) for( int nX = 0; nX < Width; nX++ ) { float flScale = flOutputScale * (2.0/3.0) * ( Pixel( nX, nY, 0 ) + Pixel( nX, nY, 1 ) + Pixel( nX, nY, 2 ) ); ret->Pixel( nX, nY, 0 ) *= flScale; ret->Pixel( nX, nY, 1 ) *= flScale; ret->Pixel( nX, nY, 2 ) *= flScale; } } delete[] verts; delete[] trace_directions; delete[] normals; return ret; // destructor will clean up rtenv }
ThreadHandle_t CreateSimpleThread( ThreadFunc_t pfnThread, void *pParam, unsigned stackSize ) { return CreateSimpleThread( pfnThread, pParam, NULL, stackSize ); }
HMODULE Sys_LoadLibrary( const char *pLibraryName, Sys_Flags flags ) { char str[ 1024 ]; // Note: DLL_EXT_STRING can be "_srv.so" or "_360.dll". So be careful // when using the V_*Extension* routines... const char *pDllStringExtension = V_GetFileExtension( DLL_EXT_STRING ); const char *pModuleExtension = pDllStringExtension ? ( pDllStringExtension - 1 ) : DLL_EXT_STRING; Q_strncpy( str, pLibraryName, sizeof(str) ); if ( IsX360() ) { // old, probably busted, behavior for xbox if ( !Q_stristr( str, pModuleExtension ) ) { V_SetExtension( str, pModuleExtension, sizeof(str) ); } } else { // always force the final extension to be .dll V_SetExtension( str, pModuleExtension, sizeof(str) ); } Q_FixSlashes( str ); #ifdef _WIN32 ThreadedLoadLibraryFunc_t threadFunc = GetThreadedLoadLibraryFunc(); if ( !threadFunc ) return InternalLoadLibrary( str, flags ); // We shouldn't be passing noload while threaded. Assert( !( flags & SYS_NOLOAD ) ); ThreadedLoadLibaryContext_t context; context.m_pLibraryName = str; context.m_hLibrary = 0; ThreadHandle_t h = CreateSimpleThread( ThreadedLoadLibraryFunc, &context ); #ifdef _X360 ThreadSetAffinity( h, XBOX_PROCESSOR_3 ); #endif unsigned int nTimeout = 0; while( ThreadWaitForObject( h, true, nTimeout ) == TW_TIMEOUT ) { nTimeout = threadFunc(); } ReleaseThreadHandle( h ); return context.m_hLibrary; #elif POSIX int dlopen_mode = RTLD_NOW; if ( flags & SYS_NOLOAD ) dlopen_mode |= RTLD_NOLOAD; HMODULE ret = ( HMODULE )dlopen( str, dlopen_mode ); if ( !ret && !( flags & SYS_NOLOAD ) ) { const char *pError = dlerror(); if ( pError && ( strstr( pError, "No such file" ) == 0 ) && ( strstr( pError, "image not found" ) == 0 ) ) { Msg( " failed to dlopen %s error=%s\n", str, pError ); } } return ret; #endif }