mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 09:23:06 +08:00
Merge pull request #22389 from peppy/mania-long-note-wang
Add basic support for stupidly long hold note skin textures
This commit is contained in:
commit
5f4dd19b49
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
@ -14,4 +14,6 @@ Hit200: mania/hit200@2x
|
||||
Hit300: mania/hit300@2x
|
||||
Hit300g: mania/hit300g@2x
|
||||
StageLeft: mania/stage-left
|
||||
StageRight: mania/stage-right
|
||||
StageRight: mania/stage-right
|
||||
NoteImage0L: LongNoteTailWang
|
||||
NoteImage1L: LongNoteTailWang
|
||||
|
@ -54,6 +54,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
||||
float lightScale = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightScale)?.Value
|
||||
?? 1;
|
||||
|
||||
float minimumColumnWidth = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.MinimumColumnWidth)?.Value
|
||||
?? 1;
|
||||
|
||||
// Create a temporary animation to retrieve the number of frames, in an effort to calculate the intended frame length.
|
||||
// This animation is discarded and re-queried with the appropriate frame length afterwards.
|
||||
var tmp = skin.GetAnimation(lightImage, true, false);
|
||||
@ -92,7 +95,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
||||
d.RelativeSizeAxes = Axes.Both;
|
||||
d.Size = Vector2.One;
|
||||
d.FillMode = FillMode.Stretch;
|
||||
// Todo: Wrap
|
||||
d.Height = minimumColumnWidth / d.DrawWidth * 1.6f; // constant matching stable.
|
||||
// Todo: Wrap?
|
||||
});
|
||||
|
||||
if (bodySprite != null)
|
||||
|
84
osu.Game/Skinning/MaxDimensionLimitedTextureLoaderStore.cs
Normal file
84
osu.Game/Skinning/MaxDimensionLimitedTextureLoaderStore.cs
Normal file
@ -0,0 +1,84 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.IO.Stores;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class MaxDimensionLimitedTextureLoaderStore : IResourceStore<TextureUpload>
|
||||
{
|
||||
private readonly IResourceStore<TextureUpload>? textureStore;
|
||||
|
||||
public MaxDimensionLimitedTextureLoaderStore(IResourceStore<TextureUpload>? textureStore)
|
||||
{
|
||||
this.textureStore = textureStore;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
textureStore?.Dispose();
|
||||
}
|
||||
|
||||
public TextureUpload Get(string name)
|
||||
{
|
||||
var textureUpload = textureStore?.Get(name);
|
||||
|
||||
// NRT not enabled on framework side classes (IResourceStore / TextureLoaderStore), welp.
|
||||
if (textureUpload == null)
|
||||
return null!;
|
||||
|
||||
return limitTextureUploadSize(textureUpload);
|
||||
}
|
||||
|
||||
public async Task<TextureUpload> GetAsync(string name, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
// NRT not enabled on framework side classes (IResourceStore / TextureLoaderStore), welp.
|
||||
if (textureStore == null)
|
||||
return null!;
|
||||
|
||||
var textureUpload = await textureStore.GetAsync(name, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (textureUpload == null)
|
||||
return null!;
|
||||
|
||||
return await Task.Run(() => limitTextureUploadSize(textureUpload), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private TextureUpload limitTextureUploadSize(TextureUpload textureUpload)
|
||||
{
|
||||
// So there's a thing where some users have taken it upon themselves to create skin elements of insane dimensions.
|
||||
// To the point where GPUs cannot load the textures (along with most image editor apps).
|
||||
// To work around this, let's look out for any stupid images and shrink them down into a usable size.
|
||||
const int max_supported_texture_size = 8192;
|
||||
|
||||
if (textureUpload.Height > max_supported_texture_size || textureUpload.Width > max_supported_texture_size)
|
||||
{
|
||||
var image = Image.LoadPixelData(textureUpload.Data.ToArray(), textureUpload.Width, textureUpload.Height);
|
||||
|
||||
// The original texture upload will no longer be returned or used.
|
||||
textureUpload.Dispose();
|
||||
|
||||
image.Mutate(i => i.Resize(new Size(
|
||||
Math.Min(textureUpload.Width, max_supported_texture_size),
|
||||
Math.Min(textureUpload.Height, max_supported_texture_size)
|
||||
)));
|
||||
|
||||
return new TextureUpload(image);
|
||||
}
|
||||
|
||||
return textureUpload;
|
||||
}
|
||||
|
||||
public Stream? GetStream(string name) => textureStore?.GetStream(name);
|
||||
|
||||
public IEnumerable<string> GetAvailableResources() => textureStore?.GetAvailableResources() ?? Array.Empty<string>();
|
||||
}
|
||||
}
|
@ -77,7 +77,7 @@ namespace osu.Game.Skinning
|
||||
(storage as ResourceStore<byte[]>)?.AddExtension("ogg");
|
||||
|
||||
Samples = samples;
|
||||
Textures = new TextureStore(resources.Renderer, resources.CreateTextureLoaderStore(storage));
|
||||
Textures = new TextureStore(resources.Renderer, new MaxDimensionLimitedTextureLoaderStore(resources.CreateTextureLoaderStore(storage)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user