public void SetSource(IFrameBasedClock trackingClock) { this.trackingClock = trackingClock; offsetClock = new OffsetClock(trackingClock) { Offset = -trackingClock.CurrentTime + startTime }; }
public override bool Equals(Object obj) { if (obj is OffsetClock) { OffsetClock other = (OffsetClock)obj; return(BaseClock.Equals(other.BaseClock) && Offset.Equals(other.Offset)); } return(false); }
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config, OsuGame osu) { dimLevel = config.GetBindable <int>(OsuConfig.DimLevel); mouseWheelDisabled = config.GetBindable <bool>(OsuConfig.MouseDisableWheel); Ruleset rulesetInstance; try { if (Beatmap == null) { Beatmap = beatmaps.GetWorkingBeatmap(BeatmapInfo, withStoryboard: true); } if ((Beatmap?.Beatmap?.HitObjects.Count ?? 0) == 0) { throw new Exception("No valid objects were found!"); } if (Beatmap == null) { throw new Exception("Beatmap was not loaded"); } ruleset = osu?.Ruleset.Value ?? Beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); try { HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap); } catch (BeatmapInvalidForRulesetException) { // we may fail to create a HitRenderer if the beatmap cannot be loaded with the user's preferred ruleset // let's try again forcing the beatmap's ruleset. ruleset = Beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap); } } catch (Exception e) { Logger.Log($"Could not load this beatmap sucessfully ({e})!", LoggingTarget.Runtime, LogLevel.Error); //couldn't load, hard abort! Exit(); return; } Track track = Beatmap.Track; if (track != null) { audio.Track.SetExclusive(track); sourceClock = track; } sourceClock = (IAdjustableClock)track ?? new StopwatchClock(); offsetClock = new OffsetClock(sourceClock); userAudioOffset = config.GetBindable <double>(OsuConfig.AudioOffset); userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); interpolatedSourceClock = new InterpolatingFramedClock(offsetClock); Schedule(() => { sourceClock.Reset(); foreach (var mod in Beatmap.Mods.Value.OfType <IApplicableToClock>()) { mod.ApplyToClock(sourceClock); } }); scoreProcessor = HitRenderer.CreateScoreProcessor(); hudOverlay = new StandardHudOverlay() { Anchor = Anchor.Centre, Origin = Anchor.Centre }; hudOverlay.KeyCounter.Add(rulesetInstance.CreateGameplayKeys()); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindHitRenderer(HitRenderer); hudOverlay.Progress.Objects = HitRenderer.Objects; hudOverlay.Progress.AudioClock = interpolatedSourceClock; //bind HitRenderer to ScoreProcessor and ourselves (for a pass situation) HitRenderer.OnAllJudged += onCompletion; //bind ScoreProcessor to ourselves (for a fail situation) scoreProcessor.Failed += onFail; Children = new Drawable[] { new Container { RelativeSizeAxes = Axes.Both, Clock = interpolatedSourceClock, Children = new Drawable[] { HitRenderer, skipButton = new SkipButton { Alpha = 0 }, } }, hudOverlay, pauseOverlay = new PauseOverlay { OnResume = delegate { Delay(400); Schedule(Resume); }, OnRetry = Restart, OnQuit = Exit, }, failOverlay = new FailOverlay { OnRetry = Restart, OnQuit = Exit, }, new HotkeyRetryOverlay { Action = () => { //we want to hide the hitrenderer immediately (looks better). //we may be able to remove this once the mouse cursor trail is improved. HitRenderer?.Hide(); Restart(); }, } }; }
private void Timer_Tick(object sender, object e) { prevTime = currTime; currTime = DateTime.Now; int extraTicks = 0; if (timerFinished) { if (!outroSmall) { if (outroLoopCount >= 10) { soundPlayer.PlayRandomSound(); outroLoopCount = 0; } ScaleBkgRect.ScaleX = 1.2; ScaleBkgRect.ScaleY = 1.2; RotateBkgRect.Value -= 110; LightBkgRect.Distance = 100; outroSmall = true; return; } else { ScaleBkgRect.ScaleX = 0.7; ScaleBkgRect.ScaleY = 0.7; RotateBkgRect.Value -= 60; LightBkgRect.Distance = 30; outroLoopCount++; outroSmall = false; return; } } if (!timerCanStart) { if (introCount == 0) { FadeInBkgRectAnimation.Begin(); } if (introCount < 3) { if (Settings.Current.SoundModeIndex > 0) { soundPlayer.PlaySound((Settings.Current.SoundModeIndex - 1) * 2); } RotateBkgRect.Value += 90; ScaleBkgRect.ScaleX += 0.15; ScaleBkgRect.ScaleY += 0.15; LightBkgRect.Distance += 15; introCount++; FadeOutClockAnimation.Begin(); return; } else { if (Settings.Current.SoundModeIndex > 0) { soundPlayer.PlaySound(((Settings.Current.SoundModeIndex - 1) * 2) + 1); } clockGrid.Opacity = 1; FadeOutBkgRectAnimation.Begin(); RotateBkgRect.Value += 150; ScaleBkgRect.ScaleX += 1.5; ScaleBkgRect.ScaleY += 1.5; if (Settings.Current.PlacementModeIndex == 1) { OffsetClock.StartAnimation(); ScaleClock.StartAnimation(); } timerCanStart = true; pauseButton.Visibility = Visibility.Visible; FadeInPauseButtonAnimation.Begin(); } } // in order to keep the clock honest, we check that the current tick time and // previous tick time are less than 2 seconds apart // this is important in case the app gets minimized, // which sometimes causes the tick code to not run if ((currTime - prevTime) > TimeSpan.FromSeconds(2)) { TimeSpan diffTime = currTime - prevTime; double diffTotalSeconds = Math.Floor(diffTime.TotalSeconds); // keep track of extra needed ticks // we'll need these to catch up the background animation extraTicks = (int)diffTotalSeconds; // if we haven't passed a minute mark, simply decrement the seconds wiht the diff time if (diffTotalSeconds <= countdownCurrTime.Seconds) { countdownCurrTime.Seconds -= diffTime.Seconds; } else { // otherwise, do some math to figure out how many minutes and seconds to decrement int diffMinutes = ((int)Math.Floor((diffTotalSeconds - countdownCurrTime.Seconds) / 60) + 1); int diffSeconds = ((int)diffTotalSeconds - countdownCurrTime.Seconds - (60 * (diffMinutes - 1))); countdownCurrTime.Minutes -= diffMinutes; countdownCurrTime.Seconds = 60 - diffSeconds; } } if (countdownCurrTime.Seconds <= 0) { if (countdownCurrTime.Minutes <= 0) { EndTimer(); return; } countdownCurrTime.Minutes--; countdownCurrTime.Seconds = 59; } else { countdownCurrTime.Seconds--; } // increment the elapsed time percentage to update the background animation if (extraTicks > 0) { // something got off, so we need to account for the lost time // by artificially adding extra ticks for (int i = 0; i < extraTicks; i++) { timeBackground.TimeElapsedPercentage += percentageInterval; } // reset our extra ticks variable extraTicks = 0; } else { // just a normal tick timeBackground.TimeElapsedPercentage += percentageInterval; } // update the clock clockMinuteText.Text = ((countdownCurrTime.Minutes < 10 && !minutesOnly) ? "0" : "") + countdownCurrTime.Minutes.ToString(); clockSecondText.Text = ((countdownCurrTime.Seconds < 10) ? "0" : "") + countdownCurrTime.Seconds.ToString(); }