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 ×tamp ) { 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; }
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(); }
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(); }