Skip to content

Commit

Permalink
1. Create IPatternGenerator to batch calculate like calculate karao…
Browse files Browse the repository at this point in the history
…ke text's layout and start time.

2. Fix lyric's start time issue.
  • Loading branch information
andy840119 committed Jul 5, 2020
1 parent 4534ba4 commit 8566b15
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 73 deletions.
11 changes: 6 additions & 5 deletions osu.Game.Rulesets.Karaoke/Beatmaps/Formats/LrcDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ protected override void ParseStreamInto(LineBufferedReader stream, Beatmap outpu
var startTime = timeTags.FirstOrDefault(x => x.Time > 0).Time;
var duration = timeTags.LastOrDefault(x => x.Time > 0).Time - startTime;

var lyric = line.Text;
output.HitObjects.Add(new LyricLine
var lyric = new LyricLine
{
Text = lyric,
Text = line.Text,
// Start time and end time should be re-assigned
StartTime = startTime,
Duration = duration,
Expand All @@ -59,13 +58,15 @@ protected override void ParseStreamInto(LineBufferedReader stream, Beatmap outpu

return new TimeTagIndex(index, state);
}, v => (double)v.Time),
RubyTags = result.QueryRubies(lyric).Select(ruby => new RubyTag
RubyTags = result.QueryRubies(line.Text).Select(ruby => new RubyTag
{
Text = ruby.Ruby.Ruby,
StartIndex = ruby.StartIndex,
EndIndex = ruby.EndIndex
}).ToArray()
});
};
lyric.InitialWorkingTime();
output.HitObjects.Add(lyric);
}
catch (Exception ex)
{
Expand Down
70 changes: 3 additions & 67 deletions osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Beatmaps.Patterns;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps
Expand All @@ -24,73 +25,8 @@ public override void PostProcess()
if (!lyrics.Any())
return;

// re-arrange layout
layoutArrangement(lyrics);
}

/// <summary>
/// Calculate arrangement and assign layout number
/// </summary>
/// <example>
/// Lyric | Anchor | LayoutIndex |
/// ----------------------------------------
/// **** (left) 1
/// ***** (right) 0
/// -----------
/// ******* (left) 3
/// ***** (left) 4
/// ***** (left) 5
/// -----------
/// ******* (left) 6
/// ***** (left) 7
/// ****** (right) 8
/// **** (right) 9
/// -----------
/// ****** (left) 10
/// ****** (right) 11
/// ****** (left) 12
/// ****** (right) 13
/// </example>
/// <param name="lyrics"></param>
/// <param name="bottomOnly"></param>
private void layoutArrangement(IList<LyricLine> lyrics, bool bottomOnly = false)
{
// Force change to new line if lyric has long time
const int new_lyric_line_time = 15000;
const int number_of_line = 2;

// Apply layout index
for (int i = 0; i < lyrics.Count; i++)
{
var previousCycleLyric = i >= number_of_line ? lyrics[i - number_of_line] : null;
var previousLyric = i >= 1 ? lyrics[i - 1] : null;
var lyric = lyrics[i];

// Force change layout
if (lyric.StartTime - previousLyric?.EndTime > new_lyric_line_time)
lyric.LayoutIndex = 1;
// Change to next layout
else if (previousLyric?.LayoutIndex == 1)
lyric.LayoutIndex = 0;
// Change to first layout index
else
lyric.LayoutIndex = 1;
}

// Apply start time
for (int i = 0; i < lyrics.Count; i++)
{
var lastLyricLine = i >= number_of_line ? lyrics[i - number_of_line] : null;
var lyricLine = lyrics[i];

if (lastLyricLine != null)
{
// Adjust start time and end time
lyricLine.StartTime = lastLyricLine.EndTime + 1000;
}
}

// TODO : Apply end time?
var pattern = new LegacyKaraokeLayoutGenerator();
pattern.Generate(lyrics);
}
}
}
12 changes: 12 additions & 0 deletions osu.Game.Rulesets.Karaoke/Beatmaps/Patterns/IPatternGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Patterns
{
public interface IPatternGenerator<T>
{
void Generate(IEnumerable<T> hitObjects);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Rulesets.Karaoke.Objects;
using System.Collections.Generic;
using System.Linq;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Patterns
{
public class LegacyKaraokeLayoutGenerator : IPatternGenerator<LyricLine>
{
private const int number_of_line = 2;

public void Generate(IEnumerable<LyricLine> hitObjects)
{
var lyrics = hitObjects.ToList();

// Re-arrange layout
assignLayoutArrangement(lyrics);

// Re-assign time
assignLyricTime(lyrics);
}

/// <summary>
/// Calculate arrangement and assign layout number
/// </summary>
/// <example>
/// Lyric | Anchor | LayoutIndex |
/// ----------------------------------------
/// **** (left) 1
/// ***** (right) 0
/// -----------
/// ******* (left) 3
/// ***** (left) 4
/// ***** (left) 5
/// -----------
/// ******* (left) 6
/// ***** (left) 7
/// ****** (right) 8
/// **** (right) 9
/// -----------
/// ****** (left) 10
/// ****** (right) 11
/// ****** (left) 12
/// ****** (right) 13
/// </example>
/// <param name="lyrics"></param>
/// <param name="bottomOnly"></param>
private void assignLayoutArrangement(IList<LyricLine> lyrics, bool bottomOnly = false)
{
// Force change to new line if lyric has long time
const int new_lyric_line_time = 15000;

// Apply layout index
for (int i = 0; i < lyrics.Count; i++)
{
var previousCycleLyric = i >= number_of_line ? lyrics[i - number_of_line] : null;
var previousLyric = i >= 1 ? lyrics[i - 1] : null;
var lyric = lyrics[i];

// Force change layout
if (lyric.StartTime - previousLyric?.EndTime > new_lyric_line_time)
lyric.LayoutIndex = 1;
// Change to next layout
else if (previousLyric?.LayoutIndex == 1)
lyric.LayoutIndex = 0;
// Change to first layout index
else
lyric.LayoutIndex = 1;
}
}

private void assignLyricTime(IList<LyricLine> lyrics)
{
// Reset working time
lyrics.ForEach(h => h.InitialWorkingTime());

// Apply start time
for (int i = 0; i < lyrics.Count; i++)
{
var lastLyricLine = i >= number_of_line ? lyrics[i - number_of_line] : null;
var lyricLine = lyrics[i];

if (lastLyricLine != null)
{
// Adjust start time and end time
var lyricEndTime = lyricLine.EndTime;
lyricLine.StartTime = lastLyricLine.EndTime + 1000;

// Should re-assign duration here
lyricLine.Duration = lyricEndTime - lyricLine.StartTime;
}
}
}
}
}
27 changes: 26 additions & 1 deletion osu.Game.Rulesets.Karaoke/Objects/LyricLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Judgements;
using osu.Game.Rulesets.Objects.Types;

Expand Down Expand Up @@ -69,7 +72,12 @@ public RomajiTag[] RomajiTags
}

/// <summary>
/// Duration
/// Lyric's start time is created from <see cref="KaraokeBeatmapProcessor"/> and should not be saved.
/// </summary>
public override double StartTime { get => base.StartTime; set => base.StartTime = value; }

/// <summary>
/// Lyric's duration is created from <see cref="KaraokeBeatmapProcessor"/> and should not be saved.
/// </summary>
public double Duration { get; set; }

Expand Down Expand Up @@ -150,5 +158,22 @@ public IEnumerable<Note> CreateDefaultNotes()
}

public override Judgement CreateJudgement() => new KaraokeLyricJudgement();

protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);

// Add because it will cause error on exit then enter gameplay.
StartTimeBindable.UnbindAll();

// Initial working start and end time.
InitialWorkingTime();
}

public void InitialWorkingTime()
{
StartTime = LyricStartTime;
Duration = LyricDuration;
}
}
}

0 comments on commit 8566b15

Please sign in to comment.