Module.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Input;
  3. using OpenVIII.Encoding.Tags;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using System.Linq;
  9. namespace OpenVIII.Fields
  10. {
  11. //issues found.
  12. //558 //color looks off on glow. with purple around it.
  13. //267 //text showing with white background.
  14. //132 missing lava.
  15. //pupu states that there is are 2 widths of the texture for Type1 and Type2
  16. //we are only using 1 so might be reading the wrong pixels somewhere.
  17. public static partial class Module
  18. {
  19. #region Fields
  20. public static Background Background;
  21. public static WalkMesh WalkMesh;
  22. private static EventEngine eventEngine;
  23. private static Field_mods mod = 0;
  24. //private static Texture2D tex;
  25. //private static Texture2D texOverlap;
  26. private static IServices services;
  27. #endregion Fields
  28. #region Enums
  29. [Flags]
  30. public enum _Toggles : byte
  31. {
  32. DumpingData = 0x1,
  33. ClassicSpriteBatch = 0x2,
  34. Quad = 0x4,
  35. WalkMesh = 0x8,
  36. Deswizzle = 0x10,
  37. Perspective = 0x20,
  38. Menu = 0x40,
  39. }
  40. public enum Field_mods
  41. {
  42. INIT,
  43. DEBUGRENDER,
  44. DISABLED,
  45. NOJSM
  46. };
  47. public static _Toggles Flip(this _Toggles flagged, _Toggles flag)
  48. => flagged ^= flag;
  49. #endregion Enums
  50. #region Properties
  51. public static Cameras Cameras { get; private set; }
  52. public static FieldMenu FieldMenu { get; private set; }
  53. public static _Toggles Toggles { get; set; } = _Toggles.Quad | _Toggles.Menu;
  54. public static Field_mods Mod { get => mod; }
  55. #endregion Properties
  56. #region Methods
  57. public static void Draw()
  58. {
  59. Memory.graphics.GraphicsDevice.Clear(Color.Black);
  60. switch (mod)
  61. {
  62. case Field_mods.INIT:
  63. break; //null
  64. default:
  65. DrawDebug();
  66. break;
  67. case Field_mods.DISABLED:
  68. FieldMenu.Draw();
  69. break;
  70. }
  71. }
  72. public static string GetFieldName()
  73. {
  74. string fieldname = Memory.FieldHolder.fields[Memory.FieldHolder.FieldID].ToLower();
  75. if (string.IsNullOrWhiteSpace(fieldname))
  76. fieldname = $"unk{Memory.FieldHolder.FieldID}";
  77. return fieldname;
  78. }
  79. public static string GetFolder(string fieldname = null)
  80. {
  81. if (string.IsNullOrWhiteSpace(fieldname))
  82. fieldname = GetFieldName();
  83. string folder = Path.Combine(Path.GetTempPath(), "Fields", fieldname.Substring(0, 2), fieldname);
  84. Directory.CreateDirectory(folder);
  85. return folder;
  86. }
  87. public static void ResetField()
  88. {
  89. Memory.SuppressDraw = true;
  90. mod = Field_mods.INIT;
  91. }
  92. public static void Update()
  93. {
  94. // lets you move through all the feilds just holding left or right. it will just loop when it runs out.
  95. //if (false && Input2.DelayedButton(FF8TextTagKey.Left))
  96. //{
  97. // init_debugger_Audio.PlaySound(0);
  98. // if (Memory.FieldHolder.FieldID > 0)
  99. // Memory.FieldHolder.FieldID--;
  100. // else
  101. // Memory.FieldHolder.FieldID = checked((ushort)(Memory.FieldHolder.fields.Length - 1));
  102. // ResetField();
  103. //}
  104. //else if (false && Input2.DelayedButton(FF8TextTagKey.Right))
  105. //{
  106. // init_debugger_Audio.PlaySound(0);
  107. // if (Memory.FieldHolder.FieldID < checked((ushort)(Memory.FieldHolder.fields.Length - 1)))
  108. // Memory.FieldHolder.FieldID++;
  109. // else
  110. // Memory.FieldHolder.FieldID = 0;
  111. // ResetField();
  112. //}
  113. if (Input2.DelayedButton(Keys.D0))
  114. Toggles = Toggles.Flip(_Toggles.Menu);
  115. else
  116. {
  117. switch (mod)
  118. {
  119. case Field_mods.INIT:
  120. Init();
  121. break;
  122. case Field_mods.DEBUGRENDER:
  123. UpdateScript();
  124. Background.Update();
  125. if (Toggles.HasFlag(_Toggles.Menu))
  126. FieldMenu.Update();
  127. break; //await events here
  128. case Field_mods.NOJSM://no scripts but has background.
  129. Background.Update();
  130. if (Toggles.HasFlag(_Toggles.Menu))
  131. FieldMenu.Update();
  132. break; //await events here
  133. case Field_mods.DISABLED:
  134. FieldMenu.Update();
  135. break;
  136. }
  137. }
  138. }
  139. private static void DrawDebug()
  140. {
  141. Background.Draw();
  142. //Memory.SpriteBatchStartAlpha();
  143. //Memory.font.RenderBasicText($"FieldID: {GetFieldID()} - {GetFieldName().ToUpper()}" +
  144. // $"\n4-Bit: {Background.Is4Bit}" +
  145. // $"\nadd: {Background.IsAddBlendMode}" +
  146. // $"\n1/2 add: {Background.IsHalfBlendMode}" +
  147. // $"\n1/4 add: {Background.IsQuarterBlendMode}" +
  148. // $"\nsubtract: {Background.IsSubtractBlendMode}", new Point(20, 20), new Vector2(3f));
  149. //Memory.SpriteBatchEnd();
  150. if(Toggles.HasFlag(_Toggles.Menu))
  151. FieldMenu.Draw();
  152. }
  153. private static void DrawEntities() => throw new NotImplementedException();
  154. private static ushort GetFieldID() => Memory.FieldHolder.FieldID;
  155. private static void Init()
  156. {
  157. Memory.SuppressDraw = true;
  158. ArchiveWorker aw = new ArchiveWorker(Memory.Archives.A_FIELD);
  159. string[] test = aw.GetListOfFiles();
  160. FieldMenu = FieldMenu.Create();
  161. //TODO fix endless look on FieldID 50.
  162. if (Memory.FieldHolder.FieldID >= Memory.FieldHolder.fields.Length ||
  163. Memory.FieldHolder.FieldID < 0)
  164. return;
  165. string fieldArchiveName = test.FirstOrDefault(x => x.IndexOf(Memory.FieldHolder.GetString(), StringComparison.OrdinalIgnoreCase) >= 0);
  166. if (string.IsNullOrWhiteSpace(fieldArchiveName))
  167. {
  168. Debug.WriteLine($"FileNotFound :: {Memory.FieldHolder.FieldID} - {Memory.FieldHolder.GetString().ToUpper()}");
  169. mod = Field_mods.DISABLED;
  170. return;
  171. }
  172. ArchiveBase fieldArchive = aw.GetArchive(fieldArchiveName);
  173. string[] filelist = fieldArchive.GetListOfFiles();
  174. string findstr(string s) =>
  175. filelist.FirstOrDefault(x => x.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0);
  176. byte[] getfile(string s)
  177. {
  178. s = findstr(s);
  179. if (!string.IsNullOrWhiteSpace(s))
  180. return fieldArchive.GetBinaryFile(s);
  181. else
  182. return null;
  183. }
  184. string s_jsm = findstr(".jsm");
  185. string s_sy = findstr(".sy");
  186. if ((Background = Background.Load(getfile(".mim"), getfile(".map"))) == null)
  187. {
  188. mod = Field_mods.DISABLED;
  189. return;
  190. }
  191. Cameras = Cameras.Load(getfile(".ca"));
  192. WalkMesh = WalkMesh.Load(getfile(".id"));
  193. //let's start with scripts
  194. List<Scripts.Jsm.GameObject> jsmObjects;
  195. if (!string.IsNullOrWhiteSpace(s_jsm))
  196. {
  197. try
  198. {
  199. jsmObjects = Scripts.Jsm.File.Read(fieldArchive.GetBinaryFile(s_jsm));
  200. }
  201. catch (Exception e)
  202. {
  203. Debug.WriteLine(e);
  204. mod = Field_mods.NOJSM;
  205. return;
  206. }
  207. Sym.GameObjects symObjects;
  208. if (!string.IsNullOrWhiteSpace(s_sy))
  209. {
  210. symObjects = Sym.Reader.FromBytes(fieldArchive.GetBinaryFile(s_sy));
  211. }
  212. else
  213. {
  214. Debug.WriteLine($"FileNotFound :: {Memory.FieldHolder.GetString().ToUpper()}.sy");
  215. mod = Field_mods.NOJSM;
  216. return;
  217. }
  218. services = Initializer.GetServices();
  219. eventEngine = ServiceId.Field[services].Engine;
  220. eventEngine.Reset();
  221. for (int objIndex = 0; objIndex < jsmObjects.Count; objIndex++)
  222. {
  223. Scripts.Jsm.GameObject obj = jsmObjects[objIndex];
  224. FieldObject fieldObject = new FieldObject(obj.Id, symObjects.GetObjectOrDefault(objIndex).Name);
  225. foreach (Scripts.Jsm.GameScript script in obj.Scripts)
  226. fieldObject.Scripts.Add(script.ScriptId, script.Segment.GetExecuter());
  227. eventEngine.RegisterObject(fieldObject);
  228. }
  229. }
  230. else
  231. {
  232. mod = Field_mods.NOJSM;
  233. return;
  234. }
  235. //byte[] mchb = getfile(".mch");//Field character models
  236. //byte[] oneb = getfile(".one");//Field character models container
  237. //byte[] msdb = getfile(".msd");//dialogs
  238. //byte[] infb = getfile(".inf");//gateways
  239. //byte[] idb = getfile(".id");//walkmesh
  240. //byte[] cab = getfile(".ca");//camera
  241. //byte[] tdwb = getfile(".tdw");//extra font
  242. //byte[] mskb = getfile(".msk");//movie cam
  243. //byte[] ratb = getfile(".rat");//battle on field
  244. //byte[] pmdb = getfile(".pmd");//particle info
  245. //byte[] sfxb = getfile(".sfx");//sound effects
  246. mod++;
  247. return;
  248. }
  249. private static void UpdateScript()
  250. {
  251. //We do not know every instruction and it's not possible for now to play field with unknown instruction
  252. //eventEngine.Update(services);
  253. }
  254. #endregion Methods
  255. ///// <summary>
  256. ///// Blend the colors depending on tile.blendmode
  257. ///// </summary>
  258. ///// <param name="finalImageColor"></param>
  259. ///// <param name="color"></param>
  260. ///// <param name="tile"></param>
  261. ///// <returns>Color</returns>
  262. ///// <see cref="http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt"/>
  263. ///// <seealso cref="http://www.psxdev.net/forum/viewtopic.php?t=953"/>
  264. ///// <seealso cref="//http://wiki.ffrtt.ru/index.php?title=FF8/FileFormat_MAP"/>
  265. //private static Color BlendColors(ref Color finalImageColor, Color color, Tile tile)
  266. //{
  267. // //• Semi Transparency
  268. // //When semi transparency is set for a pixel, the GPU first reads the pixel it wants to write to, and then calculates
  269. // //the color it will write from the 2 pixels according to the semi - transparency mode selected.Processing speed is lower
  270. // //in this mode because additional reading and calculating are necessary.There are 4 semi - transparency modes in the
  271. // //GPU.
  272. // //B = the pixel read from the image in the frame buffer, F = the half transparent pixel
  273. // //• 1.0 x B + 0.5 x F
  274. // //• 1.0 x B + 1.0 x F
  275. // //• 1.0 x B - 1.0 x F
  276. // //• 1.0 x B + 0.25 x F
  277. // //color must not be black
  278. // Color baseColor = finalImageColor;
  279. // //BlendState blendmode1 = new BlendState
  280. // //{
  281. // // ColorSourceBlend = Blend.SourceColor,
  282. // // ColorDestinationBlend = Blend.DestinationColor,
  283. // // ColorBlendFunction = BlendFunction.Add
  284. // //};
  285. // //BlendState blendmode2 = new BlendState
  286. // //{
  287. // // ColorSourceBlend = Blend.SourceColor,
  288. // // ColorDestinationBlend = Blend.DestinationColor,
  289. // // ColorBlendFunction = BlendFunction.Subtract
  290. // //};
  291. // //BlendState blendmode3 = new BlendState
  292. // //{
  293. // // BlendFactor =
  294. // // ColorSourceBlend = Blend.SourceColor,
  295. // // ColorDestinationBlend = Blend.DestinationColor,
  296. // // ColorBlendFunction = BlendFunction.Subtract
  297. // //};
  298. // switch (tile.BlendMode)
  299. // {
  300. // case BlendMode.halfadd:
  301. // return finalImageColor = blend0(baseColor, color);
  302. // case BlendMode.add:
  303. // return finalImageColor = blend1(baseColor, color);
  304. // case BlendMode.subtract:
  305. // return finalImageColor = blend2(baseColor, color);
  306. // case BlendMode.quarteradd:
  307. // //break;
  308. // return finalImageColor = blend3(baseColor, color);
  309. // }
  310. // throw new Exception($"Blendtype is {tile.BlendMode}: There are only 4 blend modes, 0-3, 4+ are drawn directly.");
  311. //}
  312. }
  313. }