celeste-avali-skin/SourceCode/Misc.cs

109 lines
4.1 KiB
C#

using System;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Monocle;
using CC = Celeste.Mod.AvaliSkin.AvaliSkinSettings.ColorChoice;
namespace Celeste.Mod.AvaliSkin {
public static class Misc {
public static string DialogOrKey(this string key, Language lang = null) {
return key.DialogCleanOrNull(lang) ?? key;
}
}
// This is a "never/empty type" in C#. It is impossible to construct.
// Used in cases where a variable should never be initialized.
public enum Void {}
public static class ColorUtil {
public static Color SettingToColor(CC col) {
switch (col) {
case CC.Beige: return new Color(162, 136, 92); // light body
case CC.Black: return new Color(0, 0, 0);
case CC.BlueDark: return new Color(22, 42, 162); // dash 3
case CC.BlueLight: return new Color(50, 151, 223); // dash 0
case CC.Brown: return new Color(98, 75, 33);
case CC.Cyan: return new Color(26, 225, 225);
case CC.GreenDark: return new Color(41, 132, 49);
case CC.GreenLight: return new Color(59, 219, 47);
case CC.GreyDark: return new Color(78, 78, 78); // dark body
case CC.GreyLight: return new Color(168, 168, 168);
case CC.Magenta: return new Color(228, 14, 155);
case CC.Orange: return new Color(237, 147, 32);
case CC.Pink: return new Color(233, 106, 252); // dash 2
case CC.Purple: return new Color(190, 23, 214);
case CC.Red: return new Color(238, 17, 34); // dash 5+
case CC.Turquoise: return new Color(26, 213, 137); // dash 1
case CC.White: return new Color(255, 255, 255);
case CC.Yellow: return new Color(244, 226, 15); // dash 4
default: return new Color(26, 213, 137);
}
}
public static string ToHex(this Color color) {
return $"#{color.R:x2}{color.G:x2}{color.B:x2}";
}
public static string ToHexA(this Color color) {
return $"#{color.R:x2}{color.G:x2}{color.B:x2}{color.A:x2}";
}
// Converts the 6 or 8 character hex to a non-premultiplied color
public static Color HexToColor(this string hex) {
hex = hex.TrimStart(' ', '#');
if (hex.Length < 6) {
throw new IndexOutOfRangeException("Hex colors must contain at least 6 characters.");
}
float r = (float)(Calc.HexToByte(hex[0]) * 16 + Calc.HexToByte(hex[1])) / 255f;
float g = (float)(Calc.HexToByte(hex[2]) * 16 + Calc.HexToByte(hex[3])) / 255f;
float b = (float)(Calc.HexToByte(hex[4]) * 16 + Calc.HexToByte(hex[5])) / 255f;
if (hex.Length < 8) {
return new Color(r, g, b);
}
float a = (float)(Calc.HexToByte(hex[6]) * 16 + Calc.HexToByte(hex[7])) / 255f;
return new Color(r, g, b, a);
}
public static Color Premultiply(this Color color) {
return Color.FromNonPremultiplied(color.ToVector4());
}
// From https://web.archive.org/web/20200213094821/http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
public static Vector4 ToHSV(this Color color) {
// custom deconstructors are broken on mono
float r = color.R / 255.0f;
float g = color.G / 255.0f;
float b = color.B / 255.0f;
float a = color.A / 255.0f;
float K = 0f;
if (g < b) {
b = Interlocked.Exchange(ref g, b);
K = -1f;
}
if (r < g) {
g = Interlocked.Exchange(ref r, g);
K = -2f / 6f - K;
}
float chroma = r - Math.Min(g, b);
float h = Math.Abs(K + (g - b) / (6f * chroma + 1e-20f));
float s = chroma / (r + 1e-20f);
float v = r;
return new Vector4(h, s, v, a);
}
}
}