mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 06:20:25 +00:00
94baab1c45
With the approaching games, PKM sprites are a different size from the 3DS era (as already hinted by LGPE, which has 56x68). It'll be a little easier to manage with this portion of the library walled off from the rest of the codebase. Eventually the net46 target will use fody or something to merge in these extra dependency dll's automatically to not disturb the usual exe/dll experience.
107 lines
No EOL
3.5 KiB
C#
107 lines
No EOL
3.5 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Timers;
|
|
using System.Windows.Forms;
|
|
using PKHeX.Drawing;
|
|
using Timer = System.Timers.Timer;
|
|
|
|
namespace PKHeX.WinForms.Controls
|
|
{
|
|
public sealed class BitmapAnimator : Timer
|
|
{
|
|
public BitmapAnimator(Image extraLayer = null)
|
|
{
|
|
ExtraLayer = extraLayer;
|
|
Elapsed += TimerElapsed;
|
|
}
|
|
|
|
private int imgWidth;
|
|
private int imgHeight;
|
|
private byte[] GlowData;
|
|
private readonly Image ExtraLayer;
|
|
private Image[] GlowCache;
|
|
public Image OriginalBackground;
|
|
private readonly object Lock = new object();
|
|
|
|
private PictureBox pb;
|
|
private int GlowInterval;
|
|
private int GlowCounter;
|
|
|
|
public int GlowFps { get; set; } = 60;
|
|
public Color GlowToColor { get; set; } = Color.LightSkyBlue;
|
|
public Color GlowFromColor { get; set; } = Color.White;
|
|
|
|
public new void Start() => throw new ArgumentException();
|
|
|
|
public new void Stop()
|
|
{
|
|
if (pb == null || !Enabled)
|
|
return;
|
|
|
|
lock (Lock)
|
|
{
|
|
Enabled = false;
|
|
pb.BackgroundImage = OriginalBackground;
|
|
}
|
|
|
|
// reset logic
|
|
GlowCounter = 0;
|
|
for (int i = 0; i < GlowCache.Length; i++)
|
|
GlowCache[i] = null;
|
|
}
|
|
|
|
public void Start(PictureBox pbox, Image baseImage, byte[] glowData, Image original)
|
|
{
|
|
Enabled = false;
|
|
imgWidth = baseImage.Width;
|
|
imgHeight = baseImage.Height;
|
|
GlowData = glowData;
|
|
GlowCounter = 0;
|
|
GlowCache = new Image[GlowFps];
|
|
GlowInterval = 1000 / GlowFps;
|
|
Interval = GlowInterval;
|
|
lock (Lock)
|
|
{
|
|
pb = pbox;
|
|
OriginalBackground = original;
|
|
}
|
|
Enabled = true;
|
|
}
|
|
|
|
private void TimerElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
|
|
{
|
|
if (!Enabled)
|
|
return; // timer canceled, was waiting to proceed
|
|
GlowCounter = (GlowCounter + 1) % (GlowInterval * 2); // loop backwards
|
|
int frameIndex = GlowCounter >= GlowInterval ? (GlowInterval * 2) - GlowCounter : GlowCounter;
|
|
|
|
lock (Lock)
|
|
{
|
|
if (!Enabled)
|
|
return;
|
|
try { pb.BackgroundImage = GetFrame(frameIndex); } // drawing GDI can be silly sometimes #2072
|
|
catch (AccessViolationException ex) { System.Diagnostics.Debug.WriteLine(ex.Message); }
|
|
}
|
|
}
|
|
|
|
private Image GetFrame(int frameIndex)
|
|
{
|
|
var frame = GlowCache[frameIndex];
|
|
if (frame != null)
|
|
return frame;
|
|
|
|
var elapsedFraction = (double)frameIndex / GlowInterval;
|
|
var frameColor = GetFrameColor(elapsedFraction);
|
|
var frameData = (byte[])GlowData.Clone();
|
|
ImageUtil.ChangeAllColorTo(frameData, frameColor);
|
|
|
|
frame = ImageUtil.GetBitmap(frameData, imgWidth, imgHeight);
|
|
if (ExtraLayer != null)
|
|
frame = ImageUtil.LayerImage(frame, ExtraLayer, 0, 0);
|
|
frame = ImageUtil.LayerImage(OriginalBackground, frame, 0, 0);
|
|
return GlowCache[frameIndex] = frame;
|
|
}
|
|
|
|
private Color GetFrameColor(double elapsedFraction) => ImageUtil.Blend(GlowToColor, GlowFromColor, elapsedFraction);
|
|
}
|
|
} |