/* ================= Sys_AsyncThread ================= */ void Sys_AsyncThread( void ) { int now; int next; int want_sleep; // multi tick compensate for poor schedulers (Linux 2.4) int ticked, to_ticked; now = Sys_Milliseconds(); ticked = now >> 4; while( true ) { // sleep now = Sys_Milliseconds(); next = ( now & 0xFFFFFFF0 ) + 0x10; want_sleep = ( next - now - 1 ) * 1000; if( want_sleep > 0 ) { usleep( want_sleep ); // sleep 1ms less than true target } // compensate if we slept too long now = Sys_Milliseconds(); to_ticked = now >> 4; // show ticking statistics - every 100 ticks, print a summary #if 0 #define STAT_BUF 100 static int stats[STAT_BUF]; static int counter = 0; // how many ticks to play stats[counter] = to_ticked - ticked; counter++; if( counter == STAT_BUF ) { Sys_DebugPrintf( "\n" ); for( int i = 0; i < STAT_BUF; i++ ) { if( !( i & 0xf ) ) { Sys_DebugPrintf( "\n" ); } Sys_DebugPrintf( "%d ", stats[i] ); } Sys_DebugPrintf( "\n" ); counter = 0; } #endif while( ticked < to_ticked ) { common->Async(); ticked++; Sys_TriggerEvent( TRIGGER_EVENT_ONE ); } // thread exit pthread_testcancel(); } }
/* ================= 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) ); } }