Icons.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. namespace OpenVIII
  8. {
  9. /// <summary>
  10. /// Images of parts of most of the menus and ui.
  11. /// </summary>
  12. public sealed partial class Icons : SP2
  13. {
  14. #region Fields
  15. private Rectangle _dataSize;
  16. private new Dictionary<ID, EntryGroup> Entries = null;
  17. #endregion Fields
  18. #region Constructors
  19. public Icons()
  20. {
  21. }
  22. #endregion Constructors
  23. #region Enums
  24. public enum NumType
  25. {
  26. Num_8x8_0,
  27. Num_8x8_1,
  28. Num_8x8_2,
  29. Num_8x16_0,
  30. Num_8x16_1,
  31. Num_16x16_0,
  32. sysFntBig,
  33. sysfnt,
  34. menuFont,
  35. }
  36. #endregion Enums
  37. #region Properties
  38. public new uint Count => (uint)Entries.Count();
  39. public Rectangle DataSize { get => _dataSize; private set => _dataSize = value; }
  40. public new uint EntriesPerTexture => (uint)Enum.GetValues(typeof(Icons.ID)).Cast<Icons.ID>().Max();
  41. public new uint PaletteCount => (uint)Textures.Count();
  42. private new uint TextureStartOffset => 0;
  43. #endregion Properties
  44. #region Indexers
  45. public new EntryGroup this[Enum id] => GetEntryGroup(id);
  46. #endregion Indexers
  47. #region Methods
  48. public static Icons Load()
  49. {
  50. Icons r = Load<Icons>();
  51. Memory.MainThreadOnlyActions.Enqueue(r.Trim);
  52. return r;
  53. }
  54. 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)
  55. {
  56. if (type == NumType.sysfnt)
  57. {
  58. DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.sysfnt, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
  59. return DataSize;
  60. }
  61. else if (type == NumType.sysFntBig)
  62. {
  63. DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.sysFntBig, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
  64. return DataSize;
  65. }
  66. else if (type == NumType.menuFont)
  67. {
  68. DataSize = Memory.font.RenderBasicText(number.ToString(), location.ToPoint(), scale, Font.Type.menuFont, Fade: fade, color: color, blink: blink, skipdraw: skipdraw);
  69. return DataSize;
  70. }
  71. 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 };
  72. List<ID>[] nums = new List<ID>[numberstarts.Length];
  73. int j = 0;
  74. foreach (ID id in numberstarts)
  75. {
  76. nums[j] = new List<ID>(10);
  77. for (byte i = 0; i < 10; i++)
  78. {
  79. nums[j].Add(id + i);
  80. }
  81. j++;
  82. }
  83. IEnumerable<int> intList = number.ToString(format).Select(digit => int.Parse(digit.ToString()));
  84. Rectangle dst = new Rectangle { Location = location.ToPoint() };
  85. DataSize = dst;
  86. foreach (int i in intList)
  87. {
  88. if (!skipdraw)
  89. Draw(nums[(int)type][i], palette, dst, scale, fade, blink ? Color.Lerp(Font.ColorID2Color[color], Font.ColorID2Blink[color], Menu.Blink_Amount) : Font.ColorID2Color[color]);
  90. float width = Entries[nums[(int)type][i]].GetRectangle.Width * scale.X;
  91. float height = Entries[nums[(int)type][i]].GetRectangle.Height * scale.Y;
  92. dst.Offset(width, 0);
  93. _dataSize.Width += (int)width;
  94. if (_dataSize.Height < (int)height)
  95. _dataSize.Height = (int)height;
  96. }
  97. return DataSize;
  98. }
  99. public void Draw(Enum id, int palette, Rectangle dst, Vector2 scale, float fade = 1f, Color? color = null)
  100. {
  101. if ((ID)id != ID.None)
  102. Entries[(ID)id].Draw(Textures, palette, dst, scale, fade, color);
  103. }
  104. public override void Draw(Enum id, Rectangle dst, float fade = 1) => Draw((ID)id, 2, dst, Vector2.One, fade);
  105. public Entry GetEntry(Enum id, int index) => Entries[(ID)id][index] ?? null;
  106. public override Entry GetEntry(Enum id) => Entries[(ID)id][0] ?? null;
  107. public EntryGroup GetEntryGroup(Enum id)
  108. {
  109. if ((ID)id != ID.None)
  110. return Entries[(ID)id] ?? null;
  111. return null;
  112. }
  113. public Color MostSaturated(Enum ic, byte pal)
  114. {
  115. EntryGroup eg = this[(ID)ic];
  116. return eg.MostSaturated(Textures[pal], pal);
  117. }
  118. public override void Trim(Enum ic, byte pal)
  119. {
  120. EntryGroup eg = this[(ID)ic];
  121. eg.Trim(Textures[pal]);
  122. }
  123. protected override void DefaultValues()
  124. {
  125. base.DefaultValues();
  126. Color[] red = new Color[256];
  127. red[15] = new Color(255, 30, 30, 255); //red
  128. red[14] = new Color(140, 30, 30, 255); //dark red
  129. red[13] = new Color(37, 37, 37, 255); //gray
  130. Color[] yellow = new Color[256];
  131. yellow[15] = new Color(222, 222, 8, 255); //yellow
  132. yellow[14] = new Color(131, 131, 24, 255); //dark yellow
  133. yellow[13] = new Color(41, 41, 41, 255); //gray
  134. //FORCE_ORIGINAL = true;
  135. Props = new List<TexProps>()
  136. {
  137. new TexProps{Filename = "icon.tex",Count = 1,Big = new List<BigTexProps>{ new BigTexProps{Filename = "iconfl{0:00}.TEX",Split = 4} } }, //0-15 palette
  138. new TexProps{Filename = "icon.tex",Count = 1,Colors = red,Big = new List<BigTexProps>{ new BigTexProps{Filename = "iconfl{0:00}.TEX",Split = 4,Colors = red } } },//16 palette
  139. new TexProps{Filename = "icon.tex",Count = 1,Colors = yellow,Big = new List<BigTexProps>{ new BigTexProps { Filename = "iconfl{0:00}.TEX", Split = 4, Colors = yellow } } }//17 palette
  140. };
  141. IndexFilename = "icon.sp1";
  142. }
  143. protected override void InitEntries(ArchiveWorker aw = null)
  144. {
  145. if (Entries == null)
  146. {
  147. //read from icon.sp1
  148. MemoryStream ms = null;
  149. using (BinaryReader br = new BinaryReader(ms = new MemoryStream(
  150. ArchiveWorker.GetBinaryFile(ArchiveString,
  151. aw.GetListOfFiles().First(x => x.IndexOf(IndexFilename, StringComparison.OrdinalIgnoreCase) >= 0)))))
  152. {
  153. Loc[] locs = new Loc[br.ReadUInt32()];
  154. for (int i = 0; i < locs.Length; i++)
  155. {
  156. locs[i].seek = br.ReadUInt16();
  157. locs[i].length = br.ReadUInt16();
  158. }
  159. Entries = new Dictionary<ID, EntryGroup>(locs.Length + 10);
  160. for (int i = 0; i < locs.Length; i++)
  161. {
  162. ms.Seek(locs[i].seek, SeekOrigin.Begin);
  163. byte c = (byte)locs[i].length;
  164. Entries[(ID)i] = new EntryGroup(c);
  165. for (int e = 0; e < c; e++)
  166. {
  167. Entry tmp = new Entry();
  168. tmp.LoadfromStreamSP1(br);
  169. tmp.Part = (byte)e;
  170. tmp.SetLoc(locs[i]);
  171. Entries[(ID)i].Add(tmp);
  172. }
  173. }
  174. ms = null;
  175. }
  176. }
  177. }
  178. protected override void InitTextures<T>(ArchiveWorker aw = null)
  179. {
  180. Textures = new List<TextureHandler>();
  181. for (int t = 0; t < Props.Count; t++)
  182. {
  183. T tex = new T();
  184. tex.Load(ArchiveWorker.GetBinaryFile(ArchiveString,
  185. aw.GetListOfFiles().First(x => x.IndexOf(Props[t].Filename, StringComparison.OrdinalIgnoreCase) >= 0)));
  186. if (Props[t].Colors == null || Props[t].Colors.Length == 0)
  187. {
  188. for (ushort i = 0; i < tex.GetClutCount; i++)
  189. {
  190. if (FORCE_ORIGINAL == false && Props[t].Big != null && Props[t].Big.Count > 0)
  191. Textures.Add(TextureHandler.Create(Props[t].Big[0].Filename, tex, 2, Props[t].Big[0].Split / 2, i));
  192. else
  193. Textures.Add(TextureHandler.Create(Props[t].Filename, tex, 1, 1, i));
  194. }
  195. }
  196. else
  197. {
  198. if (FORCE_ORIGINAL == false && Props[t].Big != null && Props[t].Big.Count > 0)
  199. 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));
  200. else
  201. Textures.Add(TextureHandler.Create(Props[t].Filename, tex, 1, 1, (ushort)Textures.Count, colors: Props[t].Colors));
  202. }
  203. }
  204. }
  205. 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)
  206. {
  207. Trim(ic, pal);
  208. EntryGroup eg = this[(ID)ic];
  209. VertexPositionTexture_Texture2D r = Quad(eg[0], Textures[pal], scale, eg.Count == 1 ? options : options | Box_Options.UseOffset);
  210. if (eg.Count > 1)
  211. {
  212. List<VertexPositionTexture> tmp = new List<VertexPositionTexture>(r.VPT.Length * eg.Count);
  213. tmp.AddRange(r.VPT);
  214. for (int i = 1; i < eg.Count; i++)
  215. tmp.AddRange(Quad(eg[0], Textures[pal], scale, options | Box_Options.UseOffset, i * 0.001f).VPT);
  216. return new VertexPositionTexture_Texture2D(tmp.ToArray(), r.Texture);
  217. }
  218. return r;
  219. }
  220. private void Trim()
  221. {
  222. Trim(ID.Bar_Fill, 5);
  223. //trim checks to see if it's ran once before.
  224. //so no need to check if it's already ran.
  225. //will throw exception if not in main thread.
  226. for (byte i = 0; i <= 7; i++)
  227. Trim(ID._0_Hit_ + i, 2);
  228. Trim(ID.Trigger_, 2);
  229. Trim(ID.Perfect__, 2);
  230. Trim(ID.Renzokeken_Seperator, 6);
  231. }
  232. #endregion Methods
  233. //public VertexPositionTexture[] GenerateVPT(Vector3 v, float width, float height)
  234. //{
  235. // Vector3[] verts = new Vector3[]
  236. // {
  237. // new Vector3(v.X-width/2f,v.Y+height/2f,v.Z),
  238. // new Vector3(v.X+width/2f,v.Y+height/2f,v.Z),
  239. // new Vector3(v.X+width/2f,v.Y-height/2f,v.Z),
  240. // new Vector3(v.X-width/2f,v.Y-height/2f,v.Z),
  241. // };
  242. // VertexPositionTexture GetVPT(ref Debug_battleDat.Quad quad, byte i)
  243. // {
  244. // Vector3 GetVertex(ref Quad _quad, byte _i)
  245. // {
  246. // return TransformVertex(verts[_quad.GetIndex(_i)], translationPosition, rotation);
  247. // }
  248. // return new VertexPositionTexture(GetVertex(quad, i), quad.GetUV(i).ToVector2(preVarTex.Width, preVarTex.Height));
  249. // }
  250. // TempVPT[0] = TempVPT[3] = GetVPT(ref this, this[0]);
  251. // TempVPT[1] = GetVPT(ref this, this[1]);
  252. // TempVPT[4] = GetVPT(ref this, this[4]);
  253. // TempVPT[2] = TempVPT[5] = GetVPT(ref this, this[2]);
  254. //}
  255. }
  256. }