Strings.Kernel.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using System.Collections.Generic;
  2. using System.IO;
  3. namespace OpenVIII
  4. {
  5. /// <summary>
  6. /// Loads strings from FF8 files
  7. /// </summary>
  8. public partial class Strings
  9. {
  10. #region Classes
  11. /// <summary>
  12. /// <para>Kernel.bin Strings</para>
  13. /// <para>Has Multi-byte Characters, Requires Namedic</para>
  14. /// </summary>
  15. public sealed class Kernel : StringsBase
  16. {
  17. #region Constructors
  18. public static Kernel Load() => Load<Kernel>();
  19. protected override void DefaultValues() => SetValues(Memory.Archives.A_MAIN, "kernel.bin");
  20. #endregion Constructors
  21. #region Properties
  22. /// <summary>
  23. /// <para>uint pointer locations, tuple(uint StringLocation,uint get, unit skip)</para>
  24. /// <para>
  25. /// So you read the pointers at location, you get so many pointers then skip so many
  26. /// bytes before getting more pointers. Do this till start of next section.
  27. /// </para>
  28. /// </summary>
  29. /// <remarks>Colly's list of string pointers. Adapted.</remarks>
  30. /// <see cref="http://www.balamb.pl/qh/kernel-pointers.htm"/>
  31. public IReadOnlyDictionary<int, (uint StringLocation, uint Get, uint Skip)> StringLocations
  32. { get; } = new Dictionary<int, (uint StringLocation, uint Get, uint Skip)>(){
  33. {0, (31,2,4)},
  34. {1, (32,2,56) },
  35. {2, (33,2,128) },
  36. {3, (34,1,18) },//38,58,178, or 78
  37. {4, (35,1,10) },
  38. {5, (36,2,20) },
  39. {6, (37,1,34) },//+1interval 70 //character names here.
  40. {7, (38,2,20) },
  41. {8, (39,1,0) },
  42. {9, (40,1,18) },
  43. {11, (41,2,4) },
  44. {12, (42,2,4) },
  45. {13, (43,2,4) },
  46. {14, (44,2,4) },
  47. {15, (45,2,4) },
  48. {16, (46,2,4) },
  49. {17, (47,2,4) },
  50. {18, (48,2,20) },
  51. {19, (49,2,12) },
  52. {21, (50,2,20) },
  53. {22, (51,2,28) },
  54. {24, (52,2,4) },
  55. {25, (53,1,18) },
  56. {28, (54,1,10) },
  57. {30, (55,1,0) },
  58. };
  59. #endregion Properties
  60. #region Methods
  61. /// <summary>
  62. /// Read Section Pointers
  63. /// </summary>
  64. /// <param name="br"></param>
  65. private void GetFileLocations(BinaryReader br)
  66. {
  67. var count = br.ReadUInt32();
  68. while (count-- > 0)
  69. {
  70. var seek = br.ReadUInt32();
  71. uint length;
  72. if (count <= 0) length = (uint)br.BaseStream.Length - seek;
  73. else
  74. {
  75. length = br.ReadUInt32() - seek;
  76. br.BaseStream.Seek(-4, SeekOrigin.Current);
  77. }
  78. StringFiles.SubPositions.Add(Loc.CreateInstance(seek, length));
  79. }
  80. }
  81. /// <summary>
  82. /// Fetch strings from kernel.bin
  83. /// </summary>
  84. /// <see cref="http://www.balamb.pl/qh/kernel-pointers.htm"/>
  85. protected override void LoadArchiveFiles()
  86. {
  87. Settings = (FF8StringReference.Settings.MultiCharByte | FF8StringReference.Settings.Namedic);
  88. var aw = ArchiveWorker.Load(Archive);
  89. StringFiles = new StringFile(56);
  90. var buffer = aw.GetBinaryFile(FileNames[0], true);
  91. if (buffer == null) return;
  92. using (var br = new BinaryReader(new MemoryStream(buffer)))
  93. {
  94. GetFileLocations(br);
  95. for (var key = 0; key < StringFiles.SubPositions.Count; key++)
  96. {
  97. if (StringLocations.ContainsKey(key))
  98. {
  99. Get_Strings_BinMSG(br, FileNames[0], key, StringFiles.SubPositions[(int)(StringLocations[key].Item1)].Seek, StringLocations[key].Item2, StringLocations[key].Item3);
  100. }
  101. }
  102. }
  103. }
  104. #endregion Methods
  105. }
  106. #endregion Classes
  107. }
  108. }