void RageDisplay::FrameLimitBeforeVsync( int iFPS )
{
	ASSERT( iFPS != 0 );

	int iDelayMicroseconds = 0;
	if( g_fFrameLimitPercent.Get() > 0.0f && !g_LastFrameEndedAt.IsZero() )
	{
		float fFrameTime = g_LastFrameEndedAt.GetDeltaTime();
		float fExpectedTime = 1.0f / iFPS;

		/* This is typically used to turn some of the delay that would normally
		 * be waiting for vsync and turn it into a usleep, to make sure we give
		 * up the CPU.  If we overshoot the sleep, then we'll miss the vsync,
		 * so allow tweaking the amount of time we expect a frame to take.
		 * Frame limiting is disabled by setting this to 0. */
		fExpectedTime *= g_fFrameLimitPercent.Get();
		float fExtraTime = fExpectedTime - fFrameTime;

		iDelayMicroseconds = int(fExtraTime * 1000000);
	}

	if( !HOOKS->AppHasFocus() )
		iDelayMicroseconds = max( iDelayMicroseconds, 10000 ); // give some time to other processes and threads

#if defined(_WINDOWS)
	/* In Windows, always explicitly give up a minimum amount of CPU for other threads. */
	iDelayMicroseconds = max( iDelayMicroseconds, 1000 );
#endif

	if( iDelayMicroseconds > 0 )
		usleep( iDelayMicroseconds );
}
void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp )
{

	if( !timestamp.IsZero() )
		m_LastBeatUpdate = timestamp;
	else
		m_LastBeatUpdate.Touch();

	TimingData::GetBeatArgs beat_info;
	beat_info.elapsed_time= fPositionSeconds;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeat= beat_info.beat;
	m_fCurBPS= beat_info.bps_out;
	m_bFreeze= beat_info.freeze_out;
	m_bDelay= beat_info.delay_out;
	m_iWarpBeginRow= beat_info.warp_begin_out;
	m_fWarpDestination= beat_info.warp_dest_out;
	
	// "Crash reason : -243478.890625 -48695.773438"
	// The question is why is -2000 used as the limit? -aj
	ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds is less than -2000!", m_fSongBeat, fPositionSeconds) );

	m_fMusicSeconds = fPositionSeconds;

	m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );

	m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
	
	m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get();
	beat_info.elapsed_time= m_fMusicSecondsVisible;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeatVisible= beat_info.beat;
}
Exemple #3
0
static bool ChangeAppPri()
{
	if( g_bNeverBoostAppPriority.Get() )
		return false;

	// if using NTPAD don't boost or else input is laggy
#if defined(_WINDOWS)
	{
		vector<InputDeviceInfo> vDevices;

		// This can get called before INPUTMAN is constructed.
		if( INPUTMAN )
		{
			INPUTMAN->GetDevicesAndDescriptions(vDevices);
			FOREACH_CONST( InputDeviceInfo, vDevices, d )
			{
				if( d->sDesc.find("NTPAD") != string::npos )
				{
					LOG->Trace( "Using NTPAD.  Don't boost priority." );
					return false;
				}
			}
		}
	}
#endif

	/* If this is a debug build, don't.  It makes the VC debugger sluggish. */
#if defined(WIN32) && defined(DEBUG)
	return false;
#else
	return true;
#endif
}
void RageDisplay::FrameLimitAfterVsync()
{
	if( g_fFrameLimitPercent.Get() == 0.0f )
		return;

	g_LastFrameEndedAt.Touch();
}
void ChangeVisualDelay( float fDelta )
{
	Preference<float> *pRet = Preference<float>::GetPreferenceByName("VisualDelaySeconds");
	float fSecs = pRet->Get();
	fSecs += fDelta;
	fSecs = Rage::clamp( fSecs, -1.0f, 1.0f );
	pRet->Set( fSecs );
}
bool RageSoundReader_Preload::Open( RageSoundReader *pSource )
{
	ASSERT( pSource );
	m_iSampleRate = pSource->GetSampleRate();
	m_iChannels = pSource->GetNumChannels();
	m_fRate = pSource->GetStreamToSourceRatio();

	int iMaxSamples = g_iSoundPreloadMaxSamples.Get();
	
	/* Check the length, and see if we think it'll fit in the buffer. */
	int iLen = pSource->GetLength_Fast();
	if( iLen != -1 )
	{
		float fSecs = iLen / 1000.f;

		int iFrames = lrintf( fSecs * m_iSampleRate ); /* seconds -> frames */
		int iSamples = unsigned( iFrames * m_iChannels ); /* frames -> samples */
		if( iSamples > iMaxSamples )
			return false; /* Don't bother trying to preload it. */

		int iBytes = unsigned( iSamples * samplesize ); /* samples -> bytes */
		m_Buffer.Get()->reserve( iBytes );
	}

	while(1)
	{
		/* If the rate changes, we won't preload it. */
		if( pSource->GetStreamToSourceRatio() != m_fRate )
			return false; /* Don't bother trying to preload it. */

		float buffer[1024];
		int iCnt = pSource->Read( buffer, ARRAYLEN(buffer) / m_iChannels );

		if( iCnt == END_OF_FILE )
			break;
		if( iCnt < 0 )
			return false;

		/* Add the buffer. */
		if( m_bBufferIs16Bit )
		{
			int16_t buffer16[1024];
			RageSoundUtil::ConvertFloatToNativeInt16( buffer, buffer16, iCnt*m_iChannels );
			m_Buffer.Get()->append( (char *) buffer16, (char *) (buffer16+iCnt*m_iChannels) );
		}
		else
		{
			m_Buffer.Get()->append( (char *) buffer, (char *) (buffer+iCnt*m_iChannels) );
		}

		if( m_Buffer.Get()->size() > iMaxSamples * samplesize )
			return false; /* too big */
	}

	m_iPosition = 0;
	delete pSource;
	return true;
}
void ChangeVolume( float fDelta )
{
	Preference<float> *pRet = Preference<float>::GetPreferenceByName("SoundVolume");
	float fVol = pRet->Get();
	fVol += fDelta;
	fVol = Rage::clamp( fVol, 0.0f, 1.0f );
	pRet->Set( fVol );
	SOUNDMAN->SetMixVolume();
}
Exemple #8
0
bool X11Helper::MakeWindow( Window &win, int screenNum, int depth, Visual *visual, int width, int height, bool overrideRedirect )
{
	if( !Dpy )
		return false;

	XSetWindowAttributes winAttribs;
	winAttribs.border_pixel = 0;
	winAttribs.event_mask = 0L;

	if( win )
	{
		// Preserve the event mask.
		XWindowAttributes attribs;
		XGetWindowAttributes( Dpy, win, &attribs );
		winAttribs.event_mask = attribs.your_event_mask;
		XDestroyWindow( Dpy, win );
	}
	// XXX: Error catching/handling?
	winAttribs.colormap = XCreateColormap( Dpy, RootWindow(Dpy, screenNum), visual, AllocNone );
	unsigned long mask = CWBorderPixel | CWColormap | CWEventMask;

	if( overrideRedirect )
	{
		winAttribs.override_redirect = True;
		mask |= CWOverrideRedirect;
	}
	win = XCreateWindow( Dpy, RootWindow(Dpy, screenNum), 0, 0, width, height, 0,
			     depth, InputOutput, visual, mask, &winAttribs );
	if( win == None )
		return false;

	XClassHint *hint = XAllocClassHint();
	if ( hint == nullptr ) {
		LOG->Warn("Could not set class hint for X11 Window");
	} else {
		hint->res_name   = (char*)g_XWMName.Get().c_str();
		hint->res_class  = (char*)PRODUCT_FAMILY;
		XSetClassHint(Dpy, win, hint);
		XFree(hint);
	}

	// Hide the mouse cursor in certain situations.
    if( !PREFSMAN->m_bShowMouseCursor )
	{
		const char pBlank[] = { 0,0,0,0,0,0,0,0 };
		Pixmap BlankBitmap = XCreateBitmapFromData( Dpy, win, pBlank, 8, 8 );

		XColor black = { 0, 0, 0, 0, 0, 0 };
		Cursor pBlankPointer = XCreatePixmapCursor( Dpy, BlankBitmap, BlankBitmap, &black, &black, 0, 0 );
		XFreePixmap( Dpy, BlankBitmap );

		XDefineCursor( Dpy, win, pBlankPointer );
		XFreeCursor( Dpy, pBlankPointer );
	}

	return true;
}
static void MoveMap( int &sel, Preference<T> &opt, bool ToSel, const T *mapping, unsigned cnt )
{
	if( ToSel )
	{
		sel = FindClosestEntry( opt.Get(), mapping, cnt );
	} else {
		/* sel -> opt */
		opt.Set( mapping[sel] );
	}
}
LightsDriver_EXTIO::LightsDriver_EXTIO()
{
	if (s_bInitialized) return;
	s_bInitialized = true; //only one instance should do this
	m_bShutdown = false;


	LOG->Info("EXTIO: Initializing EXTIO Light drivers...");
	LOG->Info("EXTIO: Configured EXTIO serial port: %s", m_EXTIO_COMPORT.Get().c_str());
	//check if we have a valid com port name for EXTIO
	if (m_EXTIO_COMPORT.Get().length()>1)
	{
		//this is nice because EXTIO code will now only run after this SINGLE check
		EXTIOThread.SetName("EXTIO thread");
		EXTIOThread.Create(EXTIOThread_Start, this);
	}


}
void LightsDriver_EXTIO::EXTIOThreadMain()
{
	extio.setPort(m_EXTIO_COMPORT.Get().c_str()); //on a ddr pcb, extio must reside on COM1
	extio.setBaudrate(38400);
	extio.setTimeout(serial_timeout);
	extio.open();
	LOG->Info("EXTIO: Opened EXTIO");
	//all P2/P3IO have the extio as pad lights so lets make sure that is good

	while (!m_bShutdown)
	{
		//LOG->Info("EXTIO: EXTIO PING");
		UpdateLightsEXTIO();
		usleep(16666); //60 times per sec

	}

	//turn off pad lights
	memset(extio_message, 0, 4 * sizeof(uint8_t));// zero out the message
	WriteExtioPacket();

}
void FileTransfer::StartTransfer( TransferType type, const RString &sURL, const RString &sSrcFile, const RString &sDestFile )
{
	RString Proto;
	RString Server;
	int Port=80;
	RString sAddress;

	if( !ParseHTTPAddress( sURL, Proto, Server, Port, sAddress ) )
	{
		m_sStatus = "Invalid URL.";
		m_bFinished = true;
		UpdateProgress();
		return;
	}

	m_bSavingFile = sDestFile != "";

	m_sBaseAddress = "http://" + Server;
	if( Port != 80 )
		m_sBaseAddress += ssprintf( ":%d", Port );
	m_sBaseAddress += "/";

	if( sAddress.Right(1) != "/" )
	{
		m_sEndName = Basename( sAddress );
		m_sBaseAddress += Dirname( sAddress );
	}
	else
	{
		m_sEndName = "";
	}

	// Open the file...

	// First find out if a file by this name already exists if so, then we gotta
	// ditch out.
	// XXX: This should be fixed by a prompt or something?

	// if we are not talking about a file, let's not worry
	if( m_sEndName != "" && m_bSavingFile )
	{
		if( !m_fOutputFile.Open( sDestFile, RageFile::WRITE | RageFile::STREAMED ) )
		{
			m_sStatus = m_fOutputFile.GetError();
			UpdateProgress();
			return;
		}
	}
	// Continue...

	sAddress = URLEncode( sAddress );

	if ( sAddress != "/" )
		sAddress = "/" + sAddress;

	m_wSocket.close();
	m_wSocket.create();

	m_wSocket.blocking = true;

	if( !m_wSocket.connect( Server, (short) Port ) )
	{
		m_sStatus = "Failed to connect.";
		UpdateProgress();
		return;
	}

	// Produce HTTP header
	RString sAction;
	switch( type )
	{
	case upload: sAction = "POST"; break;
	case download: sAction = "GET"; break;
	}

	vector<RString> vsHeaders;
	vsHeaders.push_back( sAction+" "+sAddress+" HTTP/1.0" );
	vsHeaders.push_back( "Host: " + Server );
	vsHeaders.push_back( "Cookie: " + g_sCookie.Get() );
	vsHeaders.push_back( "Connection: closed" );
	string sBoundary = "--ZzAaB03x";
	vsHeaders.push_back( "Content-Type: multipart/form-data; boundary=" + sBoundary );
	RString sRequestPayload;
	if( type == upload )
	{
		RageFile f;
		if( !f.Open( sSrcFile ) )
			FAIL_M( f.GetError() );
		sRequestPayload.reserve( f.GetFileSize() );
		int iBytesRead = f.Read( sRequestPayload );
		if( iBytesRead == -1 )
			FAIL_M( f.GetError() );

		sRequestPayload = "--" + sBoundary + "\r\n" + 
			"Content-Disposition: form-data; name=\"name\"\r\n" +
			"\r\n" +
			"Chris\r\n" +
			"--" + sBoundary + "\r\n" + 
			"Content-Disposition: form-data; name=\"userfile\"; filename=\"" + Basename(sSrcFile) + "\"\r\n" +
			"Content-Type: application/zip\r\n" + 
			"\r\n" +
			sRequestPayload + "\r\n" +
			"--" + sBoundary + "--";
	}
	/*
	if( sRequestPayload.size() > 0 )
	{
		sHeader += "Content-Type: application/octet-stream\r\n";
		sHeader += "Content-Length: multipart/form-data; boundary=" + sBoundary + "\r\n";
		//sHeader += "Content-Length: " + ssprintf("%d",sRequestPayload.size()) + "\r\n";
	}
	*/

	vsHeaders.push_back( "Content-Length: " + ssprintf("%zd",sRequestPayload.size()) );

	RString sHeader;
	FOREACH_CONST( RString, vsHeaders, h )
		sHeader += *h + "\r\n";
	sHeader += "\r\n";

	m_wSocket.SendData( sHeader.c_str(), sHeader.length() );
	m_wSocket.SendData( "\r\n" );

	m_wSocket.SendData( sRequestPayload.GetBuffer(), sRequestPayload.size() );

	m_sStatus = "Header Sent.";
	m_wSocket.blocking = false;
	m_bIsDownloading = true;
	m_sBUFFER = "";
	m_bGotHeader = false;
	UpdateProgress();
}
RageSoundReader_Preload::RageSoundReader_Preload():
	m_Buffer( new RString )
{
	m_bBufferIs16Bit = g_bSoundPreload16bit.Get();
}
// Assign cards from m_vStorageDevices to m_Device.
void MemoryCardManager::UpdateAssignments()
{
	if( !g_bMemoryCardProfiles.Get() )
		return;

	// make a list of unassigned
	vector<UsbStorageDevice> vUnassignedDevices = m_vStorageDevices; // copy

	// remove cards that are already assigned
	FOREACH_PlayerNumber( p )
	{
		UsbStorageDevice &assigned_device = m_Device[p];
		if( assigned_device.IsBlank() )     // no card assigned to this player
			continue;

		FOREACH( UsbStorageDevice, vUnassignedDevices, d )
		{
			if( *d == assigned_device )
			{
				vUnassignedDevices.erase( d );
				break;
			}
		}
	}

	// Try to assign each device to a player. If a player already has a device
	// assigned, and the device still exists, keep him on the same card.
	FOREACH_PlayerNumber( p )
	{
		UsbStorageDevice &assigned_device = m_Device[p];
		if( !assigned_device.IsBlank() )
		{
			// The player has a card assigned. If it's been removed, clear it.
			vector<UsbStorageDevice>::iterator it = find( m_vStorageDevices.begin(), m_vStorageDevices.end(), assigned_device );
			if( it != m_vStorageDevices.end() )
			{
				/* The player has a card, and it's still plugged in. Update any
				 * changed state, such as m_State. */
				LOG->Trace( "Player %d already has a card: '%s'", p+1, assigned_device.sOsMountDir.c_str() );
				assigned_device = *it;
				continue;
			}

			// The assigned card has been removed; clear it and re-search.
			LOG->Trace( "Player %i: disconnected bus %d port %d device %d path %s",
				p+1, assigned_device.iBus, assigned_device.iPort, assigned_device.iLevel, assigned_device.sOsMountDir.c_str() );
			assigned_device.MakeBlank();
		}

		LOG->Trace( "Looking for a card for Player %d", p+1 );
				
		FOREACH( UsbStorageDevice, vUnassignedDevices, d )
		{
			// search for card dir match
			if( !m_sMemoryCardOsMountPoint[p].Get().empty() &&
				d->sOsMountDir.CompareNoCase(m_sMemoryCardOsMountPoint[p].Get()) )
				continue; // not a match
			
			// search for USB bus match
			if( m_iMemoryCardUsbBus[p] != -1 &&
				m_iMemoryCardUsbBus[p] != d->iBus )
				continue; // not a match
			
			if( m_iMemoryCardUsbPort[p] != -1 &&
				m_iMemoryCardUsbPort[p] != d->iPort )
				continue; // not a match
			
			if( m_iMemoryCardUsbLevel[p] != -1 &&
				m_iMemoryCardUsbLevel[p] != d->iLevel )
				continue;// not a match
			
			LOG->Trace( "Player %i: matched %s", p+1, d->sDevice.c_str() );

			assigned_device = *d; // save a copy
			vUnassignedDevices.erase( d ); // remove the device so we don't match it for another player
			break;
		}
	}

	CheckStateChanges();
}
bool ScreenNetworkOptions::MenuStart( const InputEventPlus &input )
{
	switch( GetCurrentRow() )
	{
	case PO_CONNECTION:
		if ( !NSMAN->useSMserver )
		{
			ScreenTextEntry::TextEntry( SM_DoneConnecting, ENTER_NETWORK_ADDRESS.GetValue()+"\n\n"+CONNECT_TO_YOURSELF.GetValue(), g_sLastServer.Get(), 128 );
		}
		else
		{
			NSMAN->CloseConnection();
			SCREENMAN->SystemMessage( DISCONNECTED.GetValue() );
			UpdateConnectStatus( );
		}
		return true;
	case PO_SCOREBOARD:
		if (m_pRows[PO_SCOREBOARD]->GetOneSharedSelection() == NO_SCOREBOARD_ON)
			PREFSMAN->m_bEnableScoreboard.Set(true);
		else
			PREFSMAN->m_bEnableScoreboard.Set(false);
		return true;
	/*
	case NetworkOptionRow::PO_SERVERS:
		if ( !AllServers.empty() )
		{
			string sNewName = AllServers[m_pRows[GetCurrentRow()]->GetOneSharedSelection()].Address;
			NSMAN->PostStartUp(sNewName);
			NSMAN->DisplayStartupStatus();
			UpdateConnectStatus( );
		}
		else
		{
			//If the server list is empty, keep passing the message on so exit works
			ScreenOptions::MenuStart( input );
		}
		return true;
	*/
	default:
		return ScreenOptions::MenuStart( input );
	}
}
RageSoundReader_Preload::RageSoundReader_Preload():
	m_Buffer( new RString ), m_bBufferIs16Bit(false),
	m_iPosition(0), m_iSampleRate(0), m_iChannels(0), m_fRate(0.0f)
{
	m_bBufferIs16Bit = g_bSoundPreload16bit.Get();
}