module_overture_debug.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using Microsoft.Xna.Framework.Input;
  4. using OpenVIII.Encoding.Tags;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.IO;
  9. using System.Linq;
  10. namespace OpenVIII
  11. {
  12. public static class Module_overture_debug
  13. {
  14. #region Fields
  15. private const float speed = 1f;
  16. private static bool bFadingIn;
  17. private static bool bNames;
  18. //by default first should fade in, wait, then fire fading out and wait for finish, then loop
  19. private static bool bWaitingSplash, bFadingOut;
  20. private static float fSplashWait, Fade;
  21. private static OverturepublicModule publicModule = OverturepublicModule._5Reset;
  22. private static double publicTimer;
  23. private static int splashIndex, splashName, splashLoop;
  24. private static Splash splashTex;
  25. #endregion Fields
  26. #region Enums
  27. private enum OverturepublicModule
  28. {
  29. _0InitSound,
  30. _1WaitBeforeFirst,
  31. _2PlaySequence,
  32. _3SequenceFinishedPlayMainMenu,
  33. _4Squaresoft,
  34. _5Reset
  35. }
  36. #endregion Enums
  37. #region Properties
  38. private static float Fadespd1 => (float)(Memory.ElapsedGameTime.TotalMilliseconds / 500f) * speed;
  39. private static float Fadespd2 => (float)Fadespd5;
  40. private static float Fadespd3 => (float)(Memory.ElapsedGameTime.TotalMilliseconds / 5000.0f) * speed;
  41. private static float Fadespd4 => (float)(Memory.ElapsedGameTime.TotalMilliseconds / 2000.0f) * speed;
  42. private static double Fadespd5 => (Memory.ElapsedGameTime.TotalMilliseconds / 1000.0d) * speed;
  43. #endregion Properties
  44. #region Methods
  45. public static void Draw()
  46. {
  47. Memory.Graphics.GraphicsDevice.Clear(Color.Black);
  48. switch (publicModule)
  49. {
  50. case OverturepublicModule._2PlaySequence:
  51. DrawSplash();
  52. break; //actually this is our entry point for draw;
  53. case OverturepublicModule._3SequenceFinishedPlayMainMenu:
  54. DrawLogo(); //after this ends, jump into main menu module
  55. break;
  56. }
  57. }
  58. public static void ResetModule()
  59. {
  60. bFadingIn = true;
  61. bNames = true;
  62. publicModule = 0;
  63. publicTimer = 0.0f;
  64. bFadingIn = true;
  65. bWaitingSplash = false;
  66. fSplashWait = 0.0f;
  67. bFadingOut = false;
  68. Fade = 0;
  69. splashIndex = 0;
  70. splashName = splashLoop = 1;
  71. splashTex = null;
  72. Memory.SpriteBatch.GraphicsDevice.Clear(Color.Black);
  73. Memory.Module = Module.OvertureDebug;
  74. publicModule = OverturepublicModule._4Squaresoft;
  75. ModuleMovieTest.ReturnState = Module.OvertureDebug;
  76. }
  77. public static void SplashUpdate(ref int _splashIndex)
  78. {
  79. if (splashTex == null)
  80. {
  81. ReadSplash();
  82. }
  83. if (bFadingIn)
  84. {
  85. Fade += Fadespd1;
  86. if (Fade > 1.0f)
  87. {
  88. Fade = 1.0f;
  89. bFadingIn = false;
  90. bWaitingSplash = true;
  91. }
  92. }
  93. if (bFadingOut)
  94. {
  95. if (splashLoop + 1 >= 0x0F && splashName >= 0x0F)
  96. {
  97. bFadingIn = false;
  98. bFadingOut = true;
  99. bWaitingSplash = false;
  100. publicTimer = 0.0f;
  101. Fade = 1.0f;
  102. publicModule++;
  103. return;
  104. }
  105. Fade -= Fadespd1;
  106. if (Fade < 0.0f)
  107. {
  108. bFadingIn = true;
  109. bFadingOut = false;
  110. Fade = 0.0f;
  111. _splashIndex++;
  112. if (bNames)
  113. {
  114. splashName++;
  115. }
  116. else
  117. {
  118. splashLoop++;
  119. }
  120. if (_splashIndex > 1)
  121. {
  122. bNames = !bNames;
  123. _splashIndex = 0;
  124. }
  125. ReadSplash();
  126. }
  127. }
  128. if (bWaitingSplash)
  129. {
  130. if (bNames)
  131. {
  132. if (fSplashWait > 4.8f)
  133. {
  134. bWaitingSplash = false;
  135. bFadingOut = true;
  136. fSplashWait = 0.0f;
  137. }
  138. }
  139. else
  140. {
  141. if (fSplashWait > 6.5f)
  142. {
  143. bWaitingSplash = false;
  144. bFadingOut = true;
  145. fSplashWait = 0.0f;
  146. }
  147. }
  148. Memory.SuppressDraw = true;
  149. fSplashWait += Fadespd2;
  150. }
  151. //loop 01-14 + name01-14;
  152. }
  153. public static void Update()
  154. {
  155. if (Input2.DelayedButton(FF8TextTagKey.Confirm) || Input2.DelayedButton(FF8TextTagKey.Cancel) || Input2.DelayedButton(Keys.Space))
  156. {
  157. AV.Music.Stop();
  158. Memory.Module = Module.MainMenuDebug;
  159. }
  160. switch (publicModule)
  161. {
  162. case OverturepublicModule._0InitSound:
  163. InitSound();
  164. break;
  165. case OverturepublicModule._1WaitBeforeFirst:
  166. Memory.SuppressDraw = true;
  167. WaitForFirst();
  168. break;
  169. case OverturepublicModule._2PlaySequence:
  170. SplashUpdate(ref splashIndex);
  171. break;
  172. case OverturepublicModule._4Squaresoft:
  173. publicModule = OverturepublicModule._0InitSound;
  174. ModuleMovieTest.Index = 104;//104 is SE logo in steam release.
  175. ModuleMovieTest.ReturnState = Module.OvertureDebug;
  176. Memory.Module = Module.MovieTest;
  177. break;
  178. case OverturepublicModule._5Reset:
  179. ResetModule();
  180. Update();
  181. return;
  182. }
  183. }
  184. private static void DrawLogo()
  185. {
  186. if (splashTex != null)
  187. {
  188. if (!bWaitingSplash)
  189. {
  190. Memory.Graphics.GraphicsDevice.Clear(Color.White);
  191. Memory.SpriteBatchStartAlpha(ss: SamplerState.AnisotropicClamp);
  192. }
  193. else
  194. {
  195. Memory.SpriteBatchStartStencil(ss: SamplerState.AnisotropicClamp);
  196. }
  197. Memory.SpriteBatch.Draw(splashTex,
  198. new Rectangle(0, 0, Memory.Graphics.GraphicsDevice.Viewport.Width, Memory.Graphics.GraphicsDevice.Viewport.Height),
  199. new Rectangle(0, 0, splashTex.Width, splashTex.Height)
  200. , Color.White * Fade);
  201. if (bFadingIn)
  202. {
  203. Fade += Fadespd3;
  204. }
  205. if (bFadingOut)
  206. {
  207. Fade -= Fadespd4;
  208. }
  209. if (Fade < 0.0f)
  210. {
  211. bFadingIn = true;
  212. ReadSplash(true);
  213. bFadingOut = false;
  214. }
  215. if (bFadingIn && Fade > 1.0f && !bWaitingSplash)
  216. {
  217. publicTimer += Fadespd5;
  218. }
  219. if (publicTimer > 5.0f)
  220. {
  221. bWaitingSplash = true;
  222. bFadingOut = true;
  223. }
  224. Memory.SpriteBatchEnd();
  225. if (bWaitingSplash && Fade < 0.0f)
  226. {
  227. Memory.Module = Module.MainMenuDebug;
  228. }
  229. }
  230. }
  231. private static void DrawSplash()
  232. {
  233. if (splashTex == null)
  234. {
  235. return;
  236. }
  237. Memory.SpriteBatchStartStencil(ss: SamplerState.AnisotropicClamp);
  238. Memory.SpriteBatch.Draw(splashTex,
  239. new Rectangle(0, 0, Memory.Graphics.GraphicsDevice.Viewport.Width, Memory.Graphics.GraphicsDevice.Viewport.Height),
  240. new Rectangle(0, 0, splashTex.Width, splashTex.Height)
  241. , Color.White * Fade);
  242. Memory.SpriteBatchEnd();
  243. }
  244. private static void InitSound()
  245. {
  246. AV.Music.Play(79, loop: false);
  247. Memory.MusicIndex = ushort.MaxValue; // reset pos after playing overture; will loop back to start if push next
  248. publicModule++;
  249. }
  250. private static void ReadSplash(bool bLogo = false) => splashTex = new Splash(bNames ? splashName : splashLoop, bNames, bLogo);
  251. private static void WaitForFirst()
  252. {
  253. if (publicTimer > 6.0f)
  254. {
  255. publicModule++;
  256. Console.WriteLine("MODULE_OVERTURE: DEBUG MODULE 2");
  257. }
  258. publicTimer += Fadespd5;
  259. }
  260. #endregion Methods
  261. }
  262. public class Splash : IDisposable
  263. {
  264. #region Fields
  265. private const string loops = "loop";
  266. private const string names = "name";
  267. private static List<string> logonames;
  268. private static List<string> loopsnames;
  269. private static List<string> namesnames;
  270. private bool disposedValue = false;
  271. private string filename;
  272. #endregion Fields
  273. #region Constructors
  274. public Splash(int splashNum, bool bNames = true, bool bLogo = false)
  275. {
  276. if (splashNum > 0x0f)
  277. {
  278. return;
  279. }
  280. var aw = ArchiveWorker.Load(Memory.Archives.A_MAIN);
  281. InitNames(aw);
  282. GetName(splashNum, bNames, bLogo);
  283. ReadSplash();
  284. }
  285. #endregion Constructors
  286. #region Destructors
  287. // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
  288. ~Splash()
  289. {
  290. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  291. Dispose(false);
  292. }
  293. #endregion Destructors
  294. #region Properties
  295. public int Height => tex?.Height ?? 0;
  296. public TextureHandler tex { get; private set; }
  297. public int Width => tex?.Width ?? 0;
  298. #endregion Properties
  299. #region Methods
  300. public static implicit operator Texture2D(Splash s) => (Texture2D)s.tex;
  301. // This code added to correctly implement the disposable pattern.
  302. public void Dispose()
  303. {
  304. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  305. Dispose(true);
  306. // TODO: uncomment the following line if the finalizer is overridden above.
  307. GC.SuppressFinalize(this);
  308. }
  309. public override string ToString() => filename;
  310. protected virtual void Dispose(bool disposing)
  311. {
  312. if (!disposedValue)
  313. {
  314. if (disposing)
  315. {
  316. // TODO: dispose managed state (managed objects).
  317. }
  318. // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
  319. // TODO: set large fields to null.
  320. tex.Dispose();
  321. disposedValue = true;
  322. }
  323. }
  324. private static void InitNames(ArchiveBase aw)
  325. {
  326. if (loopsnames == null && namesnames == null && logonames == null)
  327. {
  328. var lof = aw.GetListOfFiles();
  329. loopsnames = lof.Where(x => x.IndexOf(loops, StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();
  330. namesnames = lof.Where(x => x.IndexOf(names, StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();
  331. logonames = lof.Where(x => x.IndexOf("ff8.lzs", StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();
  332. }
  333. }
  334. private void GetName(int splashNum, bool bNames, bool bLogo) => filename = !bLogo
  335. ? bNames
  336. ? namesnames.ElementAtOrDefault(splashNum - 1)
  337. : loopsnames.ElementAtOrDefault(splashNum - 1)
  338. : logonames.FirstOrDefault();
  339. //Splash is 640x400 16BPP typical TIM with palette of ggg bbbbb a rrrrr gg
  340. private void ReadSplash()
  341. {
  342. if (string.IsNullOrWhiteSpace(filename)) return;
  343. var fn = Path.GetFileNameWithoutExtension(filename);
  344. //Debug.Assert(!fn.Equals("ff8", StringComparison.OrdinalIgnoreCase));
  345. var aw = ArchiveWorker.Load(Memory.Archives.A_MAIN);
  346. var buffer = aw.GetBinaryFile(filename);
  347. var tim = new TIMOverture(buffer);
  348. if ((fn.Equals("ff8", StringComparison.OrdinalIgnoreCase)) || (fn.IndexOf("loop", StringComparison.OrdinalIgnoreCase) >= 0))
  349. {
  350. tim.IgnoreAlpha = true;
  351. }
  352. tex = TextureHandler.Create(fn, tim, 0);//TIM2.Overture(buffer);
  353. //using (FileStream fs = File.Create(Path.Combine("D:\\main", Path.GetFileNameWithoutExtension(filename) + ".png")))
  354. // splashTex.SaveAsPng(fs, splashTex.Width, splashTex.Height);
  355. GC.Collect();
  356. GC.WaitForPendingFinalizers();
  357. }
  358. #endregion Methods
  359. // To detect redundant calls
  360. }
  361. }