mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 05:53:10 +08:00
Refactor ReplayInputHandler creation for more flexibility.
This commit is contained in:
parent
0f4b98ce73
commit
fa7c72a099
@ -15,7 +15,7 @@ using osu.Game.Modes.Replays;
|
||||
|
||||
namespace osu.Game.Modes.Osu
|
||||
{
|
||||
public class OsuAutoReplay : FramedReplay
|
||||
public class OsuAutoReplay : Replay
|
||||
{
|
||||
private static readonly Vector2 spinner_centre = new Vector2(256, 192);
|
||||
|
||||
|
@ -101,7 +101,7 @@ namespace osu.Game.Database
|
||||
|
||||
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
|
||||
using (var reader = new StreamReader(lzma))
|
||||
score.Replay = score.CreateLegacyReplayFrom(reader);
|
||||
score.Replay = score.CreateReplay(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ namespace osu.Game.Modes.Mods
|
||||
|
||||
public void Apply(HitRenderer<T> hitRenderer)
|
||||
{
|
||||
hitRenderer.InputManager.ReplayInputHandler = CreateReplayScore(hitRenderer.Beatmap)?.Replay?.CreateInputHandler();
|
||||
hitRenderer.SetReplay(CreateReplayScore(hitRenderer.Beatmap)?.Replay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Input.Handlers;
|
||||
|
||||
namespace osu.Game.Modes.Replays
|
||||
{
|
||||
public abstract class FramedReplay : Replay
|
||||
{
|
||||
protected List<ReplayFrame> Frames = new List<ReplayFrame>();
|
||||
|
||||
public override ReplayInputHandler CreateInputHandler() => new FramedReplayInputHandler(Frames);
|
||||
}
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
using System;
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Input;
|
||||
@ -17,18 +20,20 @@ namespace osu.Game.Modes.Replays
|
||||
/// </summary>
|
||||
public class FramedReplayInputHandler : ReplayInputHandler
|
||||
{
|
||||
private readonly List<ReplayFrame> replayContent;
|
||||
private readonly Replay replay;
|
||||
|
||||
public ReplayFrame CurrentFrame => !hasFrames ? null : replayContent[currentFrameIndex];
|
||||
public ReplayFrame NextFrame => !hasFrames ? null : replayContent[nextFrameIndex];
|
||||
protected List<ReplayFrame> Frames => replay.Frames;
|
||||
|
||||
public ReplayFrame CurrentFrame => !hasFrames ? null : Frames[currentFrameIndex];
|
||||
public ReplayFrame NextFrame => !hasFrames ? null : Frames[nextFrameIndex];
|
||||
|
||||
private int currentFrameIndex;
|
||||
|
||||
private int nextFrameIndex => MathHelper.Clamp(currentFrameIndex + (currentDirection > 0 ? 1 : -1), 0, replayContent.Count - 1);
|
||||
private int nextFrameIndex => MathHelper.Clamp(currentFrameIndex + (currentDirection > 0 ? 1 : -1), 0, Frames.Count - 1);
|
||||
|
||||
public FramedReplayInputHandler(List<ReplayFrame> replayContent)
|
||||
public FramedReplayInputHandler(Replay replay)
|
||||
{
|
||||
this.replayContent = replayContent;
|
||||
this.replay = replay;
|
||||
}
|
||||
|
||||
private bool advanceFrame()
|
||||
@ -75,7 +80,7 @@ namespace osu.Game.Modes.Replays
|
||||
};
|
||||
}
|
||||
|
||||
public bool AtLastFrame => currentFrameIndex == replayContent.Count - 1;
|
||||
public bool AtLastFrame => currentFrameIndex == Frames.Count - 1;
|
||||
public bool AtFirstFrame => currentFrameIndex == 0;
|
||||
|
||||
public Vector2 Size => new Vector2(512, 384);
|
||||
@ -91,7 +96,7 @@ namespace osu.Game.Modes.Replays
|
||||
/// </summary>
|
||||
public bool FrameAccuratePlayback = true;
|
||||
|
||||
private bool hasFrames => replayContent.Count > 0;
|
||||
private bool hasFrames => Frames.Count > 0;
|
||||
|
||||
private bool inImportantSection =>
|
||||
FrameAccuratePlayback &&
|
||||
|
@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using osu.Game.IO.Legacy;
|
||||
|
||||
namespace osu.Game.Modes.Replays
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a replay from a legacy replay file (.osr v1)
|
||||
/// </summary>
|
||||
public class LegacyFramedReplay : FramedReplay
|
||||
{
|
||||
public LegacyFramedReplay(StreamReader reader)
|
||||
{
|
||||
float lastTime = 0;
|
||||
|
||||
foreach (var l in reader.ReadToEnd().Split(','))
|
||||
{
|
||||
var split = l.Split('|');
|
||||
|
||||
if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
|
||||
|
||||
lastTime += float.Parse(split[0]);
|
||||
|
||||
Frames.Add(new ReplayFrame(
|
||||
lastTime,
|
||||
float.Parse(split[1]),
|
||||
384 - float.Parse(split[2]),
|
||||
(ReplayButtonState)int.Parse(split[3])
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public class LegacyReplayFrame : ReplayFrame
|
||||
{
|
||||
public LegacyReplayFrame(Stream s) : this(new SerializationReader(s))
|
||||
{
|
||||
}
|
||||
|
||||
public LegacyReplayFrame(SerializationReader sr)
|
||||
{
|
||||
ButtonState = (ReplayButtonState)sr.ReadByte();
|
||||
|
||||
byte bt = sr.ReadByte();
|
||||
if (bt > 0)//Handle Pre-Taiko compatible replays.
|
||||
ButtonState = ReplayButtonState.Right1;
|
||||
|
||||
MouseX = sr.ReadSingle();
|
||||
MouseY = sr.ReadSingle();
|
||||
Time = sr.ReadInt32();
|
||||
}
|
||||
|
||||
public void ReadFromStream(SerializationReader sr)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteToStream(SerializationWriter sw)
|
||||
{
|
||||
sw.Write((byte)ButtonState);
|
||||
sw.Write((byte)0);
|
||||
sw.Write(MouseX);
|
||||
sw.Write(MouseY);
|
||||
sw.Write(Time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Input.Handlers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Modes.Replays
|
||||
{
|
||||
public abstract class Replay
|
||||
public class Replay
|
||||
{
|
||||
public virtual ReplayInputHandler CreateInputHandler() => null;
|
||||
public List<ReplayFrame> Frames = new List<ReplayFrame>();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Modes.Mods;
|
||||
@ -46,11 +47,34 @@ namespace osu.Game.Modes.Scoring
|
||||
public DateTime Date;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a legacy replay which is read from a stream.
|
||||
/// Creates a replay which is read from a stream.
|
||||
/// </summary>
|
||||
/// <param name="reader">The stream reader.</param>
|
||||
/// <returns>The replay.</returns>
|
||||
public virtual Replay CreateLegacyReplayFrom(StreamReader reader) => new LegacyFramedReplay(reader);
|
||||
public virtual Replay CreateReplay(StreamReader reader)
|
||||
{
|
||||
var frames = new List<ReplayFrame>();
|
||||
|
||||
float lastTime = 0;
|
||||
|
||||
foreach (var l in reader.ReadToEnd().Split(','))
|
||||
{
|
||||
var split = l.Split('|');
|
||||
|
||||
if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
|
||||
|
||||
lastTime += float.Parse(split[0]);
|
||||
|
||||
frames.Add(new ReplayFrame(
|
||||
lastTime,
|
||||
float.Parse(split[1]),
|
||||
384 - float.Parse(split[2]),
|
||||
(ReplayButtonState)int.Parse(split[3])
|
||||
));
|
||||
}
|
||||
|
||||
return new Replay { Frames = frames };
|
||||
}
|
||||
|
||||
// [JsonProperty(@"count50")] 0,
|
||||
//[JsonProperty(@"count100")] 0,
|
||||
|
@ -14,6 +14,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Game.Modes.Replays;
|
||||
using osu.Game.Modes.Scoring;
|
||||
|
||||
namespace osu.Game.Modes.UI
|
||||
@ -68,6 +69,10 @@ namespace osu.Game.Modes.UI
|
||||
/// </summary>
|
||||
/// <returns>The input manager.</returns>
|
||||
protected virtual KeyConversionInputManager CreateKeyConversionInputManager() => new KeyConversionInputManager();
|
||||
|
||||
protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay);
|
||||
|
||||
public void SetReplay(Replay replay) => InputManager.ReplayInputHandler = CreateReplayInputHandler(replay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -125,7 +125,7 @@ namespace osu.Game
|
||||
|
||||
Beatmap.Value = BeatmapDatabase.GetWorkingBeatmap(s.Beatmap);
|
||||
|
||||
menu.Push(new PlayerLoader(new Player { ReplayInputHandler = s.Replay.CreateInputHandler() }));
|
||||
menu.Push(new PlayerLoader(new ReplayPlayer(s.Replay)));
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -15,7 +15,6 @@ using osu.Framework.Screens;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Input.Handlers;
|
||||
using osu.Game.Modes;
|
||||
using osu.Game.Modes.UI;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
@ -34,7 +33,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
internal override bool HasLocalCursorDisplayed => !hasReplayLoaded && !IsPaused;
|
||||
|
||||
private bool hasReplayLoaded => hitRenderer.InputManager.ReplayInputHandler != null;
|
||||
private bool hasReplayLoaded => HitRenderer.InputManager.ReplayInputHandler != null;
|
||||
|
||||
public BeatmapInfo BeatmapInfo;
|
||||
|
||||
@ -53,7 +52,7 @@ namespace osu.Game.Screens.Play
|
||||
private Ruleset ruleset;
|
||||
|
||||
private ScoreProcessor scoreProcessor;
|
||||
private HitRenderer hitRenderer;
|
||||
protected HitRenderer HitRenderer;
|
||||
private Bindable<int> dimLevel;
|
||||
private SkipButton skipButton;
|
||||
|
||||
@ -112,9 +111,9 @@ namespace osu.Game.Screens.Play
|
||||
});
|
||||
|
||||
ruleset = Ruleset.GetRuleset(Beatmap.PlayMode);
|
||||
hitRenderer = ruleset.CreateHitRendererWith(Beatmap);
|
||||
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
|
||||
|
||||
scoreProcessor = hitRenderer.CreateScoreProcessor();
|
||||
scoreProcessor = HitRenderer.CreateScoreProcessor();
|
||||
|
||||
hudOverlay = new StandardHudOverlay();
|
||||
hudOverlay.KeyCounter.Add(ruleset.CreateGameplayKeys());
|
||||
@ -133,13 +132,10 @@ namespace osu.Game.Screens.Play
|
||||
};
|
||||
|
||||
|
||||
if (ReplayInputHandler != null)
|
||||
hitRenderer.InputManager.ReplayInputHandler = ReplayInputHandler;
|
||||
|
||||
hudOverlay.BindHitRenderer(hitRenderer);
|
||||
hudOverlay.BindHitRenderer(HitRenderer);
|
||||
|
||||
//bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
|
||||
hitRenderer.OnAllJudged += onCompletion;
|
||||
HitRenderer.OnAllJudged += onCompletion;
|
||||
|
||||
//bind ScoreProcessor to ourselves (for a fail situation)
|
||||
scoreProcessor.Failed += onFail;
|
||||
@ -152,7 +148,7 @@ namespace osu.Game.Screens.Play
|
||||
Clock = interpolatedSourceClock,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
hitRenderer,
|
||||
HitRenderer,
|
||||
skipButton = new SkipButton
|
||||
{
|
||||
Alpha = 0
|
||||
@ -336,8 +332,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private Bindable<bool> mouseWheelDisabled;
|
||||
|
||||
public ReplayInputHandler ReplayInputHandler;
|
||||
|
||||
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !IsPaused;
|
||||
}
|
||||
}
|
23
osu.Game/Screens/Play/ReplayPlayer.cs
Normal file
23
osu.Game/Screens/Play/ReplayPlayer.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Replays;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class ReplayPlayer : Player
|
||||
{
|
||||
public Replay Replay;
|
||||
|
||||
public ReplayPlayer(Replay replay)
|
||||
{
|
||||
Replay = replay;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
HitRenderer.SetReplay(Replay);
|
||||
}
|
||||
}
|
||||
}
|
@ -96,10 +96,9 @@
|
||||
<Compile Include="IO\Legacy\SerializationReader.cs" />
|
||||
<Compile Include="IO\Legacy\SerializationWriter.cs" />
|
||||
<Compile Include="IPC\ScoreIPCChannel.cs" />
|
||||
<Compile Include="Modes\Replays\FramedReplay.cs" />
|
||||
<Compile Include="Modes\Replays\Replay.cs" />
|
||||
<Compile Include="Modes\Judgements\DrawableJudgement.cs" />
|
||||
<Compile Include="Modes\Replays\FramedReplayInputHandler.cs" />
|
||||
<Compile Include="Modes\Replays\LegacyFramedReplay.cs" />
|
||||
<Compile Include="Modes\Mods\IApplicableMod.cs" />
|
||||
<Compile Include="Modes\Mods\ModType.cs" />
|
||||
<Compile Include="Modes\Objects\Drawables\ArmedState.cs" />
|
||||
@ -125,7 +124,6 @@
|
||||
<Compile Include="Modes\Objects\Types\IHasPosition.cs" />
|
||||
<Compile Include="Modes\Objects\Types\IHasHold.cs" />
|
||||
<Compile Include="Modes\Objects\Legacy\LegacyHitObjectType.cs" />
|
||||
<Compile Include="Modes\Replays\Replay.cs" />
|
||||
<Compile Include="Modes\Replays\ReplayButtonState.cs" />
|
||||
<Compile Include="Modes\Replays\ReplayFrame.cs" />
|
||||
<Compile Include="Modes\Scoring\Score.cs" />
|
||||
@ -202,6 +200,7 @@
|
||||
<Compile Include="Screens\Play\KeyConversionInputManager.cs" />
|
||||
<Compile Include="Screens\Play\PlayerInputManager.cs" />
|
||||
<Compile Include="Screens\Play\PlayerLoader.cs" />
|
||||
<Compile Include="Screens\Play\ReplayPlayer.cs" />
|
||||
<Compile Include="Screens\Play\SkipButton.cs" />
|
||||
<Compile Include="Modes\UI\StandardComboCounter.cs" />
|
||||
<Compile Include="Screens\Select\BeatmapCarousel.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user