109 lines
4.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|