/* ======================== idParallelJobManagerLocal::Init ======================== */ void idParallelJobManagerLocal::Init() { // on consoles this will have specific cores for the threads, but on PC they will all be CORE_ANY core_t cores[] = JOB_THREAD_CORES; assert( sizeof( cores ) / sizeof( cores[0] ) >= MAX_JOB_THREADS ); for( int i = 0; i < MAX_JOB_THREADS; i++ ) { threads[i].Start( cores[i], i ); } maxThreads = jobs_numThreads.GetInteger(); Sys_CPUCount( numPhysicalCpuCores, numLogicalCpuCores, numCpuPackages ); }
void idGameEdit::RecordPlayback( const usercmd_t &cmd, idEntity *source ) { // Not recording - so instantly exit if( !g_recordPlayback.GetInteger() && !gamePlayback ) { return; } if( !gamePlayback ) { gamePlayback = new rvGamePlayback(); } if( g_recordPlayback.GetInteger() ) { gamePlayback->RecordData( cmd, source ); } else { delete gamePlayback; gamePlayback = NULL; } }
/* ======================== idResolutionScale::GetCurrentResolutionScale ======================== */ void idResolutionScale::GetCurrentResolutionScale( float& x, float& y ) { assert( currentResolution >= MINIMUM_RESOLUTION_SCALE ); assert( currentResolution <= MAXIMUM_RESOLUTION_SCALE ); x = MAXIMUM_RESOLUTION_SCALE; y = MAXIMUM_RESOLUTION_SCALE; // foresthale 2014-05-28: don't allow resolution scaling with editors, we don't really care about framerate and we don't refresh constantly anyway if (com_editors) return; switch( rs_enable.GetInteger() ) { case 0: return; case 1: x = currentResolution; break; case 2: y = currentResolution; break; case 3: { const float middle = ( MINIMUM_RESOLUTION_SCALE + MAXIMUM_RESOLUTION_SCALE ) * 0.5f; if( currentResolution >= middle ) { // First scale horizontally from max to min x = MINIMUM_RESOLUTION_SCALE + ( currentResolution - middle ) * 2.0f; } else { // Then scale vertically from max to min x = MINIMUM_RESOLUTION_SCALE; y = MINIMUM_RESOLUTION_SCALE + ( currentResolution - MINIMUM_RESOLUTION_SCALE ) * 2.0f; } break; } } float forceFrac = rs_forceFractionX.GetFloat(); if( forceFrac > 0.0f && forceFrac <= MAXIMUM_RESOLUTION_SCALE ) { x = forceFrac; } forceFrac = rs_forceFractionY.GetFloat(); if( forceFrac > 0.0f && forceFrac <= MAXIMUM_RESOLUTION_SCALE ) { y = forceFrac; } }
/* ======================== idLobbyBackendDirect::GetConnectInfo ======================== */ lobbyConnectInfo_t idLobbyBackendDirect::GetConnectInfo() { lobbyConnectInfo_t connectInfo; // If we aren't the host, this lobby should have been joined through JoinFromConnectInfo if ( IsHost() ) { // If we are the host, give them our ip address const char * ip = Sys_GetLocalIP( 0 ); Sys_StringToNetAdr( ip, &address, false ); address.port = net_port.GetInteger(); } connectInfo.netAddr = address; return connectInfo; }
void idMultiplayerGame::ReceiveAndPlayVoiceData( const idBitMsg &inMsg ) { int clientNum; if( !gameLocal.serverInfo.GetBool( "si_voiceChat" ) ) { return; } clientNum = inMsg.ReadByte(); soundSystem->PlayVoiceData( clientNum, inMsg.GetReadData(), inMsg.GetRemainingData() ); if( g_voiceChatDebug.GetInteger() & 4 ) { common->Printf( "VC: Playing %d bytes\n", inMsg.GetRemainingData() ); } }
/* ======================== idLobbyBackendDirect::JoinFromConnectInfo ======================== */ void idLobbyBackendDirect::JoinFromConnectInfo( const lobbyConnectInfo_t& connectInfo ) { if( lobbyToSessionCB->CanJoinLocalHost() ) { Sys_StringToNetAdr( "localhost", &address, true ); address.port = net_port.GetInteger(); } else { address = connectInfo.netAddr; } state = STATE_READY; isLocal = false; isHost = false; }
/* ======================== idResolutionScale::GetCurrentResolutionScale ======================== */ void idResolutionScale::GetCurrentResolutionScale( float& x, float& y ) { assert( currentResolution >= MINIMUM_RESOLUTION_SCALE ); assert( currentResolution <= MAXIMUM_RESOLUTION_SCALE ); x = MAXIMUM_RESOLUTION_SCALE; y = MAXIMUM_RESOLUTION_SCALE; switch( rs_enable.GetInteger() ) { case 0: return; case 1: x = currentResolution; break; case 2: y = currentResolution; break; case 3: { const float middle = ( MINIMUM_RESOLUTION_SCALE + MAXIMUM_RESOLUTION_SCALE ) * 0.5f; if( currentResolution >= middle ) { // First scale horizontally from max to min x = MINIMUM_RESOLUTION_SCALE + ( currentResolution - middle ) * 2.0f; } else { // Then scale vertically from max to min x = MINIMUM_RESOLUTION_SCALE; y = MINIMUM_RESOLUTION_SCALE + ( currentResolution - MINIMUM_RESOLUTION_SCALE ) * 2.0f; } break; } } float forceFrac = rs_forceFractionX.GetFloat(); if( forceFrac > 0.0f && forceFrac <= MAXIMUM_RESOLUTION_SCALE ) { x = forceFrac; } forceFrac = rs_forceFractionY.GetFloat(); if( forceFrac > 0.0f && forceFrac <= MAXIMUM_RESOLUTION_SCALE ) { y = forceFrac; } }
static HGLRC CreateOpenGLContextOnDC( const HDC hdc, const bool debugContext ) { HGLRC m_hrc = NULL; int useOpenGL32 = r_useOpenGL32.GetInteger(); for ( int i = 0; i < 2; i++ ) { const int glMajorVersion = ( useOpenGL32 != 0 ) ? 3 : 2; const int glMinorVersion = ( useOpenGL32 != 0 ) ? 2 : 0; const int glDebugFlag = debugContext ? WGL_CONTEXT_DEBUG_BIT_ARB : 0; const int glProfileMask = ( useOpenGL32 != 0 ) ? WGL_CONTEXT_PROFILE_MASK_ARB : 0; const int glProfile = ( useOpenGL32 == 1 ) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : ( ( useOpenGL32 == 2 ) ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : 0 ); const int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, glMajorVersion, WGL_CONTEXT_MINOR_VERSION_ARB, glMinorVersion, WGL_CONTEXT_FLAGS_ARB, glDebugFlag, glProfileMask, glProfile, 0 }; m_hrc = wglCreateContextAttribsARB( hdc, 0, attribs ); if ( m_hrc != NULL ) { idLib::Printf( "created OpenGL %d.%d context\n", glMajorVersion, glMinorVersion ); break; } idLib::Printf( "failed to create OpenGL %d.%d context\n", glMajorVersion, glMinorVersion ); useOpenGL32 = 0; // fall back to OpenGL 2.0 } if ( m_hrc == NULL ) { int err = GetLastError(); switch( err ) { case ERROR_INVALID_VERSION_ARB: idLib::Printf( "ERROR_INVALID_VERSION_ARB\n" ); break; case ERROR_INVALID_PROFILE_ARB: idLib::Printf( "ERROR_INVALID_PROFILE_ARB\n" ); break; default: idLib::Printf( "unknown error: 0x%x\n", err ); break; } } return m_hrc; }
/* ======================== idSoundWorldLocal::UnPause ======================== */ void idSoundWorldLocal::UnPause() { if ( isPaused ) { isPaused = false; accumulatedPauseTime += soundSystemLocal.SoundTime() - pausedTime; pauseFade.SetVolume( DB_SILENCE ); pauseFade.Fade( 0.0f, s_unpauseFadeInTime.GetInteger(), GetSoundTime() ); // just unpause all unmutable voices (normally just voice overs) for ( int e = emitters.Num() - 1; e > 0; e-- ) { for ( int i = 0; i < emitters[e]->channels.Num(); i++ ) { idSoundChannel * channel = emitters[e]->channels[i]; if ( !channel->CanMute() && channel->hardwareVoice != NULL ) { channel->hardwareVoice->UnPause(); } } } } }
/* ======================== idParallelJobManagerLocal::Submit ======================== */ void idParallelJobManagerLocal::Submit( idParallelJobList_Threads* jobList, int parallelism ) { if( jobs_numThreads.IsModified() ) { maxThreads = idMath::ClampInt( 0, MAX_JOB_THREADS, jobs_numThreads.GetInteger() ); jobs_numThreads.ClearModified(); } // determine the number of threads to use int numThreads = maxThreads; if( parallelism == JOBLIST_PARALLELISM_DEFAULT ) { numThreads = maxThreads; } else if( parallelism == JOBLIST_PARALLELISM_MAX_CORES ) { numThreads = numLogicalCpuCores; } else if( parallelism == JOBLIST_PARALLELISM_MAX_THREADS ) { numThreads = MAX_JOB_THREADS; } else if( parallelism > MAX_JOB_THREADS ) { numThreads = MAX_JOB_THREADS; } else { numThreads = parallelism; } if( numThreads <= 0 ) { threadJobListState_t state( jobList->GetVersion() ); jobList->RunJobs( 0, state, false ); return; } for( int i = 0; i < numThreads; i++ ) { threads[i].AddJobList( jobList ); threads[i].SignalWork(); } }
/* ======================== idLobbyBackendDirect::JoinFromConnectInfo ======================== */ void idLobbyBackendDirect::JoinFromConnectInfo( const lobbyConnectInfo_t& connectInfo ) { if( lobbyToSessionCB->CanJoinLocalHost() ) { // TODO: "CanJoinLocalHost" == *must* join LocalHost ?! Sys_StringToNetAdr( "localhost", &address, true ); address.port = net_port.GetInteger(); NET_VERBOSE_PRINT( "NET: idLobbyBackendDirect::JoinFromConnectInfo(): canJoinLocalHost\n" ); } else { address = connectInfo.netAddr; NET_VERBOSE_PRINT( "NET: idLobbyBackendDirect::JoinFromConnectInfo(): %s\n", Sys_NetAdrToString( address ) ); } state = STATE_READY; isLocal = false; isHost = false; }
/* ============================================== idSWFTextInstance::UpdateSubtitle ============================================== */ bool idSWFTextInstance::UpdateSubtitle( int time ) { if ( subForceKillQueued ) { subForceKillQueued = false; subForceKill = true; subKillTimeDelay = time + swf_subtitleExtraTime.GetInteger(); } if ( subUpdating && !subForceKill ) { if ( ( time >= subSwitchTime && !subNeedsSwitch ) || ( !subNeedsSwitch && subInitialLine ) ) { //idLib::Printf( "SWITCH TIME %d / %d \n", time, subSwitchTime ); if ( subInitialLine && subtitleTimingInfo.Num() > 0 ) { if ( subStartTime == -1 ) { subStartTime = time - 600; } if ( time < subStartTime + subtitleTimingInfo[0].startTime ) { return true; } else { text = subtitleText;//subtitleText = ""; subInitialLine = false; } } if ( subNextStartIndex + 1 >= text.Length( ) ) { subForceKillQueued = true; } else { subCharStartIndex = subNextStartIndex; //subtitleText.CopyRange( text, subCharStartIndex, subCharEndIndex ); subNeedsSwitch = true; } } } if ( subForceKill ) { if ( time >= subKillTimeDelay ) { subForceKill = false; return false; } } return true; }
/* ======================== idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsRestartRequired ======================== */ bool idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsRestartRequired() const { if( originalAntialias != r_antiAliasing.GetInteger() ) { return true; } if( originalFramerate != com_engineHz.GetInteger() ) { return true; } if( originalShadowMapping != r_useShadowMapping.GetInteger() ) { return true; } return false; }
/* =============== idCommonLocal::SendSnapshots =============== */ void idCommonLocal::SendSnapshots() { if ( !mapSpawned ) { return; } int currentTime = Sys_Milliseconds(); if ( currentTime < nextSnapshotSendTime ) { return; } idLobbyBase & lobby = session->GetActingGameStateLobbyBase(); if ( !lobby.IsHost() ) { return; } if ( !lobby.HasActivePeers() ) { return; } idSnapShot ss; game->ServerWriteSnapshot( ss ); session->SendSnapshot( ss ); nextSnapshotSendTime = MSEC_ALIGN_TO_FRAME( currentTime + net_snapRate.GetInteger() ); }
/* ======================== idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField ======================== */ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField( const int fieldIndex ) const { switch ( fieldIndex ) { case SYSTEM_FIELD_FULLSCREEN: { const int fullscreen = r_fullscreen.GetInteger(); const int vidmode = r_vidMode.GetInteger(); if ( fullscreen == 0 ) { return "#str_swf_disabled"; } if ( fullscreen < 0 || vidmode < 0 || vidmode >= modeList.Num() ) { return "???"; } if ( modeList[vidmode].displayHz == 60 ) { return va( "%4i x %4i", modeList[vidmode].width, modeList[vidmode].height ); } else { return va( "%4i x %4i @ %dhz", modeList[vidmode].width, modeList[vidmode].height, modeList[vidmode].displayHz ); } } case SYSTEM_FIELD_FRAMERATE: return va( "%d FPS", com_engineHz.GetInteger() ); case SYSTEM_FIELD_VSYNC: if ( r_swapInterval.GetInteger() == 1 ) { return "#str_swf_smart"; } else if ( r_swapInterval.GetInteger() == 2 ) { return "#str_swf_enabled"; } else { return "#str_swf_disabled"; } case SYSTEM_FIELD_ANTIALIASING: if ( r_multiSamples.GetInteger() == 0 ) { return "#str_swf_disabled"; } return va( "%dx", r_multiSamples.GetInteger() ); case SYSTEM_FIELD_MOTIONBLUR: if ( r_motionBlur.GetInteger() == 0 ) { return "#str_swf_disabled"; } return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) ); case SYSTEM_FIELD_LODBIAS: return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f ); case SYSTEM_FIELD_BRIGHTNESS: return LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f ); case SYSTEM_FIELD_VOLUME: { return 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) ); } } return false; }
/* ============== idUsercmdGenLocal::CmdButtons ============== */ void idUsercmdGenLocal::CmdButtons(void) { int i; cmd.buttons = 0; // figure button bits for (i = 0 ; i <= 7 ; i++) { if (ButtonState((usercmdButton_t)(UB_BUTTON0 + i))) { cmd.buttons |= 1 << i; } } // check the attack button if (ButtonState(UB_ATTACK)) { cmd.buttons |= BUTTON_ATTACK; } // check the run button if (toggled_run.on ^(in_alwaysRun.GetBool() && idAsyncNetwork::IsActive())) { cmd.buttons |= BUTTON_RUN; } // check the zoom button if (toggled_zoom.on) { cmd.buttons |= BUTTON_ZOOM; } // check the scoreboard button if (ButtonState(UB_SHOWSCORES) || ButtonState(UB_IMPULSE19)) { // the button is toggled in SP mode as well but without effect cmd.buttons |= BUTTON_SCORES; } // check the mouse look button if (ButtonState(UB_MLOOK) ^ in_freeLook.GetInteger()) { cmd.buttons |= BUTTON_MLOOK; } }
/* ======================== idSessionLocalWin::Connect_f ======================== */ void idSessionLocalWin::Connect_f( const idCmdArgs& args ) { if( args.Argc() < 2 ) { idLib::Printf( "Usage: Connect to IP. Use with net_port. \n" ); return; } Cancel(); if( signInManager->GetMasterLocalUser() == NULL ) { signInManager->RegisterLocalUser( 0 ); } lobbyConnectInfo_t connectInfo; Sys_StringToNetAdr( args.Argv( 1 ), &connectInfo.netAddr, true ); connectInfo.netAddr.port = net_port.GetInteger(); ConnectAndMoveToLobby( GetPartyLobby(), connectInfo, false ); }
/* =============== idCommonLocal::SendUsercmd =============== */ void idCommonLocal::SendUsercmds( int localClientNum ) { if( !mapSpawned ) { return; } int currentTime = Sys_Milliseconds(); if( currentTime < nextUsercmdSendTime ) { return; } idLobbyBase& lobby = session->GetActingGameStateLobbyBase(); if( lobby.IsHost() ) { return; } // We always send the last NUM_USERCMD_SEND usercmds // Which may result in duplicate usercmds being sent in the case of a low net_ucmdRate // But the LZW compressor means the extra usercmds are not large and the redundancy can smooth packet loss byte buffer[idPacketProcessor::MAX_FINAL_PACKET_SIZE]; idBitMsg msg( buffer, sizeof( buffer ) ); idSerializer ser( msg, true ); usercmd_t empty; usercmd_t* last = ∅ usercmd_t* cmdBuffer[NUM_USERCMD_SEND]; const int numCmds = userCmdMgr.GetPlayerCmds( localClientNum, cmdBuffer, NUM_USERCMD_SEND ); msg.WriteByte( numCmds ); for( int i = 0; i < numCmds; i++ ) { cmdBuffer[i]->Serialize( ser, *last ); last = cmdBuffer[i]; } session->SendUsercmds( msg ); nextUsercmdSendTime = MSEC_ALIGN_TO_FRAME( currentTime + net_ucmdRate.GetInteger() ); }
/* ======================== idLobby::DetectSaturation See if the ping shot up, which indicates a previously saturated connection ======================== */ void idLobby::DetectSaturation( int p ) { assert( lobbyType == GetActingGameStateLobbyType() ); peer_t& peer = peers[p]; if( !peer.IsConnected() ) { return; } const float pingIncPercentBeforeThottle = session->GetTitleStorageFloat( "net_pingIncPercentBeforeRecover", net_pingIncPercentBeforeRecover.GetFloat() ); const int pingThreshold = session->GetTitleStorageInt( "net_min_ping_in_ms", net_min_ping_in_ms.GetInteger() ); const int maxFailedPingRecoveries = session->GetTitleStorageInt( "net_maxFailedPingRecoveries", net_maxFailedPingRecoveries.GetInteger() ); const int pingRecoveryThrottleTimeInSeconds = session->GetTitleStorageInt( "net_pingRecoveryThrottleTimeInSeconds", net_pingRecoveryThrottleTimeInSeconds.GetInteger() ); if( peer.lastPingRtt > peer.rightBeforeSnapsPing * pingIncPercentBeforeThottle && peer.lastPingRtt > pingThreshold ) { if( peer.failedPingRecoveries < maxFailedPingRecoveries ) { ThrottleSnapsForXSeconds( p, pingRecoveryThrottleTimeInSeconds, true ); } } }
/* ============= Sys_Error Show the early console as an error dialog ============= */ void Sys_Error( const char *error, ... ) { va_list argptr; char text[4096]; MSG msg; va_start( argptr, error ); vsprintf( text, error, argptr ); va_end( argptr); Conbuf_AppendText( text ); Conbuf_AppendText( "\n" ); Win_SetErrorText( text ); Sys_ShowConsole( 1, true ); timeEndPeriod( 1 ); Sys_ShutdownInput(); GLimp_Shutdown(); extern idCVar com_productionMode; if ( com_productionMode.GetInteger() == 0 ) { // wait for the user to quit while ( 1 ) { if ( !GetMessage( &msg, NULL, 0, 0 ) ) { common->Quit(); } TranslateMessage( &msg ); DispatchMessage( &msg ); } } Sys_DestroyConsole(); exit (1); }
/* ======================== idResolutionScale::GetConsoleText ======================== */ void idResolutionScale::GetConsoleText( idStr& s ) { float x; float y; if( rs_enable.GetInteger() == 0 ) { s = "rs-off"; return; } GetCurrentResolutionScale( x, y ); if( rs_display.GetInteger() > 0 ) { x *= 1280.0f; y *= 720.0f; if( rs_enable.GetInteger() == 1 ) { y = 1.0f; } else if( rs_enable.GetInteger() == 2 ) { x = 1.0f; } s = va( "rs-pixels %i", idMath::Ftoi( x * y ) ); } else { if( rs_enable.GetInteger() == 3 ) { s = va( "%2i%%h,%2i%%v", idMath::Ftoi( 100.0f * x ), idMath::Ftoi( 100.0f * y ) ); } else { s = va( "%2i%%%s", ( rs_enable.GetInteger() == 1 ) ? idMath::Ftoi( 100.0f * x ) : idMath::Ftoi( 100.0f * y ), ( rs_enable.GetInteger() == 1 ) ? "h" : "v" ); } } }
/* ======================== idSoundHardware_XAudio2::Update ======================== */ void idSoundHardware_XAudio2::Update() { if( pXAudio2 == NULL ) { int nowTime = Sys_Milliseconds(); if( lastResetTime + 1000 < nowTime ) { lastResetTime = nowTime; Init(); } return; } if( soundSystem->IsMuted() ) { pMasterVoice->SetVolume( 0.0f, OPERATION_SET ); } else { pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ), OPERATION_SET ); } pXAudio2->CommitChanges( XAUDIO2_COMMIT_ALL ); // IXAudio2SourceVoice::Stop() has been called for every sound on the // zombie list, but it is documented as asyncronous, so we have to wait // until it actually reports that it is no longer playing. for( int i = 0; i < zombieVoices.Num(); i++ ) { zombieVoices[i]->FlushSourceBuffers(); if( !zombieVoices[i]->IsPlaying() ) { freeVoices.Append( zombieVoices[i] ); zombieVoices.RemoveIndexFast( i ); i--; } else { static int playingZombies; playingZombies++; } } if( s_showPerfData.GetBool() ) { XAUDIO2_PERFORMANCE_DATA perfData; pXAudio2->GetPerformanceData( &perfData ); idLib::Printf( "Voices: %d/%d CPU: %.2f%% Mem: %dkb\n", perfData.ActiveSourceVoiceCount, perfData.TotalSourceVoiceCount, perfData.AudioCyclesSinceLastQuery / ( float )perfData.TotalCyclesSinceLastQuery, perfData.MemoryUsageInBytes / 1024 ); } if( vuMeterRMS == NULL ) { // Init probably hasn't been called yet return; } vuMeterRMS->Enable( s_showLevelMeter.GetBool() ); vuMeterPeak->Enable( s_showLevelMeter.GetBool() ); if( !s_showLevelMeter.GetBool() ) { pMasterVoice->DisableEffect( 0 ); return; } else { pMasterVoice->EnableEffect( 0 ); } float peakLevels[ 8 ]; float rmsLevels[ 8 ]; XAUDIO2FX_VOLUMEMETER_LEVELS levels; levels.ChannelCount = outputChannels; levels.pPeakLevels = peakLevels; levels.pRMSLevels = rmsLevels; if( levels.ChannelCount > 8 ) { levels.ChannelCount = 8; } pMasterVoice->GetEffectParameters( 0, &levels, sizeof( levels ) ); int currentTime = Sys_Milliseconds(); for( int i = 0; i < outputChannels; i++ ) { if( vuMeterPeakTimes[i] < currentTime ) { vuMeterPeak->SetValue( i, vuMeterPeak->GetValue( i ) * 0.9f, colorRed ); } } float width = 20.0f; float height = 200.0f; float left = 100.0f; float top = 100.0f; sscanf( s_meterPosition.GetString(), "%f %f %f %f", &left, &top, &width, &height ); vuMeterRMS->SetPosition( left, top, width * levels.ChannelCount, height ); vuMeterPeak->SetPosition( left, top, width * levels.ChannelCount, height ); for( uint32 i = 0; i < levels.ChannelCount; i++ ) { vuMeterRMS->SetValue( i, rmsLevels[ i ], idVec4( 0.5f, 1.0f, 0.0f, 1.00f ) ); if( peakLevels[ i ] >= vuMeterPeak->GetValue( i ) ) { vuMeterPeak->SetValue( i, peakLevels[ i ], colorRed ); vuMeterPeakTimes[i] = currentTime + s_meterTopTime.GetInteger(); } } }
/* ======================== idSoundHardware_XAudio2::Init ======================== */ void idSoundHardware_XAudio2::Init() { cmdSystem->AddCommand( "listDevices", listDevices_f, 0, "Lists the connected sound devices", NULL ); DWORD xAudioCreateFlags = 0; // RB: not available on Windows 8 SDK #if !defined(USE_WINRT) && defined(_DEBUG) // (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG) xAudioCreateFlags |= XAUDIO2_DEBUG_ENGINE; #endif // RB end XAUDIO2_PROCESSOR xAudioProcessor = XAUDIO2_DEFAULT_PROCESSOR; // RB: not available on Windows 8 SDK if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) ) { #if !defined(USE_WINRT) && defined(_DEBUG) // (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG) if( xAudioCreateFlags & XAUDIO2_DEBUG_ENGINE ) { // in case the debug engine isn't installed xAudioCreateFlags &= ~XAUDIO2_DEBUG_ENGINE; if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) ) { idLib::FatalError( "Failed to create XAudio2 engine. Try installing the latest DirectX." ); return; } } else #endif // RB end { idLib::FatalError( "Failed to create XAudio2 engine. Try installing the latest DirectX." ); return; } } #ifdef _DEBUG XAUDIO2_DEBUG_CONFIGURATION debugConfiguration = { 0 }; debugConfiguration.TraceMask = XAUDIO2_LOG_WARNINGS; debugConfiguration.BreakMask = XAUDIO2_LOG_ERRORS; pXAudio2->SetDebugConfiguration( &debugConfiguration ); #endif // Register the sound engine callback pXAudio2->RegisterForCallbacks( &soundEngineCallback ); soundEngineCallback.hardware = this; UINT32 deviceCount = 0; DWORD outputSampleRate = 44100; // Max( (DWORD)XAUDIO2FX_REVERB_MIN_FRAMERATE, Min( (DWORD)XAUDIO2FX_REVERB_MAX_FRAMERATE, deviceDetails.OutputFormat.Format.nSamplesPerSec ) ); // RB: not available on Windows 8 SDK #if defined(USE_WINRT) //(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) IMMDeviceEnumerator* immDevEnum = nullptr; IMMDeviceCollection* immDevCollection = nullptr; IMMDevice* immDev = nullptr; std::vector<AudioDevice> vAudioDevices; HRESULT hResult = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), ( void** ) &immDevEnum ); if( FAILED( hResult ) ) { idLib::Warning( "Failed to get audio enumerator" ); pXAudio2->Release(); pXAudio2 = NULL; return; } hResult = immDevEnum->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &immDevCollection ); if( FAILED( hResult ) ) { idLib::Warning( "Failed to get audio endpoints" ); pXAudio2->Release(); pXAudio2 = NULL; return; } hResult = immDevCollection->GetCount( &deviceCount ); if( FAILED( hResult ) ) { idLib::Warning( "No audio devices found" ); pXAudio2->Release(); pXAudio2 = NULL; return; } for( UINT i = 0; i < deviceCount; i++ ) { IPropertyStore* propStore = nullptr; PROPVARIANT varName; PROPVARIANT varId; PropVariantInit( &varId ); PropVariantInit( &varName ); hResult = immDevCollection->Item( i, &immDev ); if( SUCCEEDED( hResult ) ) { hResult = immDev->OpenPropertyStore( STGM_READ, &propStore ); } if( SUCCEEDED( hResult ) ) { hResult = propStore->GetValue( PKEY_AudioEndpoint_Path, &varId ); } if( SUCCEEDED( hResult ) ) { hResult = propStore->GetValue( PKEY_Device_FriendlyName, &varName ); } if( SUCCEEDED( hResult ) ) { assert( varId.vt == VT_LPWSTR ); assert( varName.vt == VT_LPWSTR ); // Now save somewhere the device display name & id AudioDevice ad; ad.name = varName.pwszVal; ad.id = varId.pwszVal; vAudioDevices.push_back( ad ); } PropVariantClear( &varName ); PropVariantClear( &varId ); if( propStore != nullptr ) { propStore->Release(); } if( immDev != nullptr ) { immDev->Release(); } } immDevCollection->Release(); immDevEnum->Release(); int preferredDevice = s_device.GetInteger(); if( !vAudioDevices.empty() ) { if( SUCCEEDED( pXAudio2->CreateMasteringVoice( &pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, outputSampleRate, 0, vAudioDevices.at( 0 ).id.c_str(), NULL, AudioCategory_GameEffects ) ) ) { XAUDIO2_VOICE_DETAILS deviceDetails; pMasterVoice->GetVoiceDetails( &deviceDetails ); pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) ); outputChannels = deviceDetails.InputChannels; DWORD win8_channelMask; pMasterVoice->GetChannelMask( &win8_channelMask ); channelMask = ( unsigned int )win8_channelMask; idLib::Printf( "Using device %s\n", vAudioDevices.at( 0 ).name ); } else { idLib::Warning( "Failed to create master voice" ); pXAudio2->Release(); pXAudio2 = NULL; return; } } #else if( pXAudio2->GetDeviceCount( &deviceCount ) != S_OK || deviceCount == 0 ) { idLib::Warning( "No audio devices found" ); pXAudio2->Release(); pXAudio2 = NULL; return; } idCmdArgs args; listDevices_f( args ); int preferredDevice = s_device.GetInteger(); if( preferredDevice < 0 || preferredDevice >= ( int )deviceCount ) { int preferredChannels = 0; for( unsigned int i = 0; i < deviceCount; i++ ) { XAUDIO2_DEVICE_DETAILS deviceDetails; if( pXAudio2->GetDeviceDetails( i, &deviceDetails ) != S_OK ) { continue; } if( deviceDetails.Role & DefaultGameDevice ) { // if we find a device the user marked as their preferred 'game' device, then always use that preferredDevice = i; preferredChannels = deviceDetails.OutputFormat.Format.nChannels; break; } if( deviceDetails.OutputFormat.Format.nChannels > preferredChannels ) { preferredDevice = i; preferredChannels = deviceDetails.OutputFormat.Format.nChannels; } } } idLib::Printf( "Using device %d\n", preferredDevice ); XAUDIO2_DEVICE_DETAILS deviceDetails; if( pXAudio2->GetDeviceDetails( preferredDevice, &deviceDetails ) != S_OK ) { // One way this could happen is if a device is removed between the loop and this line of code // Highly unlikely but possible idLib::Warning( "Failed to get device details" ); pXAudio2->Release(); pXAudio2 = NULL; return; } if( FAILED( pXAudio2->CreateMasteringVoice( &pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, outputSampleRate, 0, preferredDevice, NULL ) ) ) { idLib::Warning( "Failed to create master voice" ); pXAudio2->Release(); pXAudio2 = NULL; return; } pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) ); outputChannels = deviceDetails.OutputFormat.Format.nChannels; channelMask = deviceDetails.OutputFormat.dwChannelMask; #endif // #if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) idSoundVoice::InitSurround( outputChannels, channelMask ); // --------------------- // Create VU Meter Effect // --------------------- IUnknown* vuMeter = NULL; XAudio2CreateVolumeMeter( &vuMeter, 0 ); XAUDIO2_EFFECT_DESCRIPTOR descriptor; descriptor.InitialState = true; descriptor.OutputChannels = outputChannels; descriptor.pEffect = vuMeter; XAUDIO2_EFFECT_CHAIN chain; chain.EffectCount = 1; chain.pEffectDescriptors = &descriptor; pMasterVoice->SetEffectChain( &chain ); vuMeter->Release(); // --------------------- // Create VU Meter Graph // --------------------- vuMeterRMS = console->CreateGraph( outputChannels ); vuMeterPeak = console->CreateGraph( outputChannels ); // DG: make sure they're not NULL (as it's currently the case with the cegui-based console) if( vuMeterRMS && vuMeterPeak ) { vuMeterRMS->Enable( false ); vuMeterPeak->Enable( false ); memset( vuMeterPeakTimes, 0, sizeof( vuMeterPeakTimes ) ); vuMeterPeak->SetFillMode( idDebugGraph::GRAPH_LINE ); vuMeterPeak->SetBackgroundColor( idVec4( 0.0f, 0.0f, 0.0f, 0.0f ) ); vuMeterRMS->AddGridLine( 0.500f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) ); vuMeterRMS->AddGridLine( 0.250f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) ); vuMeterRMS->AddGridLine( 0.125f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) ); const char* channelNames[] = { "L", "R", "C", "S", "Lb", "Rb", "Lf", "Rf", "Cb", "Ls", "Rs" }; for( int i = 0, ci = 0; ci < sizeof( channelNames ) / sizeof( channelNames[0] ); ci++ ) { if( ( channelMask & BIT( ci ) ) == 0 ) { continue; } vuMeterRMS->SetLabel( i, channelNames[ci] ); i++; } } // --------------------- // Create submix buffer // --------------------- if( FAILED( pXAudio2->CreateSubmixVoice( &pSubmixVoice, 1, outputSampleRate, 0, 0, NULL, NULL ) ) ) { idLib::FatalError( "Failed to create submix voice" ); } // XAudio doesn't really impose a maximum number of voices voices.SetNum( voices.Max() ); freeVoices.SetNum( voices.Max() ); zombieVoices.SetNum( 0 ); for( int i = 0; i < voices.Num(); i++ ) { freeVoices[i] = &voices[i]; } // RB end }
/* ================ idServerScan::IsFiltered ================ */ bool idServerScan::IsFiltered( const networkServer_t server ) { int i; const idKeyValue *keyval; // OS support filter #if 0 // filter out pure servers that won't provide checksumed game code for client OS keyval = server.serverInfo.FindKey( "si_pure" ); if( keyval && !idStr::Cmp( keyval->GetValue(), "1" ) ) { if( ( server.OSMask & ( 1 << BUILD_OS_ID ) ) == 0 ) { return true; } } #else if( ( server.OSMask & ( 1 << BUILD_OS_ID ) ) == 0 ) { return true; } #endif // password filter keyval = server.serverInfo.FindKey( "si_usePass" ); if( keyval && gui_filter_password.GetInteger() == 1 ) { // show passworded only if( keyval->GetValue() [0] == '0' ) { return true; } } else if( keyval && gui_filter_password.GetInteger() == 2 ) { // show no password only if( keyval->GetValue() [0] != '0' ) { return true; } } // players filter keyval = server.serverInfo.FindKey( "si_maxPlayers" ); if( keyval ) { if( gui_filter_players.GetInteger() == 1 && server.clients == atoi( keyval->GetValue() ) ) { return true; } else if( gui_filter_players.GetInteger() == 2 && ( !server.clients || server.clients == atoi( keyval->GetValue() ) ) ) { return true; } } // gametype filter keyval = server.serverInfo.FindKey( "si_gameType" ); if( keyval && gui_filter_gameType.GetInteger() ) { i = 0; while( l_gameTypes[i] ) { if( !keyval->GetValue().Icmp( l_gameTypes[i] ) ) { break; } i++; } if( l_gameTypes[i] && i != gui_filter_gameType.GetInteger() - 1 ) { return true; } } // idle server filter keyval = server.serverInfo.FindKey( "si_idleServer" ); if( keyval && !gui_filter_idle.GetInteger() ) { if( !keyval->GetValue().Icmp( "1" ) ) { return true; } } // autofilter D3XP games if the user does not has the XP installed if( !fileSystem->HasD3XP() && !idStr::Icmp( server.serverInfo.GetString( "fs_game" ), "d3xp" ) ) { return true; } // filter based on the game doom or XP if( gui_filter_game.GetInteger() == 1 ) //Only Doom { if( idStr::Icmp( server.serverInfo.GetString( "fs_game" ), "" ) ) { return true; } } else if( gui_filter_game.GetInteger() == 2 ) //Only D3XP { if( idStr::Icmp( server.serverInfo.GetString( "fs_game" ), "d3xp" ) ) { return true; } } return false; }
/* ======================== idLobby::PickNewHostInternal ======================== */ void idLobby::PickNewHostInternal( bool forceMe, bool inviteOldHost ) { if( migrationInfo.state == MIGRATE_PICKING_HOST ) { return; // Already picking new host } idLib::Printf( "PickNewHost: Started picking new host %s.\n", GetLobbyName() ); if( IsHost() ) { idLib::Printf( "PickNewHost: Already host of session %s\n", GetLobbyName() ); return; } // Find the user with the lowest ping int bestUserIndex = -1; int bestPingMs = 0; lobbyUserID_t bestUserId; for( int i = 0; i < GetNumLobbyUsers(); i++ ) { lobbyUser_t* user = GetLobbyUser( i ); if( !verify( user != NULL ) ) { continue; } if( user->IsDisconnected() ) { continue; } if( user->peerIndex == -1 ) { continue; // Don't try and pick old host } if( bestUserIndex == -1 || IsBetterHost( user->pingMs, user->lobbyUserID, bestPingMs, bestUserId ) ) { bestUserIndex = i; bestPingMs = user->pingMs; bestUserId = user->lobbyUserID; } if( user->peerIndex == net_migration_forcePeerAsHost.GetInteger() ) { bestUserIndex = i; bestPingMs = user->pingMs; bestUserId = user->lobbyUserID; break; } } // Remember when we first started picking a new host migrationInfo.state = MIGRATE_PICKING_HOST; migrationInfo.migrationStartTime = Sys_Milliseconds(); migrationInfo.persistUntilGameEndsData.wasMigratedGame = sessionCB->GetState() == idSession::INGAME; if( bestUserIndex == -1 ) // This can happen if we call PickNewHost on an lobby that was Shutdown { NET_VERBOSE_PRINT( "MIGRATION: PickNewHost was called on an lobby that was Shutdown\n" ); BecomeHost(); return; } NET_VERBOSE_PRINT( "MIGRATION: Chose user index %d (%s) for new host\n", bestUserIndex, GetLobbyUser( bestUserIndex )->gamertag ); bool bestWasLocal = IsSessionUserIndexLocal( bestUserIndex ); // Check before shutting down the lobby migrateMsgFlags = parms.matchFlags; // Save off match parms // Build invite list BuildMigrationInviteList( inviteOldHost ); // If the best user is on this machine, then we become the host now, otherwise, wait for a new host to contact us if( forceMe || bestWasLocal ) { BecomeHost(); } }
/* ======================== NET_OpenSocks ======================== */ void NET_OpenSocks( int port ) { sockaddr_in address; struct hostent* h; int len; bool rfc1929; unsigned char buf[64]; usingSocks = false; idLib::Printf( "Opening connection to SOCKS server.\n" ); if( ( socks_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == INVALID_SOCKET ) { idLib::Printf( "WARNING: NET_OpenSocks: socket: %s\n", NET_ErrorString() ); return; } h = gethostbyname( net_socksServer.GetString() ); if( h == NULL ) { idLib::Printf( "WARNING: NET_OpenSocks: gethostbyname: %s\n", NET_ErrorString() ); return; } if( h->h_addrtype != AF_INET ) { idLib::Printf( "WARNING: NET_OpenSocks: gethostbyname: address type was not AF_INET\n" ); return; } address.sin_family = AF_INET; address.sin_addr.s_addr = *( in_addr_t* )h->h_addr_list[0]; address.sin_port = htons( ( short )net_socksPort.GetInteger() ); if( connect( socks_socket, ( sockaddr* )&address, sizeof( address ) ) == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: connect: %s\n", NET_ErrorString() ); return; } // send socks authentication handshake if( *net_socksUsername.GetString() || *net_socksPassword.GetString() ) { rfc1929 = true; } else { rfc1929 = false; } buf[0] = 5; // SOCKS version // method count if( rfc1929 ) { buf[1] = 2; len = 4; } else { buf[1] = 1; len = 3; } buf[2] = 0; // method #1 - method id #00: no authentication if( rfc1929 ) { buf[2] = 2; // method #2 - method id #02: username/password } if( send( socks_socket, ( const char* )buf, len, 0 ) == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); return; } // get the response len = recv( socks_socket, ( char* )buf, 64, 0 ); if( len == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); return; } if( len != 2 || buf[0] != 5 ) { idLib::Printf( "NET_OpenSocks: bad response\n" ); return; } switch( buf[1] ) { case 0: // no authentication break; case 2: // username/password authentication break; default: idLib::Printf( "NET_OpenSocks: request denied\n" ); return; } // do username/password authentication if needed if( buf[1] == 2 ) { int ulen; int plen; // build the request ulen = idStr::Length( net_socksUsername.GetString() ); plen = idStr::Length( net_socksPassword.GetString() ); buf[0] = 1; // username/password authentication version buf[1] = ulen; if( ulen ) { memcpy( &buf[2], net_socksUsername.GetString(), ulen ); } buf[2 + ulen] = plen; if( plen ) { memcpy( &buf[3 + ulen], net_socksPassword.GetString(), plen ); } // send it if( send( socks_socket, ( const char* )buf, 3 + ulen + plen, 0 ) == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); return; } // get the response len = recv( socks_socket, ( char* )buf, 64, 0 ); if( len == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); return; } if( len != 2 || buf[0] != 1 ) { idLib::Printf( "NET_OpenSocks: bad response\n" ); return; } if( buf[1] != 0 ) { idLib::Printf( "NET_OpenSocks: authentication failed\n" ); return; } } // send the UDP associate request buf[0] = 5; // SOCKS version buf[1] = 3; // command: UDP associate buf[2] = 0; // reserved buf[3] = 1; // address type: IPV4 *( int* )&buf[4] = INADDR_ANY; *( short* )&buf[8] = htons( ( short )port ); // port if( send( socks_socket, ( const char* )buf, 10, 0 ) == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); return; } // get the response len = recv( socks_socket, ( char* )buf, 64, 0 ); if( len == SOCKET_ERROR ) { idLib::Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); return; } if( len < 2 || buf[0] != 5 ) { idLib::Printf( "NET_OpenSocks: bad response\n" ); return; } // check completion code if( buf[1] != 0 ) { idLib::Printf( "NET_OpenSocks: request denied: %i\n", buf[1] ); return; } if( buf[3] != 1 ) { idLib::Printf( "NET_OpenSocks: relay address is not IPV4: %i\n", buf[3] ); return; } socksRelayAddr.sin_family = AF_INET; socksRelayAddr.sin_addr.s_addr = *( int* )&buf[4]; socksRelayAddr.sin_port = *( short* )&buf[8]; memset( socksRelayAddr.sin_zero, 0, sizeof( socksRelayAddr.sin_zero ) ); usingSocks = true; }
/* ======================== idMenuScreen_Shell_Root::ShowScreen ======================== */ void idMenuScreen_Shell_Root::ShowScreen( const mainMenuTransition_t transitionType ) { if ( menuData != NULL && menuData->GetPlatform() != 2 ) { idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > menuOptions; idList< idStr > option; int index = 0; if ( g_demoMode.GetBool() ) { idMenuWidget_Button * buttonWidget = NULL; option.Append( "START DEMO" ); // START DEMO menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_START_DEMO ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "Launch the demo" ); } index++; if ( g_demoMode.GetInteger() == 2 ) { option.Clear(); option.Append( "START PRESS DEMO" ); // START DEMO menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_START_DEMO2 ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "Launch the press demo" ); } index++; } option.Clear(); option.Append( "#str_swf_settings" ); // settings menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_SETTINGS ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_02206" ); } index++; option.Clear(); option.Append( "#str_swf_quit" ); // quit menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_QUIT ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_01976" ); } index++; } else { idMenuWidget_Button * buttonWidget = NULL; #if !defined ( ID_RETAIL ) option.Append( "DEV" ); // DEV menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_DEV ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "View a list of maps available for play" ); } index++; #endif option.Clear(); option.Append( "#str_swf_campaign" ); // singleplayer menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_CAMPAIGN ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_swf_campaign_desc" ); } index++; option.Clear(); option.Append( "#str_swf_multiplayer" ); // multiplayer menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_MULTIPLAYER ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_02215" ); } index++; option.Clear(); option.Append( "#str_swf_settings" ); // settings menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_SETTINGS ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_02206" ); } index++; option.Clear(); option.Append( "#str_swf_credits" ); // credits menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_CREDITS ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_02219" ); } index++; // only add quit option for PC option.Clear(); option.Append( "#str_swf_quit" ); // quit menuOptions.Append( option ); options->GetChildByIndex( index ).ClearEventActions(); options->GetChildByIndex( index ).AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, ROOT_CMD_QUIT ); buttonWidget = dynamic_cast< idMenuWidget_Button * >( &options->GetChildByIndex( index ) ); if ( buttonWidget != NULL ) { buttonWidget->SetDescription( "#str_01976" ); } index++; } options->SetListData( menuOptions ); } else { idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > menuOptions; options->SetListData( menuOptions ); } idMenuScreen::ShowScreen( transitionType ); if ( menuData != NULL && menuData->GetPlatform() == 2 ) { idMenuHandler_Shell * shell = dynamic_cast< idMenuHandler_Shell * >( menuData ); if ( shell != NULL ) { idMenuWidget_MenuBar * menuBar = shell->GetMenuBar(); if ( menuBar != NULL ) { menuBar->SetFocusIndex( GetRootIndex() ); } } } }
/* ================= idUsercmdGenLocal::MouseMove ================= */ void idUsercmdGenLocal::MouseMove( void ) { float mx, my, strafeMx, strafeMy; static int history[8][2]; static int historyCounter; int i; history[historyCounter&7][0] = mouseDx; history[historyCounter&7][1] = mouseDy; // allow mouse movement to be smoothed together int smooth = m_smooth.GetInteger(); if ( smooth < 1 ) { smooth = 1; } if ( smooth > 8 ) { smooth = 8; } mx = 0; my = 0; for ( i = 0 ; i < smooth ; i++ ) { mx += history[ ( historyCounter - i + 8 ) & 7 ][0]; my += history[ ( historyCounter - i + 8 ) & 7 ][1]; } mx /= smooth; my /= smooth; // use a larger smoothing for strafing smooth = m_strafeSmooth.GetInteger(); if ( smooth < 1 ) { smooth = 1; } if ( smooth > 8 ) { smooth = 8; } strafeMx = 0; strafeMy = 0; for ( i = 0 ; i < smooth ; i++ ) { strafeMx += history[ ( historyCounter - i + 8 ) & 7 ][0]; strafeMy += history[ ( historyCounter - i + 8 ) & 7 ][1]; } strafeMx /= smooth; strafeMy /= smooth; historyCounter++; if ( idMath::Fabs( mx ) > 1000 || idMath::Fabs( my ) > 1000 ) { Sys_DebugPrintf( "idUsercmdGenLocal::MouseMove: Ignoring ridiculous mouse delta.\n" ); mx = my = 0; } mx *= sensitivity.GetFloat(); my *= sensitivity.GetFloat(); if ( m_showMouseRate.GetBool() ) { Sys_DebugPrintf( "[%3i %3i = %5.1f %5.1f = %5.1f %5.1f] ", mouseDx, mouseDy, mx, my, strafeMx, strafeMy ); } mouseDx = 0; mouseDy = 0; if ( !strafeMx && !strafeMy ) { return; } if ( ButtonState( UB_STRAFE ) || !( cmd.buttons & BUTTON_MLOOK ) ) { // add mouse X/Y movement to cmd strafeMx *= m_strafeScale.GetFloat(); strafeMy *= m_strafeScale.GetFloat(); // clamp as a vector, instead of separate floats float len = sqrt( strafeMx * strafeMx + strafeMy * strafeMy ); if ( len > 127 ) { strafeMx = strafeMx * 127 / len; strafeMy = strafeMy * 127 / len; } } if ( !ButtonState( UB_STRAFE ) ) { viewangles[YAW] -= m_yaw.GetFloat() * mx; } else { cmd.rightmove = idMath::ClampChar( (int)(cmd.rightmove + strafeMx) ); } if ( !ButtonState( UB_STRAFE ) && ( cmd.buttons & BUTTON_MLOOK ) ) { viewangles[PITCH] += m_pitch.GetFloat() * my; } else { cmd.forwardmove = idMath::ClampChar( (int)(cmd.forwardmove - strafeMy) ); } }
/* ======================== idMenuScreen_Shell_PartyLobby::HandleAction h ======================== */ bool idMenuScreen_Shell_PartyLobby::HandleAction( idWidgetAction& action, const idWidgetEvent& event, idMenuWidget* widget, bool forceHandled ) { if( menuData == NULL ) { return true; } if( menuData->ActiveScreen() != SHELL_AREA_PARTY_LOBBY ) { return false; } widgetAction_t actionType = action.GetType(); const idSWFParmList& parms = action.GetParms(); switch( actionType ) { case WIDGET_ACTION_JOY4_ON_PRESS: { idLobbyBase& activeLobby = session->GetPartyLobbyBase(); lobbyUserID_t luid; if( CanKickSelectedPlayer( luid ) ) { activeLobby.KickLobbyUser( luid ); } return true; } case WIDGET_ACTION_GO_BACK: { class idSWFScriptFunction_Accept : public idSWFScriptFunction_RefCounted { public: idSWFScriptFunction_Accept() { } idSWFScriptVar Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { common->Dialog().ClearDialog( GDM_LEAVE_LOBBY_RET_MAIN ); session->Cancel(); return idSWFScriptVar(); } }; class idSWFScriptFunction_Cancel : public idSWFScriptFunction_RefCounted { public: idSWFScriptFunction_Cancel() { } idSWFScriptVar Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { common->Dialog().ClearDialog( GDM_LEAVE_LOBBY_RET_MAIN ); return idSWFScriptVar(); } }; idLobbyBase& activeLobby = session->GetActivePlatformLobbyBase(); if( activeLobby.GetNumActiveLobbyUsers() > 1 ) { common->Dialog().AddDialog( GDM_LEAVE_LOBBY_RET_MAIN, DIALOG_ACCEPT_CANCEL, new( TAG_SWF ) idSWFScriptFunction_Accept(), new( TAG_SWF ) idSWFScriptFunction_Cancel(), false ); } else { session->Cancel(); } return true; } case WIDGET_ACTION_MUTE_PLAYER: { if( parms.Num() != 1 ) { return true; } int index = parms[0].ToInteger(); idLobbyBase& activeLobby = session->GetPartyLobbyBase(); lobbyUserID_t luid = activeLobby.GetLobbyUserIdByOrdinal( index ); if( luid.IsValid() ) { session->ToggleLobbyUserVoiceMute( luid ); } return true; } case WIDGET_ACTION_COMMAND: { if( options == NULL ) { return true; } int selectionIndex = options->GetFocusIndex(); if( parms.Num() > 1 ) { selectionIndex = parms[1].ToInteger(); } if( selectionIndex != options->GetFocusIndex() ) { options->SetViewIndex( options->GetViewOffset() + selectionIndex ); options->SetFocusIndex( selectionIndex ); } switch( parms[0].ToInteger() ) { case PARTY_CMD_QUICK: { idMatchParameters matchParameters = idMatchParameters( session->GetPartyLobbyBase().GetMatchParms() ); // Reset these to random for quick match. matchParameters.gameMap = GAME_MAP_RANDOM; matchParameters.gameMode = GAME_MODE_RANDOM; // Always a public match. matchParameters.matchFlags &= ~MATCH_INVITE_ONLY; session->UpdatePartyParms( matchParameters ); // Update flags for game lobby. matchParameters.matchFlags = DefaultPartyFlags | DefaultPublicGameFlags; cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO, matchParameters.serverInfo ); // Force a default value for the si_timelimit and si_fraglimit for quickmatch matchParameters.serverInfo.SetInt( "si_timelimit", 15 ); matchParameters.serverInfo.SetInt( "si_fraglimit", 10 ); session->FindOrCreateMatch( matchParameters ); break; } case PARTY_CMD_FIND: { menuData->SetNextScreen( SHELL_AREA_MODE_SELECT, MENU_TRANSITION_SIMPLE ); break; } case PARTY_CMD_CREATE: { idMatchParameters matchParameters = idMatchParameters( session->GetPartyLobbyBase().GetMatchParms() ); const bool isInviteOnly = MatchTypeInviteOnly( matchParameters.matchFlags ); matchParameters.matchFlags = DefaultPartyFlags | DefaultPrivateGameFlags; if( isInviteOnly ) { matchParameters.matchFlags |= MATCH_INVITE_ONLY; } int mode = idMath::ClampInt( -1, GAME_COUNT - 1, si_mode.GetInteger() ); const idList< mpMap_t > maps = common->GetMapList(); int map = idMath::ClampInt( -1, maps.Num() - 1, si_map.GetInteger() ); matchParameters.gameMap = map; matchParameters.gameMode = mode; cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO, matchParameters.serverInfo ); session->CreateMatch( matchParameters ); break; } case PARTY_CMD_PWF: { menuData->SetNextScreen( SHELL_AREA_BROWSER, MENU_TRANSITION_SIMPLE ); break; } case PARTY_CMD_LEADERBOARDS: { ShowLeaderboards(); break; } case PARTY_CMD_TOGGLE_PRIVACY: { idMatchParameters matchParameters = idMatchParameters( session->GetPartyLobbyBase().GetMatchParms() ); matchParameters.matchFlags ^= MATCH_INVITE_ONLY; session->UpdatePartyParms( matchParameters ); int bitSet = ( matchParameters.matchFlags & MATCH_INVITE_ONLY ); net_inviteOnly.SetBool( bitSet != 0 ? true : false ); break; } case PARTY_CMD_SHOW_PARTY_GAMES: { session->ShowPartySessions(); break; } case PARTY_CMD_INVITE: { if( session->GetPartyLobbyBase().IsLobbyFull() ) { common->Dialog().AddDialog( GDM_CANNOT_INVITE_LOBBY_FULL, DIALOG_CONTINUE, NULL, NULL, true, __FUNCTION__, __LINE__, false ); return true; } InvitePartyOrFriends(); break; } } return true; } case WIDGET_ACTION_START_REPEATER: { if( options == NULL ) { return true; } if( parms.Num() == 4 ) { int selectionIndex = parms[3].ToInteger(); if( selectionIndex != options->GetFocusIndex() ) { options->SetViewIndex( options->GetViewOffset() + selectionIndex ); options->SetFocusIndex( selectionIndex ); } } break; } case WIDGET_ACTION_SELECT_GAMERTAG: { int selectionIndex = lobby->GetFocusIndex(); if( parms.Num() > 0 ) { selectionIndex = parms[0].ToInteger(); } if( selectionIndex != lobby->GetFocusIndex() ) { lobby->SetViewIndex( lobby->GetViewOffset() + selectionIndex ); lobby->SetFocusIndex( selectionIndex ); return true; } idLobbyBase& activeLobby = session->GetPartyLobbyBase(); lobbyUserID_t luid = activeLobby.GetLobbyUserIdByOrdinal( selectionIndex ); if( luid.IsValid() ) { session->ShowLobbyUserGamerCardUI( luid ); } return true; } } return idMenuWidget::HandleAction( action, event, widget, forceHandled ); }
bool RB_RenderShadowMaps( viewLight_t* vLight ) { const idMaterial* lightShader = vLight->lightShader; if (lightShader->IsFogLight() || lightShader->IsBlendLight()) { return true; } if (!vLight->localInteractions && !vLight->globalInteractions && !vLight->translucentInteractions) { return true; } if (!vLight->lightShader->LightCastsShadows()) { return true; } int lod = r_smForceLod.GetInteger(); if(lod < 0) { lod = vLight->shadowMapLod; } lod = Max( 0, Min( lod, 2 ) ); const uint64 startTime = Sys_Microseconds(); const float polygonOffsetBias = vLight->lightDef->ShadowPolygonOffsetBias(); const float polygonOffsetFactor = vLight->lightDef->ShadowPolygonOffsetFactor(); glEnable( GL_POLYGON_OFFSET_FILL ); glPolygonOffset( polygonOffsetFactor, polygonOffsetBias ); switch (r_smFaceCullMode.GetInteger()) { case 0: glEnable( GL_CULL_FACE ); glFrontFace( GL_CCW ); break; case 1: glEnable( GL_CULL_FACE ); glFrontFace( GL_CW ); break; case 2: default: glDisable( GL_CULL_FACE ); break; } ShadowRenderList renderlist; int numShadowMaps = 0; if (vLight->lightDef->parms.parallel) { assert( vLight->lightDef->numShadowMapFrustums == 1 ); shadowMapFrustum_t& frustum = vLight->lightDef->shadowMapFrustums[0]; if (!shadowMapAllocator.Allocate( 0, 6, vLight->shadowCoords )) { return false; } const float cascadeDistances[6] = { r_smCascadeDistance0.GetFloat(), r_smCascadeDistance1.GetFloat(), r_smCascadeDistance2.GetFloat(), r_smCascadeDistance3.GetFloat(), r_smCascadeDistance4.GetFloat(), 100000 }; lod = 0; float nextNearDistance = 1; for (int c = 0; c < 6; ++c) { idFrustum viewFrustum = backEnd.viewDef->viewFrustum; viewFrustum.MoveFarDistance( cascadeDistances[c] ); //move far before near, so far is always greater than near viewFrustum.MoveNearDistance( nextNearDistance ); nextNearDistance = cascadeDistances[c]; idVec3 viewCorners[8]; viewFrustum.ToPoints( viewCorners ); for (int i = 0; i < 8; ++i) { viewCorners[i] = frustum.viewMatrix * viewCorners[i]; } idVec2 viewMinimum = viewCorners[0].ToVec2(); idVec2 viewMaximum = viewCorners[0].ToVec2(); for (int i = 1; i < 8; ++i) { const float x = viewCorners[i].x; const float y = viewCorners[i].y; viewMinimum.x = Min( viewMinimum.x, x ); viewMinimum.y = Min( viewMinimum.y, y ); viewMaximum.x = Max( viewMaximum.x, x ); viewMaximum.y = Max( viewMaximum.y, y ); } idVec2 minimum, maximum; if (c < r_smViewDependendCascades.GetInteger()) { minimum.x = Max( frustum.viewSpaceBounds[0].x, viewMinimum.x ); minimum.y = Max( frustum.viewSpaceBounds[0].y, viewMinimum.y ); maximum.x = Min( frustum.viewSpaceBounds[1].x, viewMaximum.x ); maximum.y = Min( frustum.viewSpaceBounds[1].y, viewMaximum.y ); } else { minimum = frustum.viewSpaceBounds[0].ToVec2(); maximum = frustum.viewSpaceBounds[1].ToVec2(); } float r = idMath::Abs( maximum.x - minimum.x ) * 0.5f; float l = -r; float t = idMath::Abs( maximum.y - minimum.y ) * 0.5f; float b = -t; vLight->viewMatrices[c] = frustum.viewMatrix; vLight->viewMatrices[c][12] = -(maximum.x + minimum.x) * 0.5f; vLight->viewMatrices[c][13] = -(maximum.y + minimum.y) * 0.5f; vLight->viewMatrices[c][14] = -(frustum.viewSpaceBounds[1].z + 1); const float f = fabs( frustum.viewSpaceBounds[1].z - frustum.viewSpaceBounds[0].z ); const float n = 1; vLight->projectionMatrices[c] = fhRenderMatrix::identity; vLight->projectionMatrices[c][0] = 2.0f / (r - l); vLight->projectionMatrices[c][5] = 2.0f / (b - t); vLight->projectionMatrices[c][10] = -2.0f / (f - n); vLight->projectionMatrices[c][12] = -((r + l) / (r - l)); vLight->projectionMatrices[c][13] = -((t + b) / (t - b)); vLight->projectionMatrices[c][14] = -((f + n) / (f - n)); vLight->projectionMatrices[c][15] = 1.0f; vLight->viewProjectionMatrices[c] = vLight->projectionMatrices[c] * vLight->viewMatrices[c]; vLight->width[c] = fabs( r * 2 ); vLight->height[c] = fabs( t * 2 ); vLight->culled[c] = false; } renderlist.AddInteractions( vLight, nullptr, 0 ); numShadowMaps = 6; } else if (vLight->lightDef->parms.pointLight) { assert( vLight->lightDef->numShadowMapFrustums == 6 ); idVec3 viewCorners[8]; backEnd.viewDef->viewFrustum.ToPoints( viewCorners ); for (int i = 0; i < 6; ++i) { if (r_smLightSideCulling.GetBool()) { vLight->culled[i] = vLight->lightDef->shadowMapFrustums[i].Cull(viewCorners); } else { vLight->culled[i] = false; } if (vLight->culled[i]) { continue; } if (!shadowMapAllocator.Allocate(lod, 1, &vLight->shadowCoords[i])) { return false; } vLight->viewMatrices[i] = vLight->lightDef->shadowMapFrustums[i].viewMatrix; vLight->projectionMatrices[i] = vLight->lightDef->shadowMapFrustums[i].projectionMatrix; vLight->viewProjectionMatrices[i] = vLight->lightDef->shadowMapFrustums[i].viewProjectionMatrix; } renderlist.AddInteractions( vLight, vLight->lightDef->shadowMapFrustums, vLight->lightDef->numShadowMapFrustums ); numShadowMaps = 6; } else { //projected light if (!shadowMapAllocator.Allocate( lod, 1, vLight->shadowCoords )) { return false; } assert( vLight->lightDef->numShadowMapFrustums == 1 ); vLight->viewMatrices[0] = vLight->lightDef->shadowMapFrustums[0].viewMatrix; vLight->projectionMatrices[0] = vLight->lightDef->shadowMapFrustums[0].projectionMatrix; vLight->viewProjectionMatrices[0] = vLight->lightDef->shadowMapFrustums[0].viewProjectionMatrix; vLight->culled[0] = false; renderlist.AddInteractions( vLight, &vLight->lightDef->shadowMapFrustums[0], 1 ); numShadowMaps = 1; } for (int side = 0; side < numShadowMaps; side++) { if(vLight->culled[side]) { continue; } const fhFramebuffer* framebuffer = fhFramebuffer::shadowmapFramebuffer; const int width = framebuffer->GetWidth() * vLight->shadowCoords[side].scale.x; const int height = framebuffer->GetHeight() * vLight->shadowCoords[side].scale.y; const int offsetX = framebuffer->GetWidth() * vLight->shadowCoords[side].offset.x; const int offsetY = framebuffer->GetHeight() * vLight->shadowCoords[side].offset.y; glViewport( offsetX, offsetY, width, height ); glScissor( offsetX, offsetY, width, height ); renderlist.Submit( vLight->viewMatrices[side].ToFloatPtr(), vLight->projectionMatrices[side].ToFloatPtr(), side, lod ); backEnd.stats.groups[backEndGroup::ShadowMap0 + lod].passes += 1; } const uint64 endTime = Sys_Microseconds(); backEnd.stats.groups[backEndGroup::ShadowMap0 + lod].time += static_cast<uint32>(endTime - startTime); return true; }