Strings.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. namespace OpenVIII
  7. {
  8. /// <summary>
  9. /// Loads strings from FF8 files
  10. /// </summary>
  11. public partial class Strings
  12. {
  13. #region Fields
  14. private static ConcurrentDictionary<FileID, StringsBase> Files;
  15. private static object Filesloc = new object();
  16. #endregion Fields
  17. #region Constructors
  18. public Strings() => Init();
  19. #endregion Constructors
  20. #region Enums
  21. /// <summary>
  22. /// filenames of files with strings and id's for structs that hold the data.
  23. /// </summary>
  24. public enum FileID : uint
  25. {
  26. MNGRP = 0,
  27. AREAMES = 2,
  28. NAMEDIC = 3,
  29. KERNEL = 4,
  30. }
  31. #endregion Enums
  32. #region Methods
  33. public FF8String GetName(Characters c, Saves.Data d = null) => GetName(c.ToFacesID(), d);
  34. public FF8String GetName(GFs gf, Saves.Data d = null) => GetName(gf.ToFacesID(), d);
  35. public FF8String GetName(Faces.ID id, Saves.Data d = null)
  36. {
  37. if (d == null)
  38. d = Memory.State;
  39. switch (id)
  40. {
  41. case Faces.ID.Squall_Leonhart:
  42. return d.Squallsname ?? Read(FileID.MNGRP, 2, 92);
  43. case Faces.ID.Rinoa_Heartilly:
  44. return d.Rinoasname ?? Read(FileID.MNGRP, 2, 93);
  45. case Faces.ID.Angelo:
  46. return d.Angelosname ?? Read(FileID.MNGRP, 2, 94);
  47. case Faces.ID.Boko:
  48. return d.Bokosname ?? Read(FileID.MNGRP, 2, 135);
  49. case Faces.ID.Zell_Dincht:
  50. case Faces.ID.Irvine_Kinneas:
  51. case Faces.ID.Quistis_Trepe:
  52. case Faces.ID.Selphie_Tilmitt:
  53. case Faces.ID.Seifer_Almasy:
  54. case Faces.ID.Edea_Kramer:
  55. case Faces.ID.Laguna_Loire:
  56. case Faces.ID.Kiros_Seagill:
  57. case Faces.ID.Ward_Zabac:
  58. return Read(FileID.KERNEL, 6, (int)id);
  59. case Faces.ID.Quezacotl:
  60. case Faces.ID.Shiva:
  61. case Faces.ID.Ifrit:
  62. case Faces.ID.Siren:
  63. case Faces.ID.Brothers:
  64. case Faces.ID.Diablos:
  65. case Faces.ID.Carbuncle:
  66. case Faces.ID.Leviathan:
  67. case Faces.ID.Pandemona:
  68. case Faces.ID.Cerberus:
  69. case Faces.ID.Alexander:
  70. case Faces.ID.Doomtrain:
  71. case Faces.ID.Bahamut:
  72. case Faces.ID.Cactuar:
  73. case Faces.ID.Tonberry:
  74. case Faces.ID.Eden:
  75. return d.GFs[id.ToGFs()].Name ?? Read(FileID.MNGRP, 2, 95 + (int)(id.ToGFs()));
  76. case Faces.ID.Griever:
  77. return d.Grieversname ?? Read(FileID.MNGRP, 2, 135);
  78. case Faces.ID.MiniMog:
  79. return Read(FileID.KERNEL, 0, 72); // also in KERNEL, 12, 36
  80. default:
  81. return new FF8String();
  82. }
  83. }
  84. /// <summary>
  85. /// Remember to Close() if done using
  86. /// </summary>
  87. /// <param name="fileID"></param>
  88. /// <param name="sectionID"></param>
  89. /// <param name="stringID"></param>
  90. /// <returns></returns>
  91. public FF8StringReference Read(FileID fileID, int sectionID, int stringID) => Files[fileID][(uint)sectionID, stringID];
  92. public StringsBase this[FileID id] => Files[id];
  93. private void Init()
  94. {
  95. lock (Filesloc)
  96. if (Files == null)
  97. {
  98. var tasks = new List<Task<bool>>();
  99. Files = new ConcurrentDictionary<FileID, StringsBase>();
  100. tasks.Add(Task.Run(() => Files.TryAdd(FileID.NAMEDIC, Namedic.Load()))); // areames and kernel require namedic
  101. //though there shouldn't be anything reading the strings till this is done processing
  102. //Task.WaitAll(tasks.ToArray());
  103. tasks.Add(Task.Run(() => Files.TryAdd(FileID.MNGRP, Mngrp.Load())));
  104. tasks.Add(Task.Run(() => Files.TryAdd(FileID.AREAMES, Areames.Load())));
  105. tasks.Add(Task.Run(() => Files.TryAdd(FileID.KERNEL, Kernel.Load())));
  106. Task.WaitAll(tasks.ToArray());
  107. if (tasks.Any(x => !x.Result))
  108. throw new ArgumentException($"{this}::Failed to add to dictionary...");
  109. }
  110. }
  111. #endregion Methods
  112. }
  113. }