debug_MCH.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace FF8
  11. {
  12. public class Debug_MCH
  13. {
  14. const float MODEL_SCALE = 1f;
  15. private uint pBase;
  16. private MemoryStream ms;
  17. private BinaryReader br;
  18. public uint cSkeletonBones;
  19. public uint cVertices;
  20. public uint cTexAnimations;
  21. public uint cFaces;
  22. public uint cUnk;
  23. public uint cSkinObjects;
  24. public uint Unk;
  25. public ushort cTris;
  26. public ushort cQuads;
  27. public uint pBones;
  28. public uint pVertices;
  29. public uint pTexAnimations;
  30. public uint pFaces;
  31. public uint pUnk;
  32. public uint pSkinObjects;
  33. public uint pAnimation;
  34. public uint Unk2;
  35. private struct AnimationKeypoint
  36. {
  37. public short X;
  38. public short Y;
  39. public short Z;
  40. public Vector3[] rot;
  41. }
  42. [StructLayout(LayoutKind.Sequential, Size = 64, Pack = 1)]
  43. private struct Face
  44. {
  45. public int polygonType;
  46. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  47. public byte[] unk;
  48. public short unknown;
  49. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  50. public byte[] unk2;
  51. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  52. public short[] verticesA;
  53. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  54. public short[] verticesB;
  55. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  56. public int[] vertColor;
  57. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  58. public TextureMap[] TextureMap;
  59. public ushort padding;
  60. public ushort texIndex;
  61. public ulong padding2;
  62. public bool BIsQuad => polygonType == 0x2d010709;
  63. }
  64. [StructLayout(LayoutKind.Sequential, Size = 0x40, Pack = 1)]
  65. private struct Bone
  66. {
  67. public ushort parentBone;
  68. public ushort unk;
  69. public uint unk2;
  70. public short size;
  71. [MarshalAs(UnmanagedType.ByValArray, SizeConst =54)]
  72. public byte[] unkBuffer;
  73. }
  74. [StructLayout(LayoutKind.Sequential, Size = 2, Pack = 1)]
  75. private struct TextureMap
  76. {
  77. public byte u;
  78. public byte v;
  79. }
  80. private AnimationKeypoint[] animationKeypoints;
  81. private Bone[] bones;
  82. private Face[] faces;
  83. private Vector4[] vertices;
  84. public Debug_MCH(MemoryStream ms, BinaryReader br)
  85. {
  86. this.ms = ms;
  87. this.br = br;
  88. pBase = (uint)ms.Position;
  89. cSkeletonBones = br.ReadUInt32();
  90. cVertices = br.ReadUInt32();
  91. cTexAnimations = br.ReadUInt32();
  92. cFaces = br.ReadUInt32();
  93. cUnk = br.ReadUInt32();
  94. cSkinObjects = br.ReadUInt32();
  95. Unk = br.ReadUInt32();
  96. cTris = br.ReadUInt16();
  97. cQuads = br.ReadUInt16();
  98. pBones = br.ReadUInt32();
  99. pVertices = br.ReadUInt32();
  100. pTexAnimations = br.ReadUInt32();
  101. pFaces = br.ReadUInt32();
  102. pUnk = br.ReadUInt32();
  103. pSkinObjects = br.ReadUInt32();
  104. pAnimation = br.ReadUInt32();
  105. Unk2 = br.ReadUInt32();
  106. ReadSkeleton();
  107. ReadGeometry();
  108. ReadAnimation();
  109. }
  110. private void ReadSkeleton()
  111. {
  112. ms.Seek(pBase + pBones, SeekOrigin.Begin);
  113. if (ms.Position > ms.Length)
  114. return; //error handler
  115. bones = new Bone[cSkeletonBones];
  116. for (int i = 0; i < cSkeletonBones; i++)
  117. bones[i] = Extended.ByteArrayToStructure<Bone>(br.ReadBytes(64));
  118. return;
  119. }
  120. private void ReadGeometry()
  121. {
  122. ms.Seek(pBase + pVertices, SeekOrigin.Begin);
  123. if (ms.Position > ms.Length || pVertices+ms.Position > ms.Length) //pvert error handler
  124. return; //error handler
  125. vertices = new Vector4[cVertices];
  126. for(int i = 0; i<vertices.Length; i++)
  127. vertices[i] = new Vector4(br.ReadInt16(), br.ReadInt16(), br.ReadInt16(), br.ReadInt16());
  128. ms.Seek(pBase + pFaces, SeekOrigin.Begin);
  129. List<Face> face = new List<Face>();
  130. for(int i = 0; i<cFaces; i++)
  131. face.Add(Extended.ByteArrayToStructure<Face>(br.ReadBytes(64)));
  132. faces = face.ToArray();
  133. return;
  134. }
  135. private void ReadAnimation()
  136. {
  137. ms.Seek(pBase + pAnimation, SeekOrigin.Begin);
  138. if (ms.Position > ms.Length)
  139. return; //error handler
  140. ushort animationCount = br.ReadUInt16();
  141. List<AnimationKeypoint> animKeypoints = new List<AnimationKeypoint>();
  142. while (animationCount != 0/*(cEntries = br.ReadUInt16()) != 0*/)
  143. {
  144. ushort animationFramesCount = br.ReadUInt16();
  145. ushort cBones = br.ReadUInt16();
  146. while (animationFramesCount != 0)
  147. {
  148. AnimationKeypoint keyPoint = new AnimationKeypoint() { X = br.ReadInt16(), Y = br.ReadInt16(), Z = br.ReadInt16() };
  149. Vector3[] vetRot = new Vector3[cBones];
  150. for (int i = 0; i < cBones; i++)
  151. vetRot[i] = new Vector3() { X = br.ReadInt16()/4096.0f, Y = br.ReadUInt16()/4096.0f, Z = br.ReadUInt16()/4096.0f };
  152. animationFramesCount--;
  153. keyPoint.rot = vetRot;
  154. animKeypoints.Add(keyPoint);
  155. }
  156. animationCount--;
  157. }
  158. animationKeypoints = animKeypoints.ToArray();
  159. return;
  160. }
  161. public Tuple<VertexPositionColorTexture[], byte[]> GetVertexPositions(int baseX =0, int baseY=0, int baseZ=0)
  162. {
  163. List<VertexPositionColorTexture> facesVertices = new List<VertexPositionColorTexture>();
  164. List<byte> texIndexes = new List<byte>();
  165. for(int i = 0; i<faces.Length; i++)
  166. {
  167. if (!faces[i].BIsQuad) //triangles please
  168. {
  169. for (int k = 0; k < 3; k++)
  170. {
  171. Vector3 face = new Vector3(vertices[faces[i].verticesA[k]].X / MODEL_SCALE + baseX,
  172. vertices[faces[i].verticesA[k]].Z / MODEL_SCALE * -1f + baseY,
  173. vertices[faces[i].verticesA[k]].Y / MODEL_SCALE + baseZ);
  174. Color clr = new Color(faces[i].vertColor[0], faces[i].vertColor[1], faces[i].vertColor[2], faces[i].vertColor[3]);
  175. Vector2 texData = new Vector2(faces[i].TextureMap[k].u/256.0f, faces[i].TextureMap[k].v/256.0f);
  176. facesVertices.Add( new VertexPositionColorTexture(face, clr, texData));
  177. texIndexes.Add((byte)faces[i].texIndex);
  178. if (faces[i].texIndex > byte.MaxValue)
  179. throw new Exception("Reverse engineering: test texture index? above 255, but datatype is word");
  180. }
  181. }
  182. else //we may need to actually retriangulate
  183. {
  184. Vector3 A = new Vector3(vertices[faces[i].verticesA[0]].X / MODEL_SCALE + baseX,
  185. vertices[faces[i].verticesA[0]].Z / MODEL_SCALE * 1f + baseY,
  186. vertices[faces[i].verticesA[0]].Y / MODEL_SCALE + baseZ);
  187. Vector3 B = new Vector3(vertices[faces[i].verticesA[1]].X / MODEL_SCALE + baseX,
  188. vertices[faces[i].verticesA[1]].Z / MODEL_SCALE * 1f + baseY,
  189. vertices[faces[i].verticesA[1]].Y / MODEL_SCALE + baseZ);
  190. Vector3 C = new Vector3(vertices[faces[i].verticesA[2]].X / MODEL_SCALE + baseX,
  191. vertices[faces[i].verticesA[2]].Z / MODEL_SCALE * 1f + baseY,
  192. vertices[faces[i].verticesA[2]].Y / MODEL_SCALE + baseZ);
  193. Vector3 D = new Vector3(vertices[faces[i].verticesA[3]].X / MODEL_SCALE + baseX,
  194. vertices[faces[i].verticesA[3]].Z / MODEL_SCALE * 1f + baseY,
  195. vertices[faces[i].verticesA[3]].Y / MODEL_SCALE + baseZ);
  196. Vector2 t1 = new Vector2(faces[i].TextureMap[0].u / 256.0f, faces[i].TextureMap[0].v / 256.0f);
  197. Vector2 t2 = new Vector2(faces[i].TextureMap[1].u / 256.0f, faces[i].TextureMap[1].v / 256.0f);
  198. Vector2 t3 = new Vector2(faces[i].TextureMap[2].u / 256.0f, faces[i].TextureMap[2].v / 256.0f);
  199. Vector2 t4 = new Vector2(faces[i].TextureMap[3].u / 256.0f, faces[i].TextureMap[3].v / 256.0f);
  200. Color clr = new Color(faces[i].vertColor[0], faces[i].vertColor[1], faces[i].vertColor[2], faces[i].vertColor[3]);
  201. facesVertices.Add(new VertexPositionColorTexture(A, clr, t1));
  202. facesVertices.Add(new VertexPositionColorTexture(B, clr, t2));
  203. facesVertices.Add(new VertexPositionColorTexture(D, clr, t4));
  204. facesVertices.Add(new VertexPositionColorTexture(A, clr, t1));
  205. facesVertices.Add(new VertexPositionColorTexture(C, clr, t3));
  206. facesVertices.Add(new VertexPositionColorTexture(D, clr, t4));
  207. if (faces[i].texIndex > byte.MaxValue)
  208. throw new Exception("Reverse engineering: test texture index? above 255, but datatype is word");
  209. texIndexes.Add((byte)faces[i].texIndex); texIndexes.Add((byte)faces[i].texIndex);
  210. }
  211. }
  212. return new Tuple<VertexPositionColorTexture[], byte[]>(facesVertices.ToArray(), texIndexes.ToArray());
  213. }
  214. }
  215. }