1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 13:22:55 +08:00

Add support for reading skin frame rate from configuration file

This commit is contained in:
Dean Herbert 2020-02-07 14:58:29 +09:00
parent 7460018cd3
commit 544685be48
3 changed files with 51 additions and 31 deletions

View File

@ -46,17 +46,20 @@ namespace osu.Game.Rulesets.Osu.Skinning
switch (osuComponent.Component)
{
case OsuSkinComponents.FollowPoint:
return this.GetAnimation(component.LookupName, true, false);
return this.GetAnimation(component.LookupName, true, false, true);
case OsuSkinComponents.SliderFollowCircle:
var followCircle = this.GetAnimation("sliderfollowcircle", true, true);
var followCircle = this.GetAnimation("sliderfollowcircle", true, true, true);
if (followCircle != null)
// follow circles are 2x the hitcircle resolution in legacy skins (since they are scaled down from >1x
followCircle.Scale *= 0.5f;
return followCircle;
case OsuSkinComponents.SliderBall:
var sliderBallContent = this.GetAnimation("sliderb", true, true, "");
var sliderBallContent = this.GetAnimation("sliderb", true, true, animationSeparator: "");
// todo: slider ball has a custom frame delay based on velocity
// Math.Max((150 / Velocity) * GameBase.SIXTY_FRAME_TIME, GameBase.SIXTY_FRAME_TIME);
if (sliderBallContent != null)
{

View File

@ -5,5 +5,6 @@ namespace osu.Game.Skinning
{
public enum GlobalSkinConfiguration
{
AnimationFramerate
}
}

View File

@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Sprites;
@ -10,48 +12,62 @@ namespace osu.Game.Skinning
{
public static class LegacySkinExtensions
{
public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, string animationSeparator = "-")
public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-")
{
const double default_frame_time = 1000 / 60d;
Texture texture;
Texture getFrameTexture(int frame) => source.GetTexture($"{componentName}{animationSeparator}{frame}");
TextureAnimation animation = null;
if (animatable)
{
for (int i = 0; true; i++)
{
if ((texture = getFrameTexture(i)) == null)
break;
var textures = getTextures().ToArray();
if (animation == null)
if (textures.Length > 0)
{
animation = new TextureAnimation
var animation = new TextureAnimation
{
DefaultFrameLength = default_frame_time,
Repeat = looping
DefaultFrameLength = getFrameLength(source, applyConfigFrameRate, textures),
Repeat = looping,
};
}
animation.AddFrame(texture);
}
}
foreach (var t in textures)
animation.AddFrame(t);
if (animation != null)
return animation;
if ((texture = source.GetTexture(componentName)) != null)
{
return new Sprite
{
Texture = texture
};
}
}
// if an animation was not allowed or not found, fall back to a sprite retrieval.
if ((texture = source.GetTexture(componentName)) != null)
return new Sprite { Texture = texture };
return null;
IEnumerable<Texture> getTextures()
{
for (int i = 0; true; i++)
{
if ((texture = source.GetTexture($"{componentName}{animationSeparator}{i}")) == null)
break;
yield return texture;
}
}
}
private const double default_frame_time = 1000 / 60d;
private static double getFrameLength(ISkin source, bool applyConfigFrameRate, Texture[] textures)
{
if (applyConfigFrameRate)
{
var iniRate = source.GetConfig<GlobalSkinConfiguration, int>(GlobalSkinConfiguration.AnimationFramerate);
if (iniRate != null)
return 1000f / iniRate.Value;
return 1000f / textures.Length;
}
return default_frame_time;
}
}
}