// Apply Frame Limit and Display FPS info // This should only be called from VI void VideoThrottle() { u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 2) ? (SConfig::GetInstance().m_Framelimit - 1) * 5 : VideoInterface::TargetRefreshRate; // Disable the frame-limiter when the throttle (Tab) key is held down. Audio throttle: m_Framelimit = 2 if (SConfig::GetInstance().m_Framelimit && SConfig::GetInstance().m_Framelimit != 2 && !Host_GetKeyState('\t')) { u32 frametime = ((SConfig::GetInstance().b_UseFPS)? Common::AtomicLoad(DrawnFrame) : DrawnVideo) * 1000 / TargetVPS; u32 timeDifference = (u32)Timer.GetTimeDifference(); if (timeDifference < frametime) { Common::SleepCurrentThread(frametime - timeDifference - 1); } while ((u32)Timer.GetTimeDifference() < frametime) Common::YieldCPU(); //Common::SleepCurrentThread(1); } // Update info per second u32 ElapseTime = (u32)Timer.GetTimeDifference(); if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo) { UpdateTitle(); // Reset counter Timer.Update(); Common::AtomicStore(DrawnFrame, 0); DrawnVideo = 0; } DrawnVideo++; }
// Display FPS info // This should only be called from VI void VideoThrottle() { // Update info per second u32 ElapseTime = (u32)s_timer.GetTimeDifference(); if ((ElapseTime >= 1000 && s_drawn_video.load() > 0) || s_request_refresh_info) { UpdateTitle(); // Reset counter s_timer.Update(); s_drawn_frame.store(0); s_drawn_video.store(0); } s_drawn_video++; bool update_ss_speed = true; if (SConfig::GetInstance().bDoubleVideoRate) { update_ss_speed = s_drawn_video & 1; } // Update the audio timestretcher with the current speed if (g_sound_stream && update_ss_speed) { float Speed = (float)(s_drawn_video.load() * 1000.0 / (VideoInterface::GetTargetRefreshRate() * ElapseTime)); g_sound_stream->GetMixer()->UpdateSpeed((float)Speed); } }
void UpdateTitle() { u32 ElapseTime = (u32)s_timer.GetTimeDifference(); s_request_refresh_info = false; SConfig& _CoreParameter = SConfig::GetInstance(); if (ElapseTime == 0) ElapseTime = 1; float FPS = (float)(s_drawn_frame.load() * 1000.0 / ElapseTime); float VPS = (float)(s_drawn_video.load() * 1000.0 / ElapseTime); float Speed = (float)(s_drawn_video.load() * (100 * 1000.0) / (VideoInterface::GetTargetRefreshRate() * ElapseTime)); // Settings are shown the same for both extended and summary info std::string SSettings = StringFromFormat("%s %s | %s | %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", g_video_backend->GetDisplayName().c_str(), _CoreParameter.bDSPHLE ? "HLE" : "LLE"); std::string SFPS; if (Movie::IsPlayingInput()) SFPS = StringFromFormat("VI: %u/%u - Input: %u/%u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); else if (Movie::IsRecordingInput()) SFPS = StringFromFormat("VI: %u - Input: %u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); else { SFPS = StringFromFormat("FPS: %.0f - VPS: %.0f - %.0f%%", FPS, VPS, Speed); if (SConfig::GetInstance().m_InterfaceExtendedFPSInfo) { // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. static u64 ticks = 0; static u64 idleTicks = 0; u64 newTicks = CoreTiming::GetTicks(); u64 newIdleTicks = CoreTiming::GetIdleTicks(); u64 diff = (newTicks - ticks) / 1000000; u64 idleDiff = (newIdleTicks - idleTicks) / 1000000; ticks = newTicks; idleTicks = newIdleTicks; float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100; SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)", _CoreParameter.bSkipIdle ? "~" : "", (int)(diff), (int)(diff - idleDiff), (int)(idleDiff), SystemTimers::GetTicksPerSecond() / 1000000, _CoreParameter.bSkipIdle ? "~" : "", TicksPercentage); } } // This is our final "frame counter" string std::string SMessage = StringFromFormat("%s | %s", SSettings.c_str(), SFPS.c_str()); Host_UpdateTitle(SMessage); }
// Executed from GPU thread // reports if a frame should be skipped or not // depending on the framelimit set bool ShouldSkipFrame(int skipped) { const u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1) ? (SConfig::GetInstance().m_Framelimit - 1) * 5 : VideoInterface::TargetRefreshRate; const u32 frames = Common::AtomicLoad(s_drawn_frame); const bool fps_slow = !(s_timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS); return fps_slow; }
// Executed from GPU thread // reports if a frame should be skipped or not // depending on the emulation speed set bool ShouldSkipFrame(int skipped) { u32 TargetFPS = VideoInterface::GetTargetRefreshRate(); if (SConfig::GetInstance().m_EmulationSpeed > 0.0f) TargetFPS = u32(TargetFPS * SConfig::GetInstance().m_EmulationSpeed); const u32 frames = s_drawn_frame.load(); const bool fps_slow = !(s_timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS); return fps_slow; }
// Apply Frame Limit and Display FPS info // This should only be called from VI void VideoThrottle() { // Update info per second u32 ElapseTime = (u32)s_timer.GetTimeDifference(); if ((ElapseTime >= 1000 && s_drawn_video > 0) || s_request_refresh_info) { UpdateTitle(); // Reset counter s_timer.Update(); Common::AtomicStore(s_drawn_frame, 0); s_drawn_video = 0; } s_drawn_video++; }
// Display FPS info // This should only be called from VI void VideoThrottle() { // Update info per second u32 ElapseTime = (u32)s_timer.GetTimeDifference(); if ((ElapseTime >= 1000 && s_drawn_video.load() > 0) || s_request_refresh_info) { UpdateTitle(); // Reset counter s_timer.Update(); s_drawn_frame.store(0); s_drawn_video.store(0); } s_drawn_video++; }
// Apply Frame Limit and Display FPS info // This should only be called from VI void VideoThrottle() { // Update info per second u32 ElapseTime = (u32)Timer.GetTimeDifference(); if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo) { UpdateTitle(); // Reset counter Timer.Update(); Common::AtomicStore(DrawnFrame, 0); DrawnVideo = 0; } DrawnVideo++; }
void UDPWiimote::mainThread() { std::unique_lock<std::mutex> lk(d->termLock); Common::Timer time; fd_set fds; struct timeval timeout; timeout.tv_sec=0; timeout.tv_usec=0; time.Update(); do { int maxfd=0; FD_ZERO(&fds); for (auto& fd : d->sockfds) { FD_SET(fd,&fds); #ifndef _WIN32 if (fd>=maxfd) maxfd=(fd)+1; #endif } u64 tleft=timeout.tv_sec*1000+timeout.tv_usec/1000; u64 telapsed=time.GetTimeDifference(); time.Update(); if (tleft<=telapsed) { timeout.tv_sec=1; timeout.tv_usec=500000; broadcastPresence(); } else { tleft-=telapsed; timeout.tv_sec=(long)(tleft/1000); timeout.tv_usec=(tleft%1000)*1000; } lk.unlock(); //VERY hacky. don't like it if (d->exit) return; int rt=select(maxfd,&fds,NULL,NULL,&timeout); if (d->exit) return; lk.lock(); if (d->exit) return; if (rt) { for (sock_t fd : d->sockfds) { if (FD_ISSET(fd,&fds)) { u8 bf[64]; int size=60; size_t addr_len; struct sockaddr_storage their_addr; addr_len = sizeof their_addr; if ((size = recvfrom(fd, (dataz)bf, size , 0,(struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1) { ERROR_LOG(WIIMOTE,"UDPWii Packet error"); } else { std::lock_guard<std::mutex> lkm(d->mutex); if (pharsePacket(bf,size)==0) { //NOTICE_LOG(WIIMOTE,"UDPWII New pack"); } else { //NOTICE_LOG(WIIMOTE,"UDPWII Wrong pack format... ignoring"); } } } } } } while (!(d->exit)); }
void UpdateTitle() { u32 ElapseTime = (u32)Timer.GetTimeDifference(); g_requestRefreshInfo = false; SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; if (ElapseTime == 0) ElapseTime = 1; float FPS = (float) (Common::AtomicLoad(DrawnFrame) * 1000.0 / ElapseTime); float VPS = (float) (DrawnVideo * 1000.0 / ElapseTime); float Speed = (float) (DrawnVideo * (100 * 1000.0) / (VideoInterface::TargetRefreshRate * ElapseTime)); // Settings are shown the same for both extended and summary info std::string SSettings = StringFromFormat("%s %s | %s | %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", g_video_backend->GetDisplayName().c_str(), _CoreParameter.bDSPHLE ? "HLE" : "LLE"); std::string SFPS; if (Movie::IsPlayingInput()) SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); else if (Movie::IsRecordingInput()) SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); else { SFPS = StringFromFormat("FPS: %.0f - VPS: %.0f - %.0f%%", FPS, VPS, Speed); if (SConfig::GetInstance().m_InterfaceExtendedFPSInfo) { // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. static u64 ticks = 0; static u64 idleTicks = 0; u64 newTicks = CoreTiming::GetTicks(); u64 newIdleTicks = CoreTiming::GetIdleTicks(); u64 diff = (newTicks - ticks) / 1000000; u64 idleDiff = (newIdleTicks - idleTicks) / 1000000; ticks = newTicks; idleTicks = newIdleTicks; float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100; SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)", _CoreParameter.bSkipIdle ? "~" : "", (int)(diff), (int)(diff - idleDiff), (int)(idleDiff), SystemTimers::GetTicksPerSecond() / 1000000, _CoreParameter.bSkipIdle ? "~" : "", TicksPercentage); } } // This is our final "frame counter" string std::string SMessage = StringFromFormat("%s | %s", SSettings.c_str(), SFPS.c_str()); std::string TMessage = StringFromFormat("%s | %s", scm_rev_str, SMessage.c_str()); // Show message g_video_backend->UpdateFPSDisplay(SMessage); // Update the audio timestretcher with the current speed if (soundStream) { CMixer* pMixer = soundStream->GetMixer(); pMixer->UpdateSpeed((float)Speed / 100); } if (_CoreParameter.bRenderToMain && SConfig::GetInstance().m_InterfaceStatusbar) { Host_UpdateStatusBar(SMessage); Host_UpdateTitle(scm_rev_str); } else { Host_UpdateTitle(TMessage); } }
// Apply Frame Limit and Display FPS info // This should only be called from VI void VideoThrottle() { u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 2) ? (SConfig::GetInstance().m_Framelimit - 1) * 5 : VideoInterface::TargetRefreshRate; // Disable the frame-limiter when the throttle (Tab) key is held down. Audio throttle: m_Framelimit = 2 if (SConfig::GetInstance().m_Framelimit && SConfig::GetInstance().m_Framelimit != 2 && !Host_GetKeyState('\t')) { u32 frametime = ((SConfig::GetInstance().b_UseFPS)? Common::AtomicLoad(DrawnFrame) : DrawnVideo) * 1000 / TargetVPS; u32 timeDifference = (u32)Timer.GetTimeDifference(); if (timeDifference < frametime) { Common::SleepCurrentThread(frametime - timeDifference - 1); } while ((u32)Timer.GetTimeDifference() < frametime) Common::YieldCPU(); //Common::SleepCurrentThread(1); } // Update info per second u32 ElapseTime = (u32)Timer.GetTimeDifference(); if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo) { g_requestRefreshInfo = false; SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; if (ElapseTime == 0) ElapseTime = 1; u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime; u32 VPS = DrawnVideo * 1000 / ElapseTime; u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime); // Settings are shown the same for both extended and summary info std::string SSettings = StringFromFormat("%s %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC"); // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. //#define EXTENDED_INFO #ifdef EXTENDED_INFO u64 newTicks = CoreTiming::GetTicks(); u64 newIdleTicks = CoreTiming::GetIdleTicks(); u64 diff = (newTicks - ticks) / 1000000; u64 idleDiff = (newIdleTicks - idleTicks) / 1000000; ticks = newTicks; idleTicks = newIdleTicks; float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100; std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)", _CoreParameter.bSkipIdle ? "~" : "", (int)(diff), (int)(diff - idleDiff), (int)(idleDiff), SystemTimers::GetTicksPerSecond() / 1000000, _CoreParameter.bSkipIdle ? "~" : "", TicksPercentage); #else // Summary information std::string SFPS; if (Movie::IsPlayingInput()) SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); else if (Movie::IsRecordingInput()) SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); else SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); #endif // This is our final "frame counter" string std::string SMessage = StringFromFormat("%s | %s", SSettings.c_str(), SFPS.c_str()); std::string TMessage = StringFromFormat("%s | ", scm_rev_str) + SMessage; // Show message g_video_backend->UpdateFPSDisplay(SMessage.c_str()); if (_CoreParameter.bRenderToMain && SConfig::GetInstance().m_InterfaceStatusbar) { Host_UpdateStatusBar(SMessage.c_str()); Host_UpdateTitle(scm_rev_str); } else Host_UpdateTitle(TMessage.c_str()); // Reset counter Timer.Update(); Common::AtomicStore(DrawnFrame, 0); DrawnVideo = 0; } DrawnVideo++; }