From 3467cc6b94c83a08898b61e9a1fd7956b390d4d3 Mon Sep 17 00:00:00 2001 From: MikiraSora Date: Wed, 4 Sep 2024 01:53:55 +0800 Subject: [PATCH] add DrawPlayerLocationHelper --- OngekiFumenEditor/App.config | 3 + OngekiFumenEditor/App.xaml | 2 +- .../FumenVisualEditorGlobalSettingView.xaml | 49 +- .../Editors/DrawPlayerLocationHelper.cs | 69 ++ .../FumenVisualEditorViewModel.Drawing.cs | 780 +++++++++--------- .../Views/OngekiObjects/playerLoc.png | Bin 0 -> 691 bytes OngekiFumenEditor/OngekiFumenEditor.csproj | 6 +- .../EditorGlobalSetting.Designer.cs | 14 +- .../Properties/EditorGlobalSetting.settings | 3 + .../Properties/Resources.Designer.cs | 9 + .../Properties/Resources.ja.resx | 305 +++---- OngekiFumenEditor/Properties/Resources.resx | 3 + .../Properties/Resources.zh-Hans.resx | 3 + 13 files changed, 700 insertions(+), 546 deletions(-) create mode 100644 OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/Editors/DrawPlayerLocationHelper.cs create mode 100644 OngekiFumenEditor/Modules/FumenVisualEditor/Views/OngekiObjects/playerLoc.png diff --git a/OngekiFumenEditor/App.config b/OngekiFumenEditor/App.config index ffc24a55..92e5f623 100644 --- a/OngekiFumenEditor/App.config +++ b/OngekiFumenEditor/App.config @@ -152,6 +152,9 @@ False + + False + diff --git a/OngekiFumenEditor/App.xaml b/OngekiFumenEditor/App.xaml index 7770166a..92b421c9 100644 --- a/OngekiFumenEditor/App.xaml +++ b/OngekiFumenEditor/App.xaml @@ -31,7 +31,7 @@ - + diff --git a/OngekiFumenEditor/Kernel/SettingPages/FumenVisualEditor/Views/FumenVisualEditorGlobalSettingView.xaml b/OngekiFumenEditor/Kernel/SettingPages/FumenVisualEditor/Views/FumenVisualEditorGlobalSettingView.xaml index ce80b4fc..c71fe90d 100644 --- a/OngekiFumenEditor/Kernel/SettingPages/FumenVisualEditor/Views/FumenVisualEditorGlobalSettingView.xaml +++ b/OngekiFumenEditor/Kernel/SettingPages/FumenVisualEditor/Views/FumenVisualEditorGlobalSettingView.xaml @@ -7,14 +7,15 @@ xmlns:markup="clr-namespace:OngekiFumenEditor.UI.Markup" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:res="clr-namespace:OngekiFumenEditor.Properties" - xmlns:vm="clr-namespace:OngekiFumenEditor.Kernel.SettingPages.FumenVisualEditor.ViewModels" xmlns:valueconverters="clr-namespace:OngekiFumenEditor.Kernel.SettingPages.FumenVisualEditor.ValueConverters" + xmlns:valueconverters="clr-namespace:OngekiFumenEditor.Kernel.SettingPages.FumenVisualEditor.ValueConverters" + xmlns:vm="clr-namespace:OngekiFumenEditor.Kernel.SettingPages.FumenVisualEditor.ViewModels" d:Background="White" d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:FumenVisualEditorGlobalSettingViewModel}" d:DesignWidth="800" mc:Ignorable="d"> - + @@ -99,30 +100,54 @@ - + + Width="50" + Margin="5,0,5,0" + Text="{Binding Setting.ParallelCountLimit}"> - - + + - + - - - + + + + + + diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/Editors/DrawPlayerLocationHelper.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/Editors/DrawPlayerLocationHelper.cs new file mode 100644 index 00000000..50aa1165 --- /dev/null +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/Editors/DrawPlayerLocationHelper.cs @@ -0,0 +1,69 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Numerics; +using Caliburn.Micro; +using OngekiFumenEditor.Base; +using OngekiFumenEditor.Base.EditorObjects; +using OngekiFumenEditor.Kernel.Graphics; +using OngekiFumenEditor.Kernel.Graphics.Base; +using OngekiFumenEditor.Utils; + +namespace OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing.Editors; + +public class DrawPlayerLocationHelper +{ + private readonly (Vector2 size, Vector2 position, float rotation)[] arr = { default }; + private readonly Texture texture; + private readonly ITextureDrawing textureDrawing; + private bool enableShowPlayerLocation; + + public DrawPlayerLocationHelper() + { + textureDrawing = IoC.Get(); + arr[0].size = new Vector2(48, 48); + arr[0].rotation = 0f; + + texture = ResourceUtils.OpenReadTextureFromResource(@"Modules\FumenVisualEditor\Views\OngekiObjects\playerLoc.png"); + + UpdateProps(); + Properties.EditorGlobalSetting.Default.PropertyChanged += Default_PropertyChanged; + } + + private void UpdateProps() + { + enableShowPlayerLocation = Properties.EditorGlobalSetting.Default.EnableShowPlayerLocation; + } + + private void Default_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + switch (e.PropertyName) + { + case nameof(Properties.EditorGlobalSetting.EnableShowPlayerLocation): + UpdateProps(); + break; + default: + break; + } + } + + public void Draw(IFumenEditorDrawingContext target) + { + if (target.Editor.IsDesignMode) + return; + if (!enableShowPlayerLocation) + return; + + var tGrid = TGridCalculator.ConvertAudioTimeToTGrid(target.CurrentPlayTime, target.Editor); + var apfLane = target.Editor.Fumen.Lanes.GetVisibleStartObjects(tGrid, tGrid).OfType() + .LastOrDefault(); + var xGrid = apfLane?.CalulateXGrid(tGrid) ?? XGrid.Zero; + + var x = XGridCalculator.ConvertXGridToX(xGrid, target.Editor); + var y = target.ConvertToY(tGrid); + + arr[0].position = new Vector2((float)x, (float)y); + + textureDrawing.Draw(target, texture, arr); + } +} \ No newline at end of file diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.Drawing.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.Drawing.cs index 46ae5caf..a7ee96b2 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.Drawing.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.Drawing.cs @@ -1,7 +1,14 @@ -using Caliburn.Micro; -using Gemini.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using Caliburn.Micro; +using Gemini.Framework; using OngekiFumenEditor.Base; -using OngekiFumenEditor.Base.Collections; using OngekiFumenEditor.Base.OngekiObjects; using OngekiFumenEditor.Base.OngekiObjects.Beam; using OngekiFumenEditor.Kernel.Graphics; @@ -10,490 +17,505 @@ using OngekiFumenEditor.Modules.FumenVisualEditor.Graphics; using OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing; using OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing.Editors; +using OngekiFumenEditor.Properties; using OngekiFumenEditor.UI.Controls; -using OngekiFumenEditor.Utils; -using OngekiFumenEditor.Utils.ObjectPool; +using OngekiFumenEditor.Utils; using OpenTK.Graphics.OpenGL; using OpenTK.Mathematics; using OpenTK.Wpf; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Media; using static OngekiFumenEditor.Kernel.Graphics.IDrawingContext; using static OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing.Editors.DrawXGridHelper; +using Color = System.Drawing.Color; +using Vector4 = System.Numerics.Vector4; + +namespace OngekiFumenEditor.Modules.FumenVisualEditor.ViewModels; -namespace OngekiFumenEditor.Modules.FumenVisualEditor.ViewModels +public partial class FumenVisualEditorViewModel : PersistedDocument, ISchedulable, IFumenEditorDrawingContext { - public partial class FumenVisualEditorViewModel : PersistedDocument, ISchedulable, IFumenEditorDrawingContext - { - private IPerfomenceMonitor dummyPerformenceMonitor = new DummyPerformenceMonitor(); - private IPerfomenceMonitor actualPerformenceMonitor; + private static Dictionary drawTargets = new(); + private IPerfomenceMonitor actualPerformenceMonitor; + + private readonly List cachedMagneticXGridLines = new(); + + private Func + convertToY = TGridCalculator.ConvertTGridUnitToY_DesignMode; - private DrawTimeSignatureHelper timeSignatureHelper; - private DrawXGridHelper xGridHelper; - private DrawJudgeLineHelper judgeLineHelper; - private DrawSelectingRangeHelper selectingRangeHelper; - private DrawPlayableAreaHelper playableAreaHelper; + private string displayFPS = ""; + private readonly Dictionary> drawMap = new(); + private IFumenEditorDrawingTarget[] drawTargetOrder; + private readonly IPerfomenceMonitor dummyPerformenceMonitor = new DummyPerformenceMonitor(); + private bool enablePlayFieldDrawing; - private Func convertToY = TGridCalculator.ConvertTGridUnitToY_DesignMode; + private bool isDisplayFPS; + private DrawJudgeLineHelper judgeLineHelper; + private DrawPlayableAreaHelper playableAreaHelper; + private DrawPlayerLocationHelper playerLocationHelper; + private Vector4 playFieldBackgroundColor; + private int renderViewHeight; - private StringBuilder stringBuilder = new StringBuilder(2048); + private int renderViewWidth; + private DrawSelectingRangeHelper selectingRangeHelper; - private List cachedMagneticXGridLines = new(); - public IEnumerable CachedMagneticXGridLines => cachedMagneticXGridLines; + private readonly StringBuilder stringBuilder = new(2048); - private int renderViewWidth; - private int renderViewHeight; - private System.Numerics.Vector4 playFieldBackgroundColor; - private bool enablePlayFieldDrawing; - private float viewWidth = 0; - public float ViewWidth + private DrawTimeSignatureHelper timeSignatureHelper; + + private float viewHeight; + private float viewWidth; + + private readonly List<(TGrid minTGrid, TGrid maxTGrid)> visibleTGridRanges = new(); + private DrawXGridHelper xGridHelper; + public IEnumerable CachedMagneticXGridLines => cachedMagneticXGridLines; + + public bool IsDisplayFPS + { + get => isDisplayFPS; + set { - get => viewWidth; - set - { - Set(ref viewWidth, value); - RecalcViewProjectionMatrix(); - } + Set(ref isDisplayFPS, value); + PerfomenceMonitor = value ? actualPerformenceMonitor : dummyPerformenceMonitor; } + } - private float viewHeight = 0; - public float ViewHeight + public string DisplayFPS + { + get => displayFPS; + set { - get => viewHeight; - set - { - Set(ref viewHeight, value); - RecalcViewProjectionMatrix(); - } + displayFPS = value; + NotifyOfPropertyChange(() => DisplayFPS); } + } - public TimeSpan CurrentPlayTime { get; private set; } = TimeSpan.FromSeconds(0); - - private bool isDisplayFPS = false; - public bool IsDisplayFPS + public float ViewWidth + { + get => viewWidth; + set { - get => isDisplayFPS; - set - { - Set(ref isDisplayFPS, value); - PerfomenceMonitor = value ? actualPerformenceMonitor : dummyPerformenceMonitor; - } + Set(ref viewWidth, value); + RecalcViewProjectionMatrix(); } + } - private string displayFPS = ""; - public string DisplayFPS + public float ViewHeight + { + get => viewHeight; + set { - get => displayFPS; - set - { - displayFPS = value; - NotifyOfPropertyChange(() => DisplayFPS); - } + Set(ref viewHeight, value); + RecalcViewProjectionMatrix(); } + } - public Matrix4 ViewMatrix { get; private set; } - public Matrix4 ProjectionMatrix { get; private set; } - public Matrix4 ViewProjectionMatrix { get; private set; } + public TimeSpan CurrentPlayTime { get; private set; } = TimeSpan.FromSeconds(0); - public string SchedulerName => "Fumen Previewer Performance Statictis"; + public Matrix4 ViewMatrix { get; private set; } + public Matrix4 ProjectionMatrix { get; private set; } + public Matrix4 ViewProjectionMatrix { get; private set; } - public TimeSpan ScheduleCallLoopInterval => TimeSpan.FromSeconds(1); + public FumenVisualEditorViewModel Editor => this; - public FumenVisualEditorViewModel Editor => this; + public VisibleRect Rect { get; set; } - public VisibleRect Rect { get; set; } = default; + public IPerfomenceMonitor PerfomenceMonitor { get; private set; } = new DummyPerformenceMonitor(); - public IPerfomenceMonitor PerfomenceMonitor { get; private set; } = new DummyPerformenceMonitor(); + public void OnRenderSizeChanged(GLWpfControl glView, SizeChangedEventArgs sizeArg) + { + Log.LogDebug($"new size: {sizeArg.NewSize} , glView.RenderSize = {glView.RenderSize}"); - private static Dictionary drawTargets = new(); - private IFumenEditorDrawingTarget[] drawTargetOrder; - private Dictionary> drawMap = new(); + var dpiX = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleX; + var dpiY = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleY; - protected override void OnViewLoaded(object v) - { - base.OnViewLoaded(v); - InitExtraMenuItems(); - } + ViewWidth = (float) sizeArg.NewSize.Width; + ViewHeight = (float) sizeArg.NewSize.Height; + renderViewWidth = (int) (sizeArg.NewSize.Width * dpiX); + renderViewHeight = (int) (sizeArg.NewSize.Height * dpiY); + } - private void RecalcViewProjectionMatrix() - { - var xOffset = 0; + public async void PrepareRender(GLWpfControl openGLView) + { + Log.LogDebug("ready."); + await IoC.Get().CheckOrInitGraphics(); - var y = (float)convertToY(GetCurrentTGrid().TotalUnit, this); + var dpiX = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleX; + var dpiY = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleY; - ProjectionMatrix = - Matrix4.CreateOrthographic(ViewWidth, ViewHeight, -1, 1); - ViewMatrix = - Matrix4.CreateTranslation(new Vector3(-ViewWidth / 2 + xOffset, -y - ViewHeight / 2 + (float)Setting.JudgeLineOffsetY, 0)); + ViewWidth = (float) openGLView.ActualWidth; + ViewHeight = (float) openGLView.ActualHeight; - ViewProjectionMatrix = ViewMatrix * ProjectionMatrix; - } + renderViewWidth = (int) (openGLView.ActualWidth * dpiX); + renderViewHeight = (int) (openGLView.ActualHeight * dpiY); - public void OnRenderSizeChanged(GLWpfControl glView, SizeChangedEventArgs sizeArg) - { - Log.LogDebug($"new size: {sizeArg.NewSize} , glView.RenderSize = {glView.RenderSize}"); + playFieldBackgroundColor = Color.FromArgb(EditorGlobalSetting.Default.PlayFieldBackgroundColor).ToVector4(); + enablePlayFieldDrawing = EditorGlobalSetting.Default.EnablePlayFieldDrawing; - var dpiX = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleX; - var dpiY = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleY; + drawTargets = IoC.GetAll() + .SelectMany(target => target.DrawTargetID.Select(supportId => (supportId, target))) + .GroupBy(x => x.supportId).ToDictionary(x => x.Key, x => x.Select(x => x.target).ToArray()); - ViewWidth = (float)sizeArg.NewSize.Width; - ViewHeight = (float)sizeArg.NewSize.Height; - renderViewWidth = (int)(sizeArg.NewSize.Width * dpiX); - renderViewHeight = (int)(sizeArg.NewSize.Height * dpiY); - } + ResortRenderOrder(); - public async void PrepareRender(GLWpfControl openGLView) - { - Log.LogDebug($"ready."); - await IoC.Get().CheckOrInitGraphics(); + timeSignatureHelper = new DrawTimeSignatureHelper(); + xGridHelper = new DrawXGridHelper(); + judgeLineHelper = new DrawJudgeLineHelper(); + selectingRangeHelper = new DrawSelectingRangeHelper(); + playableAreaHelper = new DrawPlayableAreaHelper(); + playerLocationHelper = new DrawPlayerLocationHelper(); - var dpiX = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleX; - var dpiY = VisualTreeHelper.GetDpi(Application.Current.MainWindow).DpiScaleY; + actualPerformenceMonitor = IoC.Get(); + IsDisplayFPS = IsDisplayFPS; - ViewWidth = (float)openGLView.ActualWidth; - ViewHeight = (float)openGLView.ActualHeight; + openGLView.Render += Render; + } - renderViewWidth = (int)(openGLView.ActualWidth * dpiX); - renderViewHeight = (int)(openGLView.ActualHeight * dpiY); + public void Render(TimeSpan ts) + { + PerfomenceMonitor.PostUIRenderTime(ts); + PerfomenceMonitor.OnBeforeRender(); - playFieldBackgroundColor = System.Drawing.Color.FromArgb(Properties.EditorGlobalSetting.Default.PlayFieldBackgroundColor).ToVector4(); - enablePlayFieldDrawing = Properties.EditorGlobalSetting.Default.EnablePlayFieldDrawing; +#if DEBUG + GLUtility.CheckError(); +#endif - drawTargets = IoC.GetAll() - .SelectMany(target => target.DrawTargetID.Select(supportId => (supportId, target))) - .GroupBy(x => x.supportId).ToDictionary(x => x.Key, x => x.Select(x => x.target).ToArray()); + CleanRender(); + GL.Viewport(0, 0, renderViewWidth, renderViewHeight); - ResortRenderOrder(); + hits.Clear(); - timeSignatureHelper = new DrawTimeSignatureHelper(); - xGridHelper = new DrawXGridHelper(); - judgeLineHelper = new DrawJudgeLineHelper(); - selectingRangeHelper = new DrawSelectingRangeHelper(); - playableAreaHelper = new DrawPlayableAreaHelper(); + var fumen = Fumen; + if (fumen is null) + return; - actualPerformenceMonitor = IoC.Get(); - IsDisplayFPS = IsDisplayFPS; + var tGrid = GetCurrentTGrid(); - openGLView.Render += Render; - } + var curY = ConvertToY(tGrid.TotalUnit); + var minY = (float) (curY - Setting.JudgeLineOffsetY); + var maxY = minY + ViewHeight; - private void ResortRenderOrder() + //计算可以显示的TGrid范围以及像素范围 + visibleTGridRanges.Clear(); + if (IsDesignMode) { - drawTargetOrder = drawTargets.Values.SelectMany(x => x).OrderBy(x => x.CurrentRenderOrder).Distinct().ToArray(); - } - - public IFumenEditorDrawingTarget[] GetDrawingTarget(string name) => drawTargets.TryGetValue(name, out var drawingTarget) ? drawingTarget : default; + var minTGrid = TGridCalculator.ConvertYToTGrid_DesignMode(minY, this) ?? TGrid.Zero; + var maxTGrid = TGridCalculator.ConvertYToTGrid_DesignMode(maxY, this); - private IEnumerable GetDisplayableObjects(OngekiFumen fumen, IEnumerable<(TGrid min, TGrid max)> visibleRanges) + if (maxTGrid is null || minTGrid is null) + return; + visibleTGridRanges.Add((minTGrid, maxTGrid)); + } + else { - var containBeams = fumen.Beams.Any(); + var scale = Setting.VerticalDisplayScale; + var ranges = + Fumen.Soflans.GetVisibleRanges_PreviewMode(curY, ViewHeight, Setting.JudgeLineOffsetY, Fumen.BpmList, + scale); - var objects = visibleRanges.SelectMany(x => + foreach (var x in ranges) { - (var min, var max) = x; - var r = Enumerable.Empty() - .Concat(fumen.Flicks.BinaryFindRange(min, max)) - .Concat(fumen.MeterChanges.Skip(1)) //not show first meter - .Concat(fumen.BpmList.Skip(1)) //not show first bpm - .Concat(fumen.ClickSEs.BinaryFindRange(min, max)) - .Concat(fumen.LaneBlocks.GetVisibleStartObjects(min, max)) - .Concat(fumen.Comments.BinaryFindRange(min, max)) - .Concat(fumen.Soflans.GetVisibleStartObjects(min, max)) - .Concat(fumen.EnemySets.BinaryFindRange(min, max)) - .Concat(fumen.Lanes.GetVisibleStartObjects(min, max)) - .Concat(fumen.Taps.BinaryFindRange(min, max)) - .Concat(fumen.Holds.GetVisibleStartObjects(min, max)) - .Concat(fumen.SvgPrefabs); - - if (containBeams) - { - var leadInTGrid = TGridCalculator.ConvertAudioTimeToTGrid(TGridCalculator.ConvertTGridToAudioTime(min, this) - TGridCalculator.ConvertFrameToAudioTime(BeamStart.LEAD_IN_DURATION_FRAME), this); - var leadOutTGrid = TGridCalculator.ConvertAudioTimeToTGrid(TGridCalculator.ConvertTGridToAudioTime(max, this) + TimeSpan.FromMilliseconds(BeamStart.LEAD_OUT_DURATION), this); - - r = r.Concat(fumen.Beams.GetVisibleStartObjects(leadInTGrid, leadOutTGrid)); - } - - return r; - }); + if (x.maxTGrid is null || x.minTGrid is null) + return; + visibleTGridRanges.Add((x.minTGrid, x.maxTGrid)); + } + } - /* - * 这里考虑到有spd<1的子弹/Bell会提前出现的情况,因此得分状态分别去选择 - */ - var objs = Enumerable.Empty(); - if (Editor.IsPreviewMode) - { - /* - var r = fumen.Bells - .AsEnumerable() - .Concat(fumen.Bullets); + Rect = new VisibleRect(new Vector2(ViewWidth, minY), new Vector2(0, minY + ViewHeight)); - objs = objs.Concat(r); - */ - } - else - { - foreach (var item in visibleRanges) - { - (var min, var max) = item; - var blts = fumen.Bullets.BinaryFindRange(min, max); - var bels = fumen.Bells.BinaryFindRange(min, max); - - objs = objs.Concat(bels); - objs = objs.Concat(blts); - } - } + RecalculateMagaticXGridLines(); - return objects.Concat(objs).SelectMany(x => x.GetDisplayableObjects()); - } + foreach (var (minTGrid, maxTGrid) in visibleTGridRanges) + playableAreaHelper.DrawPlayField(this, minTGrid, maxTGrid); + playableAreaHelper.Draw(this); + timeSignatureHelper.DrawLines(this); - private void CleanRender() + xGridHelper.DrawLines(this, CachedMagneticXGridLines); + + //todo 可以把GroupBy()给优化掉 + var renderObjects = + GetDisplayableObjects(fumen, visibleTGridRanges) + .Distinct() + .OfType() + .GroupBy(x => x.IDShortName); + + foreach (var objGroup in renderObjects) { - if (IsDesignMode || !enablePlayFieldDrawing) - GL.ClearColor(16 / 255.0f, 16 / 255.0f, 16 / 255.0f, 1); - else - GL.ClearColor(playFieldBackgroundColor.X, playFieldBackgroundColor.Y, playFieldBackgroundColor.Z, playFieldBackgroundColor.W); - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + if (GetDrawingTarget(objGroup.Key) is not IFumenEditorDrawingTarget[] drawingTargets) + continue; + + foreach (var drawingTarget in drawingTargets) + if (!drawMap.TryGetValue(drawingTarget, out var enums)) + drawMap[drawingTarget] = objGroup; + else + drawMap[drawingTarget] = enums.Concat(objGroup); } - private List<(TGrid minTGrid, TGrid maxTGrid)> visibleTGridRanges = new List<(TGrid minTGrid, TGrid maxTGrid)>(); + if (IsPreviewMode) + { + //特殊处理:子弹和Bell + foreach (var drawingTarget in GetDrawingTarget(Bullet.CommandName)) + drawMap[drawingTarget] = Fumen.Bullets; + foreach (var drawingTarget in GetDrawingTarget(Bell.CommandName)) + drawMap[drawingTarget] = Fumen.Bells; + } - public void Render(TimeSpan ts) + var prevOrder = int.MinValue; + foreach (var drawingTarget in drawTargetOrder.Where(x => CheckDrawingVisible(x.Visible))) { - PerfomenceMonitor.PostUIRenderTime(ts); - PerfomenceMonitor.OnBeforeRender(); + //check render order + var order = drawingTarget.CurrentRenderOrder; + if (prevOrder > order) + { + ResortRenderOrder(); + CleanRender(); + break; + } -#if DEBUG - GLUtility.CheckError(); -#endif + prevOrder = order; - CleanRender(); - GL.Viewport(0, 0, renderViewWidth, renderViewHeight); + if (drawMap.TryGetValue(drawingTarget, out var drawingObjs)) + { + drawingTarget.Begin(this); + foreach (var obj in drawingObjs.OrderBy(x => x.TGrid)) + drawingTarget.Post(obj); + drawingTarget.End(); + } + } - hits.Clear(); + drawMap.Clear(); - var fumen = Fumen; - if (fumen is null) - return; + timeSignatureHelper.DrawTimeSigntureText(this); + xGridHelper.DrawXGridText(this, CachedMagneticXGridLines); + judgeLineHelper.Draw(this); + playerLocationHelper.Draw(this); + selectingRangeHelper.Draw(this); - var tGrid = GetCurrentTGrid(); - var curY = ConvertToY(tGrid.TotalUnit); - var minY = (float)(curY - Setting.JudgeLineOffsetY); - var maxY = (float)(minY + ViewHeight); + PerfomenceMonitor.OnAfterRender(); + } - //计算可以显示的TGrid范围以及像素范围 - visibleTGridRanges.Clear(); - if (IsDesignMode) - { - var minTGrid = TGridCalculator.ConvertYToTGrid_DesignMode(minY, this) ?? TGrid.Zero; - var maxTGrid = TGridCalculator.ConvertYToTGrid_DesignMode(maxY, this); + public bool CheckDrawingVisible(DrawingVisible visible) + { + return visible.HasFlag(EditorObjectVisibility == Visibility.Visible + ? DrawingVisible.Design + : DrawingVisible.Preview); + } - if (maxTGrid is null || minTGrid is null) - return; - visibleTGridRanges.Add((minTGrid, maxTGrid)); - } - else - { - var scale = Setting.VerticalDisplayScale; - var ranges = Fumen.Soflans.GetVisibleRanges_PreviewMode(curY, ViewHeight, Setting.JudgeLineOffsetY, Fumen.BpmList, scale); - - foreach (var x in ranges) - { - if (x.maxTGrid is null || x.minTGrid is null) - return; - visibleTGridRanges.Add((x.minTGrid, x.maxTGrid)); - } - } - Rect = new VisibleRect(new(ViewWidth, minY), new(0, minY + ViewHeight)); + public double ConvertToY(double tGridUnit) + { + return convertToY(tGridUnit, this); + } - RecalculateMagaticXGridLines(); + public bool CheckVisible(TGrid tGrid) + { + foreach (var (minTGrid, maxTGrid) in visibleTGridRanges) + if (minTGrid <= tGrid && tGrid <= maxTGrid) + return true; + return false; + } - foreach ((var minTGrid, var maxTGrid) in visibleTGridRanges) - playableAreaHelper.DrawPlayField(this, minTGrid, maxTGrid); - playableAreaHelper.Draw(this); - timeSignatureHelper.DrawLines(this); + public bool CheckRangeVisible(TGrid minTGrid, TGrid maxTGrid) + { + foreach (var visibleRange in visibleTGridRanges) + { + var result = !(minTGrid > visibleRange.maxTGrid || maxTGrid < visibleRange.minTGrid); + if (result) + return true; + } - xGridHelper.DrawLines(this, CachedMagneticXGridLines); + return false; + } - //todo 可以把GroupBy()给优化掉 - var renderObjects = - GetDisplayableObjects(fumen, visibleTGridRanges) - .Distinct() - .OfType() - .GroupBy(x => x.IDShortName); + public string SchedulerName => "Fumen Previewer Performance Statictis"; - foreach (var objGroup in renderObjects) - { - if (GetDrawingTarget(objGroup.Key) is not IFumenEditorDrawingTarget[] drawingTargets) - continue; - - foreach (var drawingTarget in drawingTargets) - { - if (!drawMap.TryGetValue(drawingTarget, out var enums)) - drawMap[drawingTarget] = objGroup; - else - drawMap[drawingTarget] = enums.Concat(objGroup); - } - } + public TimeSpan ScheduleCallLoopInterval => TimeSpan.FromSeconds(1); - if (IsPreviewMode) - { - //特殊处理:子弹和Bell - foreach (var drawingTarget in GetDrawingTarget(Bullet.CommandName)) - drawMap[drawingTarget] = Fumen.Bullets; - foreach (var drawingTarget in GetDrawingTarget(Bell.CommandName)) - drawMap[drawingTarget] = Fumen.Bells; - } + public void OnSchedulerTerm() + { + } - var prevOrder = int.MinValue; - foreach (var drawingTarget in drawTargetOrder.Where(x => CheckDrawingVisible(x.Visible))) - { - //check render order - var order = drawingTarget.CurrentRenderOrder; - if (prevOrder > order) - { - ResortRenderOrder(); - CleanRender(); - break; - } - prevOrder = order; - - if (drawMap.TryGetValue(drawingTarget, out var drawingObjs)) - { - drawingTarget.Begin(this); - foreach (var obj in drawingObjs.OrderBy(x => x.TGrid)) - drawingTarget.Post(obj); - drawingTarget.End(); - } - } + public Task OnScheduleCall(CancellationToken cancellationToken) + { + if (IsDisplayFPS) + { + stringBuilder.Clear(); - drawMap.Clear(); + PerfomenceMonitor?.FormatStatistics(stringBuilder); +#if DEBUG + stringBuilder.AppendLine(); + stringBuilder.AppendLine($"View: {ViewWidth}x{ViewHeight}"); + stringBuilder.AppendLine($"VisibleYRange: [{Rect.MinY}, {Rect.MaxY}]"); + stringBuilder.AppendLine("VisibleTGridRanges:"); + foreach (var tGridRange in visibleTGridRanges.ToArray()) + stringBuilder.AppendLine($"* {tGridRange.minTGrid} - {tGridRange.maxTGrid}"); +#endif - timeSignatureHelper.DrawTimeSigntureText(this); - xGridHelper.DrawXGridText(this, CachedMagneticXGridLines); - judgeLineHelper.Draw(this); - selectingRangeHelper.Draw(this); + DisplayFPS = stringBuilder.ToString(); - PerfomenceMonitor.OnAfterRender(); + PerfomenceMonitor?.Clear(); } - public void OnLoaded(ActionExecutionContext e) - { + return Task.CompletedTask; + } - } + protected override void OnViewLoaded(object v) + { + base.OnViewLoaded(v); + InitExtraMenuItems(); + } - private void RecalculateMagaticXGridLines() - { - //todo 可以优化 - cachedMagneticXGridLines.Clear(); + private void RecalcViewProjectionMatrix() + { + var xOffset = 0; - var xOffset = (float)Setting.XOffset; - var width = ViewWidth; - if (width == 0) - return; - var xUnitSpace = (float)Setting.XGridUnitSpace; - var maxDisplayXUnit = Setting.XGridDisplayMaxUnit; + var y = (float) convertToY(GetCurrentTGrid().TotalUnit, this); - var unitSize = (float)XGridCalculator.CalculateXUnitSize(maxDisplayXUnit, width, xUnitSpace); - var totalUnitValue = 0f; + ProjectionMatrix = + Matrix4.CreateOrthographic(ViewWidth, ViewHeight, -1, 1); + ViewMatrix = + Matrix4.CreateTranslation(new Vector3(-ViewWidth / 2 + xOffset, + -y - ViewHeight / 2 + (float) Setting.JudgeLineOffsetY, 0)); - var baseX = width / 2 + xOffset; + ViewProjectionMatrix = ViewMatrix * ProjectionMatrix; + } - var limitLength = width + Math.Abs(xOffset); + private void ResortRenderOrder() + { + drawTargetOrder = drawTargets.Values.SelectMany(x => x).OrderBy(x => x.CurrentRenderOrder).Distinct().ToArray(); + } + + public IFumenEditorDrawingTarget[] GetDrawingTarget(string name) + { + return drawTargets.TryGetValue(name, out var drawingTarget) ? drawingTarget : default; + } - for (float totalLength = baseX + unitSize; totalLength - xOffset < limitLength; totalLength += unitSize) + private IEnumerable GetDisplayableObjects(OngekiFumen fumen, + IEnumerable<(TGrid min, TGrid max)> visibleRanges) + { + var containBeams = fumen.Beams.Any(); + + var objects = visibleRanges.SelectMany(x => + { + var (min, max) = x; + var r = Enumerable.Empty() + .Concat(fumen.Flicks.BinaryFindRange(min, max)) + .Concat(fumen.MeterChanges.Skip(1)) //not show first meter + .Concat(fumen.BpmList.Skip(1)) //not show first bpm + .Concat(fumen.ClickSEs.BinaryFindRange(min, max)) + .Concat(fumen.LaneBlocks.GetVisibleStartObjects(min, max)) + .Concat(fumen.Comments.BinaryFindRange(min, max)) + .Concat(fumen.Soflans.GetVisibleStartObjects(min, max)) + .Concat(fumen.EnemySets.BinaryFindRange(min, max)) + .Concat(fumen.Lanes.GetVisibleStartObjects(min, max)) + .Concat(fumen.Taps.BinaryFindRange(min, max)) + .Concat(fumen.Holds.GetVisibleStartObjects(min, max)) + .Concat(fumen.SvgPrefabs); + + if (containBeams) { - totalUnitValue += xUnitSpace; - - cachedMagneticXGridLines.Add(new() - { - X = totalLength, - XGridTotalUnit = totalUnitValue, - XGridTotalUnitDisplay = totalUnitValue.ToString() - }); - - cachedMagneticXGridLines.Add(new() - { - X = baseX - (totalLength - baseX), - XGridTotalUnit = -totalUnitValue, - XGridTotalUnitDisplay = (-totalUnitValue).ToString() - }); + var leadInTGrid = TGridCalculator.ConvertAudioTimeToTGrid( + TGridCalculator.ConvertTGridToAudioTime(min, this) - + TGridCalculator.ConvertFrameToAudioTime(BeamStart.LEAD_IN_DURATION_FRAME), this); + var leadOutTGrid = TGridCalculator.ConvertAudioTimeToTGrid( + TGridCalculator.ConvertTGridToAudioTime(max, this) + + TimeSpan.FromMilliseconds(BeamStart.LEAD_OUT_DURATION), this); + + r = r.Concat(fumen.Beams.GetVisibleStartObjects(leadInTGrid, leadOutTGrid)); } - cachedMagneticXGridLines.Add(new() - { - X = baseX, - XGridTotalUnit = 0f, - }); - } - public void OnSizeChanged(ActionExecutionContext e) - { - var scrollViewer = e.Source as AnimatedScrollViewer; - scrollViewer?.InvalidateMeasure(); - } + return r; + }); - public void OnSchedulerTerm() + /* + * 这里考虑到有spd<1的子弹/Bell会提前出现的情况,因此得分状态分别去选择 + */ + var objs = Enumerable.Empty(); + if (Editor.IsPreviewMode) { + /* + var r = fumen.Bells + .AsEnumerable() + .Concat(fumen.Bullets); + objs = objs.Concat(r); + */ } - - public Task OnScheduleCall(CancellationToken cancellationToken) + else { - if (IsDisplayFPS) + foreach (var item in visibleRanges) { - stringBuilder.Clear(); + var (min, max) = item; + var blts = fumen.Bullets.BinaryFindRange(min, max); + var bels = fumen.Bells.BinaryFindRange(min, max); - PerfomenceMonitor?.FormatStatistics(stringBuilder); -#if DEBUG - stringBuilder.AppendLine(); - stringBuilder.AppendLine($"View: {ViewWidth}x{ViewHeight}"); - stringBuilder.AppendLine($"VisibleYRange: [{Rect.MinY}, {Rect.MaxY}]"); - stringBuilder.AppendLine($"VisibleTGridRanges:"); - foreach (var tGridRange in visibleTGridRanges.ToArray()) - stringBuilder.AppendLine($"* {tGridRange.minTGrid} - {tGridRange.maxTGrid}"); -#endif + objs = objs.Concat(bels); + objs = objs.Concat(blts); + } + } - DisplayFPS = stringBuilder.ToString(); + return objects.Concat(objs).SelectMany(x => x.GetDisplayableObjects()); + } - PerfomenceMonitor?.Clear(); + private void CleanRender() + { + if (IsDesignMode || !enablePlayFieldDrawing) + GL.ClearColor(16 / 255.0f, 16 / 255.0f, 16 / 255.0f, 1); + else + GL.ClearColor(playFieldBackgroundColor.X, playFieldBackgroundColor.Y, playFieldBackgroundColor.Z, + playFieldBackgroundColor.W); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + } + + public void OnLoaded(ActionExecutionContext e) + { + } - } - return Task.CompletedTask; - } + private void RecalculateMagaticXGridLines() + { + //todo 可以优化 + cachedMagneticXGridLines.Clear(); - public bool CheckDrawingVisible(DrawingVisible visible) - { - return visible.HasFlag(EditorObjectVisibility == Visibility.Visible ? DrawingVisible.Design : DrawingVisible.Preview); - } + var xOffset = (float) Setting.XOffset; + var width = ViewWidth; + if (width == 0) + return; + var xUnitSpace = (float) Setting.XGridUnitSpace; + var maxDisplayXUnit = Setting.XGridDisplayMaxUnit; - public double ConvertToY(double tGridUnit) - { - return convertToY(tGridUnit, this); - } + var unitSize = (float) XGridCalculator.CalculateXUnitSize(maxDisplayXUnit, width, xUnitSpace); + var totalUnitValue = 0f; - public bool CheckVisible(TGrid tGrid) - { - foreach ((var minTGrid, var maxTGrid) in visibleTGridRanges) - if (minTGrid <= tGrid && tGrid <= maxTGrid) - return true; - return false; - } + var baseX = width / 2 + xOffset; + + var limitLength = width + Math.Abs(xOffset); - public bool CheckRangeVisible(TGrid minTGrid, TGrid maxTGrid) + for (var totalLength = baseX + unitSize; totalLength - xOffset < limitLength; totalLength += unitSize) { - foreach (var visibleRange in visibleTGridRanges) + totalUnitValue += xUnitSpace; + + cachedMagneticXGridLines.Add(new CacheDrawXLineResult { - var result = !(minTGrid > visibleRange.maxTGrid || maxTGrid < visibleRange.minTGrid); - if (result) - return true; - } - return false; + X = totalLength, + XGridTotalUnit = totalUnitValue, + XGridTotalUnitDisplay = totalUnitValue.ToString() + }); + + cachedMagneticXGridLines.Add(new CacheDrawXLineResult + { + X = baseX - (totalLength - baseX), + XGridTotalUnit = -totalUnitValue, + XGridTotalUnitDisplay = (-totalUnitValue).ToString() + }); } - } -} + + cachedMagneticXGridLines.Add(new CacheDrawXLineResult + { + X = baseX, + XGridTotalUnit = 0f + }); + } + + public void OnSizeChanged(ActionExecutionContext e) + { + var scrollViewer = e.Source as AnimatedScrollViewer; + scrollViewer?.InvalidateMeasure(); + } +} \ No newline at end of file diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Views/OngekiObjects/playerLoc.png b/OngekiFumenEditor/Modules/FumenVisualEditor/Views/OngekiObjects/playerLoc.png new file mode 100644 index 0000000000000000000000000000000000000000..bc02bdd8cbf3e82c9d1073cf689480762dced77c GIT binary patch literal 691 zcmV;k0!;mhP)!knjz5nyb!yYW& z*Kho%xV^-O>GwT8KzjCrV!=0<>wHRIgpdd!7Gkal z)^MhPoD!5TBr{RF+-hw(Xv>v6C3?PMR=etb*|y?KbK0;oqW7b?O^p&=2rgG&@nmV6^?W2W1+%U=KyBl z394d-Wq9r0XK=uKO;AJrT=aSL+iQ`}>3C{r#TokHbeV%F7${`x^ga Z`~f?-BEIDfsq_E<002ovPDHLkV1g>(O@IIZ literal 0 HcmV?d00001 diff --git a/OngekiFumenEditor/OngekiFumenEditor.csproj b/OngekiFumenEditor/OngekiFumenEditor.csproj index cc10815d..32d1c35c 100644 --- a/OngekiFumenEditor/OngekiFumenEditor.csproj +++ b/OngekiFumenEditor/OngekiFumenEditor.csproj @@ -25,6 +25,8 @@ + + @@ -179,10 +181,10 @@ - + all - + all diff --git a/OngekiFumenEditor/Properties/EditorGlobalSetting.Designer.cs b/OngekiFumenEditor/Properties/EditorGlobalSetting.Designer.cs index 4fdb3dee..965d0e58 100644 --- a/OngekiFumenEditor/Properties/EditorGlobalSetting.Designer.cs +++ b/OngekiFumenEditor/Properties/EditorGlobalSetting.Designer.cs @@ -12,7 +12,7 @@ namespace OngekiFumenEditor.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")] public sealed partial class EditorGlobalSetting : global::System.Configuration.ApplicationSettingsBase { private static EditorGlobalSetting defaultInstance = ((EditorGlobalSetting)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new EditorGlobalSetting()))); @@ -382,5 +382,17 @@ public bool EnablePlayFieldDrawing { this["EnablePlayFieldDrawing"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool EnableShowPlayerLocation { + get { + return ((bool)(this["EnableShowPlayerLocation"])); + } + set { + this["EnableShowPlayerLocation"] = value; + } + } } } diff --git a/OngekiFumenEditor/Properties/EditorGlobalSetting.settings b/OngekiFumenEditor/Properties/EditorGlobalSetting.settings index b993c659..92d8a4c6 100644 --- a/OngekiFumenEditor/Properties/EditorGlobalSetting.settings +++ b/OngekiFumenEditor/Properties/EditorGlobalSetting.settings @@ -92,5 +92,8 @@ False + + False + \ No newline at end of file diff --git a/OngekiFumenEditor/Properties/Resources.Designer.cs b/OngekiFumenEditor/Properties/Resources.Designer.cs index 5b4437fa..6c26ab57 100644 --- a/OngekiFumenEditor/Properties/Resources.Designer.cs +++ b/OngekiFumenEditor/Properties/Resources.Designer.cs @@ -1563,6 +1563,15 @@ public static string EnablePlayFieldDrawing { } } + /// + /// 查找类似 Display the player's current position (if there is no AutoPlayFaderLane, it defaults to the center) 的本地化字符串。 + /// + public static string EnableShowPlayerLocation { + get { + return ResourceManager.GetString("EnableShowPlayerLocation", resourceCulture); + } + } + /// /// 查找类似 Enable display visualizer 的本地化字符串。 /// diff --git a/OngekiFumenEditor/Properties/Resources.ja.resx b/OngekiFumenEditor/Properties/Resources.ja.resx index cf93ca10..3d27c60d 100644 --- a/OngekiFumenEditor/Properties/Resources.ja.resx +++ b/OngekiFumenEditor/Properties/Resources.ja.resx @@ -147,6 +147,9 @@ サポートされている全ファイル形式 + + アプリケーションバージョン + 音源位置を補正する @@ -207,6 +210,9 @@ 現在オブジェクトの時刻を自動更新 + + 背景色: + 一括でクリティカル設定 @@ -261,6 +267,9 @@ AcbGeneratorFuck.Generator.Generate() の呼び出しに失敗しました + + GenerateSvgAsync() の呼び出しに失敗しました + キャンセル @@ -270,6 +279,9 @@ 選択解除 + + 新しいプロジェクトを作成できません: + 譜面をクイックオープンできませんでした: @@ -336,6 +348,9 @@ ユーザは新規プロジェクトウィザードを完了できません。このエディタを閉じてください。 + + プログラムを終了 + レーンを結合 @@ -345,6 +360,9 @@ 確認 + + 確認したため閉じることができます + コンパイルに成功しました。実行しますか? @@ -438,6 +456,12 @@ 作成 + + プロジェクトを作成 + + + 新しくプロジェクトを作成します + タイムラインのオフセット @@ -531,6 +555,12 @@ レーンの途中でレーンを2つに分岐します + + .dmpファイル: + + + 以前 + エディタは指定されたTGridに移動します @@ -576,9 +606,18 @@ メトロノームを有効化(デザインモードのみ) + + 複数起動を許可 + 通知ダイアログを表示 + + オーディオ時間(末尾の赤い線)の外側にオブジェクトを配置できるようにする + + + 渲染可击打区域(実験的機能) + スペクトル表示 @@ -615,6 +654,9 @@ 音源フォルダが存在しません + + 有栖がエディタを食べてしまいました + 実行 @@ -630,6 +672,12 @@ クイックオープン + + クイックオープン + + + 既存の譜面ファイルを開く + 譜面をクイックオープン @@ -645,6 +693,18 @@ クイック再生/一時停止 + + ファイルの関連付け + + + 選択したファイル形式を関連付ける + + + ファイルの関連付け(要管理者権限) + + + すべての関連付けを解除 + フィルタ @@ -750,6 +810,9 @@ スクリプトプロジェクトファイルの生成に失敗しました + + 生成铺面预览.svg文件 + ジャンル: @@ -765,6 +828,9 @@ 画面描画 + + 30分前 + 譜面ヘッダー情報 @@ -780,6 +846,9 @@ 画像ファイル: + + 内部例外メッセージ: + 生成する画像ファイルが存在しません @@ -825,12 +894,18 @@ 判定ラインオフセット: + + + キーワード並び替え このレーンは不正なセグメントを含んでいます + + 言語 + 元に戻せる回数を制限する @@ -846,6 +921,12 @@ 既存のMusic.xmlを読み込む + + プロジェクトと譜面は正常に読み込まれました + + + 現在のログファイルの保存先: + ロガー @@ -924,6 +1005,9 @@ (非表示) + + 再度表示しない + {0} はブラシモードでサポートされていません @@ -981,6 +1065,12 @@ エディタを開いてください + + プロジェクトを開く + + + 既存のプロジェクトを開く + オプション @@ -1023,9 +1113,15 @@ X[0, 0]を基準として水平方向にミラーリングして貼り付け + + マウスポインタ位置に貼り付け + 音声/譜面を一時停止してください + + 可击打区域颜色: + 編集の競合を避けるため,一時的にこのエディタを使用できなくなります @@ -1053,6 +1149,18 @@ プロパティのバッチ割り当て: + + ランダムオフセット範囲 + + + 再計算に成功しました + + + エディタの全長の再計算 + + + 最近使用したファイル + 音源時刻に復元 @@ -1065,6 +1173,15 @@ 更新 + + 登録に失敗しました + + + 一つ以上のファイル種別について登録に失敗しました + + + 登録に成功しました + 音源ファイルを再読込 @@ -1086,9 +1203,21 @@ 描画順 + + 権限がありません。管理者として実行してください。 + + + プログラムの再起動が必要です + リサンプリング + + 譜面・プロジェクトファイルは一時的に以下の場所に保存されています: + + + リセット + オブジェクトの選択を反転 @@ -1218,6 +1347,9 @@ 標準オンゲキ譜面を生成 + + 開始 + 外部エディタの使用を停止 @@ -1281,15 +1413,24 @@ コピーされたオブジェクト… + + 今日 + 貼り付け… 選択されたオブジェクト… + + チュートリアル + チュートリアル・文書 + + 譜面とエディタの使用方法についてチュートリアルで学習する + 出力トラックをプレビューするにはShowOriginColorのチェックを外してください @@ -1299,6 +1440,12 @@ 元に戻す/やり直し(要再起動) + + 登録解除に失敗しました + + + 登録解除に成功しました + assets.bytesを更新(存在する場合): @@ -1345,11 +1492,17 @@ 同じ方向のWALLノーツ(id:{0},id:{1})が同じ時間に存在しています - WALLノーツ(id:{0})の中間点/終点オブジェクトのTGrid({1})が始点({1})よりも小さくなっています + WALLノーツ(id:{0})の中間点/終点オブジェクトのTGrid({1})が始点({2})よりも小さくなっています いくつかの効果音の読み込みに失敗しました。詳細についてはログを確認してください。 + + 1ヶ月以内 + + + 1週間以内 + {0}オブジェクトが正しいレーン(id:{1})上に配置されていません @@ -1365,154 +1518,4 @@ 水平スクロールオフセット - - アプリケーションバージョン - - - 新しいプロジェクトを作成できません: - - - プログラムを終了 - - - 確認したため閉じることができます - - - プロジェクトを作成 - - - 新しくプロジェクトを作成します - - - .dmpファイル: - - - 以前 - - - 複数起動を許可 - - - 有栖がエディタを食べてしまいました - - - クイックオープン - - - 既存の譜面ファイルを開く - - - ファイルの関連付け - - - 選択したファイル形式を関連付ける - - - ファイルの関連付け(要管理者権限) - - - すべての関連付けを解除 - - - 30分前 - - - 内部例外メッセージ: - - - - - - 言語 - - - プロジェクトと譜面は正常に読み込まれました - - - 現在のログファイルの保存先: - - - 再度表示しない - - - プロジェクトを開く - - - 既存のプロジェクトを開く - - - マウスポインタ位置に貼り付け - - - 最近使用したファイル - - - 登録に失敗しました - - - 一つ以上のファイル種別について登録に失敗しました - - - 登録に成功しました - - - 権限がありません。管理者として実行してください。 - - - プログラムの再起動が必要です - - - 譜面・プロジェクトファイルは一時的に以下の場所に保存されています: - - - リセット - - - 開始 - - - 今日 - - - チュートリアル - - - 譜面とエディタの使用方法についてチュートリアルで学習する - - - 登録解除に失敗しました - - - 登録解除に成功しました - - - 1ヶ月以内 - - - 1週間以内 - - - オーディオ時間(末尾の赤い線)の外側にオブジェクトを配置できるようにする - - - エディタの全長の再計算 - - - 再計算に成功しました - - - 背景色: - - - 渲染可击打区域(実験的機能) - - - 生成铺面预览.svg文件 - - - 可击打区域颜色: - - - ランダムオフセット範囲 - \ No newline at end of file diff --git a/OngekiFumenEditor/Properties/Resources.resx b/OngekiFumenEditor/Properties/Resources.resx index d5b67472..182ada92 100644 --- a/OngekiFumenEditor/Properties/Resources.resx +++ b/OngekiFumenEditor/Properties/Resources.resx @@ -1524,4 +1524,7 @@ Horizontal scroll offset: + + Display the player's current position (if there is no AutoPlayFaderLane, it defaults to the center) + \ No newline at end of file diff --git a/OngekiFumenEditor/Properties/Resources.zh-Hans.resx b/OngekiFumenEditor/Properties/Resources.zh-Hans.resx index bd730455..4afda4cf 100644 --- a/OngekiFumenEditor/Properties/Resources.zh-Hans.resx +++ b/OngekiFumenEditor/Properties/Resources.zh-Hans.resx @@ -1524,4 +1524,7 @@ 水平轴偏移: + + 显示玩家当前位置 (若没AutoPlayFaderLane轨道则默认在中心) + \ No newline at end of file