Skip to content

Commit

Permalink
Merge pull request #118 from frenzibyte/replay-recorder
Browse files Browse the repository at this point in the history
Add replay recording support
  • Loading branch information
LumpBloom7 authored Apr 10, 2021
2 parents d0c8ee9 + 6c15310 commit 04a4dee
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
28 changes: 28 additions & 0 deletions osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Rush.Replays;

namespace osu.Game.Rulesets.Rush.Tests.Replay
{
[TestFixture]
public class RushReplayFrameTest
{
[TestCase]
[TestCase(RushAction.AirPrimary, RushAction.GroundPrimary)]
[TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.GroundQuaternary)]
[TestCase(RushAction.GroundPrimary, RushAction.GroundSecondary)]
[TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.AirTertiary, RushAction.AirQuaternary, RushAction.GroundPrimary, RushAction.GroundSecondary, RushAction.GroundTertiary, RushAction.GroundTertiary)]
public void TestParity(params RushAction[] actions)
{
var originalFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame();
var resultFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame();

resultFrame.FromLegacy(originalFrame.ToLegacy(new Beatmap()), new Beatmap());

Assert.That(resultFrame.Actions, Is.EquivalentTo(originalFrame.Actions));
}
}
}
33 changes: 32 additions & 1 deletion osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Diagnostics;
using osu.Game.Beatmaps;
using osu.Game.Replays.Legacy;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;

namespace osu.Game.Rulesets.Rush.Replays
{
public class RushReplayFrame : ReplayFrame
public class RushReplayFrame : ReplayFrame, IConvertibleReplayFrame
{
public List<RushAction> Actions = new List<RushAction>();

Expand All @@ -26,5 +30,32 @@ public RushReplayFrame(double time, IEnumerable<RushAction> buttons)
{
Actions.AddRange(buttons);
}

public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
{
Debug.Assert(currentFrame.MouseX != null);

uint flags = (uint)currentFrame.MouseX;

int currentBit = 0;

while (flags > 0)
{
if ((flags & 1) > 0)
Actions.Add((RushAction)currentBit);

++currentBit;
flags >>= 1;
}
}

public LegacyReplayFrame ToLegacy(IBeatmap beatmap)
{
uint flags = 0;
foreach (var action in Actions)
flags |= 1u << (int)action;

return new LegacyReplayFrame(Time, flags, 0f, ReplayButtonState.None);
}
}
}
16 changes: 8 additions & 8 deletions osu.Game.Rulesets.Rush/RushInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,28 @@ public RushInputManager(RulesetInfo ruleset)
public enum RushAction
{
[Description("Ground (Primary)")]
GroundPrimary,
GroundPrimary = 0,

[Description("Ground (Secondary)")]
GroundSecondary,
GroundSecondary = 1,

[Description("Ground (Tertiary)")]
GroundTertiary,
GroundTertiary = 2,

[Description("Ground (Quaternary)")]
GroundQuaternary,
GroundQuaternary = 3,

[Description("Air (Primary)")]
AirPrimary,
AirPrimary = 4,

[Description("Air (Secondary)")]
AirSecondary,
AirSecondary = 5,

[Description("Air (Tertiary)")]
AirTertiary,
AirTertiary = 6,

[Description("Air (Quaternary)")]
AirQuaternary
AirQuaternary = 7
}

public static class RushActionExtensions
Expand Down
4 changes: 4 additions & 0 deletions osu.Game.Rulesets.Rush/RushRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.Rush.Beatmaps;
using osu.Game.Rulesets.Rush.Mods;
using osu.Game.Rulesets.Rush.Replays;
using osu.Game.Rulesets.Rush.Scoring;
using osu.Game.Rulesets.Rush.UI;
using osu.Game.Rulesets.Scoring;
Expand Down Expand Up @@ -88,6 +90,8 @@ public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) =
new KeyBinding(InputKey.MouseLeft, RushAction.AirPrimary),
};

public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new RushReplayFrame();

public override Drawable CreateIcon() => new RushIcon();

public class RushIcon : CompositeDrawable
Expand Down
3 changes: 3 additions & 0 deletions osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using osu.Game.Rulesets.Rush.Replays;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Scoring;

namespace osu.Game.Rulesets.Rush.UI
{
Expand All @@ -39,6 +40,8 @@ public DrawableRushRuleset(RushRuleset ruleset, IBeatmap beatmap, IReadOnlyList<

protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new RushFramedReplayInputHandler(replay);

protected override ReplayRecorder CreateReplayRecorder(Score score) => new RushReplayRecorder(score);

public new RushPlayfield Playfield => (RushPlayfield)base.Playfield;

public override DrawableHitObject<RushHitObject> CreateDrawableRepresentation(RushHitObject h)
Expand Down
23 changes: 23 additions & 0 deletions osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Rush.Replays;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
using osuTK;

namespace osu.Game.Rulesets.Rush.UI
{
public class RushReplayRecorder : ReplayRecorder<RushAction>
{
public RushReplayRecorder(Score target)
: base(target)
{
}

protected override ReplayFrame HandleFrame(Vector2 mousePosition, List<RushAction> actions, ReplayFrame previousFrame)
=> new RushReplayFrame(Time.Current, actions);
}
}

0 comments on commit 04a4dee

Please sign in to comment.