using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace OpenVIII
{
///
/// Images of parts of most of the menus and ui.
///
public sealed partial class Icons : SP2
{
#region Fields
private Rectangle _dataSize;
private new Dictionary Entries = null;
#endregion Fields
#region Constructors
public Icons()
{
}
#endregion Constructors
#region Enums
public enum NumType
{
Num_8x8_0,
Num_8x8_1,
Num_8x8_2,
Num_8x16_0,
Num_8x16_1,
Num_16x16_0,
sysFntBig,
sysfnt,
menuFont,
}
#endregion Enums
#region Properties
public new uint Count => (uint)Entries.Count();
public Rectangle DataSize { get => _dataSize; private set => _dataSize = value; }
public new uint EntriesPerTexture => (uint)Enum.GetValues(typeof(Icons.ID)).Cast().Max();
public new uint PaletteCount => (uint)Textures.Count();
private new uint TextureStartOffset => 0;
#endregion Properties
#region Indexers
public new EntryGroup this[Enum id] => GetEntryGroup(id);
#endregion Indexers
#region Methods
public static Icons Load()
{
Icons r = Load();
Memory.MainThreadOnlyActions.Enqueue(r.Trim);
return r;
}
public Rectangle Draw(int number, NumType type, int palette, string format, Vector2 location, Vector2 scale, float fade = 1f, Font.ColorID color = Font.ColorID.White, bool blink = false, bool skipdraw = false)
{
if (type == NumType.sysfnt)
{
DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.sysfnt, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
return DataSize;
}
else if (type == NumType.sysFntBig)
{
DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.sysFntBig, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
return DataSize;
}
else if (type == NumType.menuFont)
{
DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.menuFont, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
return DataSize;
}
ID[] numberstarts = { ID.Num_8x8_0_0, ID.Num_8x8_1_0, ID.Num_8x8_2_0, ID.Num_8x16_0_0, ID.Num_8x16_1_0, ID.Num_16x16_0_0 };
List[] nums = new List[numberstarts.Length];
int j = 0;
foreach (ID id in numberstarts)
{
nums[j] = new List(10);
for (byte i = 0; i < 10; i++)
{
nums[j].Add(id + i);
}
j++;
}
IEnumerable intList = number.ToString(format).Select(digit => int.Parse(digit.ToString()));
Rectangle dst = new Rectangle { Location = location.ToPoint() };
DataSize = dst;
foreach (int i in intList)
{
if (!skipdraw)
Draw(nums[(int)type][i], palette, dst, scale, fade, blink ? Color.Lerp(Font.ColorID2Color[color], Font.ColorID2Blink[color], Menu.Blink_Amount) : Font.ColorID2Color[color]);
float width = Entries[nums[(int)type][i]].GetRectangle.Width * scale.X;
float height = Entries[nums[(int)type][i]].GetRectangle.Height * scale.Y;
dst.Offset(width, 0);
_dataSize.Width += (int)width;
if (_dataSize.Height < (int)height)
_dataSize.Height = (int)height;
}
return DataSize;
}
public void Draw(Enum id, int palette, Rectangle dst, Vector2 scale, float fade = 1f, Color? color = null)
{
if ((ID)id != ID.None)
Entries[(ID)id].Draw(Textures, palette, dst, scale, fade, color);
}
public override void Draw(Enum id, Rectangle dst, float fade = 1) => Draw((ID)id, 2, dst, Vector2.One, fade);
public Entry GetEntry(Enum id, int index) => Entries[(ID)id][index] ?? null;
public override Entry GetEntry(Enum id) => Entries[(ID)id][0] ?? null;
public EntryGroup GetEntryGroup(Enum id)
{
if ((ID)id != ID.None)
return Entries[(ID)id] ?? null;
return null;
}
public Color MostSaturated(Enum ic, byte pal)
{
EntryGroup eg = this[(ID)ic];
return eg.MostSaturated(Textures[pal], pal);
}
public override void Trim(Enum ic, byte pal)
{
EntryGroup eg = this[(ID)ic];
eg.Trim(Textures[pal]);
}
protected override void DefaultValues()
{
base.DefaultValues();
Color[] red = new Color[256];
red[15] = new Color(255, 30, 30, 255); //red
red[14] = new Color(140, 30, 30, 255); //dark red
red[13] = new Color(37, 37, 37, 255); //gray
Color[] yellow = new Color[256];
yellow[15] = new Color(222, 222, 8, 255); //yellow
yellow[14] = new Color(131, 131, 24, 255); //dark yellow
yellow[13] = new Color(41, 41, 41, 255); //gray
//FORCE_ORIGINAL = true;
Props = new List()
{
new TexProps{Filename = "icon.tex",Count = 1,Big = new List{ new BigTexProps{Filename = "iconfl{0:00}.TEX",Split = 4} } }, //0-15 palette
new TexProps{Filename = "icon.tex",Count = 1,Colors = red,Big = new List{ new BigTexProps{Filename = "iconfl{0:00}.TEX",Split = 4,Colors = red } } },//16 palette
new TexProps{Filename = "icon.tex",Count = 1,Colors = yellow,Big = new List{ new BigTexProps { Filename = "iconfl{0:00}.TEX", Split = 4, Colors = yellow } } }//17 palette
};
IndexFilename = "icon.sp1";
}
protected override void InitEntries(ArchiveWorker aw = null)
{
if (Entries == null)
{
//read from icon.sp1
MemoryStream ms = null;
using (BinaryReader br = new BinaryReader(ms = new MemoryStream(
ArchiveWorker.GetBinaryFile(ArchiveString,
aw.GetListOfFiles().First(x => x.IndexOf(IndexFilename, StringComparison.OrdinalIgnoreCase) >= 0)))))
{
Loc[] locs = new Loc[br.ReadUInt32()];
for (int i = 0; i < locs.Length; i++)
{
locs[i].seek = br.ReadUInt16();
locs[i].length = br.ReadUInt16();
}
Entries = new Dictionary(locs.Length + 10);
for (int i = 0; i < locs.Length; i++)
{
ms.Seek(locs[i].seek, SeekOrigin.Begin);
byte c = (byte)locs[i].length;
Entries[(ID)i] = new EntryGroup(c);
for (int e = 0; e < c; e++)
{
Entry tmp = new Entry();
tmp.LoadfromStreamSP1(br);
tmp.Part = (byte)e;
tmp.SetLoc(locs[i]);
Entries[(ID)i].Add(tmp);
}
}
ms = null;
}
}
}
protected override void InitTextures(ArchiveWorker aw = null)
{
Textures = new List();
for (int t = 0; t < Props.Count; t++)
{
T tex = new T();
tex.Load(ArchiveWorker.GetBinaryFile(ArchiveString,
aw.GetListOfFiles().First(x => x.IndexOf(Props[t].Filename, StringComparison.OrdinalIgnoreCase) >= 0)));
if (Props[t].Colors == null || Props[t].Colors.Length == 0)
{
for (ushort i = 0; i < tex.GetClutCount; i++)
{
if (FORCE_ORIGINAL == false && Props[t].Big != null && Props[t].Big.Count > 0)
Textures.Add(TextureHandler.Create(Props[t].Big[0].Filename, tex, 2, Props[t].Big[0].Split / 2, i));
else
Textures.Add(TextureHandler.Create(Props[t].Filename, tex, 1, 1, i));
}
}
else
{
if (FORCE_ORIGINAL == false && Props[t].Big != null && Props[t].Big.Count > 0)
Textures.Add(TextureHandler.Create(Props[t].Big[0].Filename, tex, 2, Props[t].Big[0].Split / 2, (ushort)Textures.Count, colors: Props[t].Big[0].Colors ?? Props[t].Colors));
else
Textures.Add(TextureHandler.Create(Props[t].Filename, tex, 1, 1, (ushort)Textures.Count, colors: Props[t].Colors));
}
}
}
protected override VertexPositionTexture_Texture2D Quad(Enum ic, byte pal, float scale = 0.25F, Box_Options options = Box_Options.Center | Box_Options.Middle, float z = 0f)
{
Trim(ic, pal);
EntryGroup eg = this[(ID)ic];
VertexPositionTexture_Texture2D r = Quad(eg[0], Textures[pal], scale, eg.Count == 1 ? options : options | Box_Options.UseOffset);
if (eg.Count > 1)
{
List tmp = new List(r.VPT.Length * eg.Count);
tmp.AddRange(r.VPT);
for (int i = 1; i < eg.Count; i++)
tmp.AddRange(Quad(eg[0], Textures[pal], scale, options | Box_Options.UseOffset, i * 0.001f).VPT);
return new VertexPositionTexture_Texture2D(tmp.ToArray(), r.Texture);
}
return r;
}
private void Trim()
{
Trim(ID.Bar_Fill, 5);
//trim checks to see if it's ran once before.
//so no need to check if it's already ran.
//will throw exception if not in main thread.
for (byte i = 0; i <= 7; i++)
Trim(ID._0_Hit_ + i, 2);
Trim(ID.Trigger_, 2);
Trim(ID.Perfect__, 2);
Trim(ID.Renzokeken_Seperator, 6);
}
#endregion Methods
//public VertexPositionTexture[] GenerateVPT(Vector3 v, float width, float height)
//{
// Vector3[] verts = new Vector3[]
// {
// new Vector3(v.X-width/2f,v.Y+height/2f,v.Z),
// new Vector3(v.X+width/2f,v.Y+height/2f,v.Z),
// new Vector3(v.X+width/2f,v.Y-height/2f,v.Z),
// new Vector3(v.X-width/2f,v.Y-height/2f,v.Z),
// };
// VertexPositionTexture GetVPT(ref Debug_battleDat.Quad quad, byte i)
// {
// Vector3 GetVertex(ref Quad _quad, byte _i)
// {
// return TransformVertex(verts[_quad.GetIndex(_i)], translationPosition, rotation);
// }
// return new VertexPositionTexture(GetVertex(quad, i), quad.GetUV(i).ToVector2(preVarTex.Width, preVarTex.Height));
// }
// TempVPT[0] = TempVPT[3] = GetVPT(ref this, this[0]);
// TempVPT[1] = GetVPT(ref this, this[1]);
// TempVPT[4] = GetVPT(ref this, this[4]);
// TempVPT[2] = TempVPT[5] = GetVPT(ref this, this[2]);
//}
}
}