Card_Game.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. namespace OpenVIII.Card
  7. {
  8. public class Game
  9. {
  10. private const int year = 2013;
  11. private TextureHandler[] _symbolsNumbers;
  12. private TextureHandler[] _cardFaces;
  13. private TextureHandler[] _cardGameBG;
  14. private TextureHandler[] _cardOtherBG;
  15. private List<Entry> _symbolNumberEntries;
  16. private List<Entry> _cardFacesEntries;
  17. public TextureHandler[] SymbolsNumbers { get => _symbolsNumbers; private set => _symbolsNumbers = value; }
  18. //private TextureHandler[] Other;
  19. public TextureHandler[] CardFaces { get => _cardFaces; private set => _cardFaces = value; }
  20. public TextureHandler[] CardGameBG { get => _cardGameBG; private set => _cardGameBG = value; }
  21. public TextureHandler[] CardOtherBG { get => _cardOtherBG; private set => _cardOtherBG = value; }
  22. public IReadOnlyList<Entry> SymbolNumberEntries => _symbolNumberEntries;
  23. public IReadOnlyList<Entry> CardFacesEntries => _cardFacesEntries;
  24. public Game()
  25. {
  26. Memory.Log.WriteLine($"{nameof(Card)} :: {nameof(Game)} :: new ");
  27. Memory.MainThreadOnlyActions.Enqueue(() =>
  28. {
  29. //Memory.EnableDumpingData = true;
  30. var input = FileStreamOpen();
  31. if (input != null)
  32. {
  33. using (var br = new BinaryReader(input))
  34. ReadSymbolsNumbers(0, br);
  35. }
  36. //Memory.EnableDumpingData = false;
  37. });
  38. Memory.MainThreadOnlyActions.Enqueue(() =>
  39. {
  40. var input = FileStreamOpen();
  41. if (input != null)
  42. using (var br = new BinaryReader(input))
  43. ReadCardFaces(2, br);
  44. });
  45. Memory.MainThreadOnlyActions.Enqueue(() =>
  46. {
  47. var input = FileStreamOpen();
  48. if (input != null)
  49. using (var br = new BinaryReader(input))
  50. {
  51. //ReadTIM(1, br,out Other);
  52. ReadTIM(50, br, out _cardGameBG);
  53. ReadTIM(51, br, out _cardOtherBG);
  54. }
  55. });
  56. }
  57. private FileStream FileStreamOpen()
  58. {
  59. if (File.Exists(EXE_Offsets.FileName[year]))
  60. return new FileStream(EXE_Offsets.FileName[year], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  61. return null;
  62. }
  63. private void ReadCardFaces(int id, BinaryReader br)
  64. {
  65. var cardtim = new TIM2(br, EXE_Offsets.TIM[year][id]);
  66. using (var cardback = cardtim.GetTexture(55))
  67. {
  68. GenernateCardFaceEntries();
  69. cardtim.ForceSetClutColors(128);
  70. cardtim.ForceSetClutCount(112);
  71. var rows = 4;
  72. var size = cardback.Height / rows;
  73. var cols = cardback.Width / size;
  74. //using (Texture2D combined = new Texture2D(Memory.graphics.GraphicsDevice, cardback.Width, cardback.Height))
  75. //{
  76. var data = new Color[size * size];
  77. var src = new Rectangle(new Point(size * (cols - 2), size * (rows - 1)), new Point(size));
  78. Rectangle dst;
  79. //cardback.GetData(0, src, data, 0, data.Length);
  80. //combined.SetData(0, src, data, 0, data.Length);
  81. var row = 0;
  82. var acol = 0;
  83. var rc = new List<Point>(110);
  84. var page = 0;
  85. var pages = cols / 2;
  86. var th = new List<TextureHandler>(pages);
  87. ushort i = 0;
  88. var filename = $"cards";
  89. while (i < 110 && page < pages)
  90. {
  91. var pagetex = new Texture2D(Memory.Graphics.GraphicsDevice, cardback.Height, cardback.Height);
  92. for (var p = 0; p < 8 && i < 110; p++)
  93. {
  94. var cardface = cardtim.GetTexture(i);
  95. var coloff = i % 2;
  96. var even = coloff == 0;
  97. if (row >= rows)
  98. {
  99. row = 0;
  100. acol += 2;
  101. }
  102. var col = acol + coloff;
  103. src = new Rectangle(new Point(size * (col), size * (row)), new Point(size));
  104. dst = new Rectangle(new Point(size * (coloff), size * (row)), new Point(size));
  105. cardface.GetData(0, src, data, 0, data.Length);
  106. //combined.SetData(0, src, data, 0, data.Length);
  107. pagetex.SetData(0, dst, data, 0, data.Length);
  108. rc.Add(new Point(col, row));
  109. if (!even) row++;
  110. i++;
  111. }
  112. if (page == pages - 1)
  113. {
  114. src = new Rectangle(new Point(size * (cols - 2), size * (rows - 1)), new Point(size));
  115. dst = new Rectangle(new Point(0, size * (rows - 1)), new Point(size));
  116. cardback.GetData(0, src, data, 0, data.Length);
  117. pagetex.SetData(0, dst, data, 0, data.Length);
  118. }
  119. if (Memory.EnableDumpingData)
  120. {
  121. Extended.Save_As_PNG(pagetex, Path.Combine(Path.GetTempPath(), $"{filename}_{page}.png"), cardback.Width, cardback.Height);
  122. }
  123. th.Add(TextureHandler.Create($"{filename}_{page}.png", new Texture2DWrapper(pagetex)));
  124. page++;
  125. }
  126. CardFaces = th.ToArray();
  127. // if (Memory.EnableDumpingData)
  128. // using (FileStream fs = new FileStream(Path.Combine(Path.GetTempPath(), $"{filename}.combined.png"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  129. // combined.SaveAsPng(fs, cardback.Width, cardback.Height);
  130. //}
  131. }
  132. }
  133. private void GenernateCardFaceEntries()
  134. {
  135. if (_cardFacesEntries == null || _cardFacesEntries.Count == 0)
  136. {
  137. _cardFacesEntries = new List<Entry>();
  138. var CardValues = (Cards.ID[])Enum.GetValues(typeof(Cards.ID));
  139. Array.Sort(CardValues);
  140. const int size = 64;
  141. const int numberofcardsperpage = 8;
  142. const int cols = 2;
  143. const int rows = 4;
  144. for (var i = 0; i < CardValues.Length && CardValues[i] <= Cards.ID.Card_Back; i++)
  145. {
  146. new Entry
  147. {
  148. ID = CardValues[i],
  149. File = checked((byte)(i / numberofcardsperpage)),
  150. X = i % cols == 1 ? size : 0,
  151. Y = ((i / cols) % rows) * size,
  152. Height = size,
  153. Width = size,
  154. CustomPalette = checked((sbyte)i),
  155. };
  156. }
  157. }
  158. }
  159. private enum SymbolID
  160. {
  161. None,
  162. HexNumbers,
  163. Fire,
  164. Ice,
  165. Lightning,
  166. Earth,
  167. Poison,
  168. Wind,
  169. Water,
  170. Holy,
  171. Score,
  172. Buff,
  173. Debuff,
  174. Win,
  175. Lose,
  176. Draw,
  177. Same,
  178. Plus,
  179. Combo,
  180. }
  181. private void ReadSymbolsNumbers(int id, BinaryReader br)
  182. {
  183. const int pages = 3;
  184. var th = new List<TextureHandler>(pages);
  185. //3 pages, 256x256; inside () is palette ID +1.
  186. //page 1 = 5 rows. first 3 rows are 16x16 grid, last 2 rows are a 24x24 grid
  187. // row 1 has 11 hex numbers: 0-A (1)
  188. // row 2 4 of 4 frame animations: fire(4), ice(7), lightning(10), earth(13)
  189. // row 3 4 of 4 frame animations: poison(16), wind(19), water(22), holy(25)
  190. // row 4 has 9 numbers: 0-9 (28)
  191. // row 5 has 2 items: +1, -1 (31 or 34)
  192. //page 2 = 3 rows of 256x48: You Win!(2), You Lose...(5), Draw(8)
  193. //page 3 = 3 rows of 256x64: Same!(9), Plus!(6), Combo!(9)
  194. GenerateEntriesSymbolsNumbers();
  195. var temp = new TIM2(br, EXE_Offsets.TIM[year][id]);
  196. //temp.ForceSetClutColors(16);
  197. //temp.ForceSetClutCount(48);
  198. var size = 256;
  199. //Rectangle pagesrc = new Rectangle(new Point(size * (page), size), new Point(size));
  200. //Rectangle dst;
  201. //using (Texture2D combined = new Texture2D(Memory.graphics.GraphicsDevice, size * 3, temp.GetHeight))
  202. //{
  203. Texture2D texture = null;
  204. Texture2D pagetex = null;
  205. sbyte CustomPalette = -1;
  206. sbyte File = -1;
  207. var filename = "";
  208. //string combinedfilename = $"text_combined.png";
  209. foreach (var e in SymbolNumberEntries)
  210. {
  211. if (File != e.File)
  212. {
  213. savepagetex();
  214. File = checked((sbyte)e.File);
  215. pagetex = new Texture2D(Memory.Graphics.GraphicsDevice, size, size);
  216. filename = $"text_{File}.png";
  217. }
  218. if (CustomPalette != e.CustomPalette)
  219. {
  220. if (texture != null)
  221. texture.Dispose();
  222. CustomPalette = e.CustomPalette;
  223. texture = temp.GetTexture((ushort)CustomPalette);
  224. }
  225. var data = new Color[(int)(e.Width * e.Height)];
  226. var src = e.GetRectangle;
  227. var dst = src;
  228. src.Offset(e.File * 256, 0);
  229. texture.GetData(0, src, data, 0, data.Length);
  230. pagetex.SetData(0, dst, data, 0, data.Length);
  231. //dst = src;
  232. //combined.SetData(0, dst, data, 0, data.Length);
  233. }
  234. texture.Dispose();
  235. savepagetex();
  236. void savepagetex()
  237. {
  238. if (pagetex != null)
  239. {
  240. if (Memory.EnableDumpingData)
  241. {
  242. Extended.Save_As_PNG(pagetex, Path.Combine(Path.GetTempPath(), filename), pagetex.Width, pagetex.Height);
  243. }
  244. th.Add(TextureHandler.Create(filename, new Texture2DWrapper(pagetex)));
  245. }
  246. }
  247. //if (Memory.EnableDumpingData)
  248. // using (FileStream fs = new FileStream(Path.Combine(Path.GetTempPath(), combinedfilename), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  249. // combined.SaveAsPng(fs, combined.Width, combined.Height);
  250. //}
  251. //if (Memory.EnableDumpingData)
  252. // Memory.MainThreadOnlyActions.Enqueue(() => { temp.SaveCLUT(Path.Combine(Path.GetTempPath(), $"{filename}.CLUT.png")); });
  253. //SymbolsNumbers = new TextureHandler[temp.GetClutCount];
  254. //for (ushort i = 0; i < temp.GetClutCount; i++)
  255. //{
  256. // SymbolsNumbers[i] = TextureHandler.Create(filename, temp, i);
  257. // //Memory.MainThreadOnlyActions.Enqueue(SymbolsNumbers[i].Save);
  258. //}
  259. if (Memory.EnableDumpingData)
  260. {
  261. filename = $"text_raw.png";
  262. for (ushort i = 0; i < temp.GetClutCount || i == 0 && temp.GetClutCount == 0; i++)
  263. {
  264. th.Add(TextureHandler.Create(filename, temp, i));
  265. }
  266. }
  267. _symbolsNumbers = th.ToArray();
  268. }
  269. private void GenerateEntriesSymbolsNumbers()
  270. {
  271. if (_symbolNumberEntries == null || _symbolNumberEntries.Count == 0)
  272. {
  273. _symbolNumberEntries = new List<Entry>();
  274. for (var i = 0; i < 11; i++)
  275. {
  276. _symbolNumberEntries.Add(new Entry
  277. {
  278. ID = SymbolID.HexNumbers,
  279. File = 0,
  280. CustomPalette = 0,
  281. Location = new Vector2(i * 16, 0),
  282. Size = new Vector2(16, 16),
  283. NumberValue = i
  284. });
  285. }
  286. for (var k = 0; k < 2; k++)
  287. for (var j = 0; j < 4; j++)
  288. for (var i = 0; i < 4; i++)
  289. {
  290. _symbolNumberEntries.Add(new Entry
  291. {
  292. ID = (SymbolID)((int)(SymbolID.Fire) + j + (k * 4)),
  293. File = 0,
  294. CustomPalette = checked((sbyte)(3 * (j + 1 + (k * 4)))),
  295. Location = new Vector2((i + (4 * j)) * 16, 16 * (k + 1)),
  296. Size = new Vector2(16, 16),
  297. Frame = i,
  298. });
  299. }
  300. for (var i = 0; i < 9; i++)
  301. {
  302. _symbolNumberEntries.Add(new Entry
  303. {
  304. ID = SymbolID.Score,
  305. File = 0,
  306. CustomPalette = 27,
  307. Location = new Vector2(i * 24, 16 * 3),
  308. Size = new Vector2(24, 24),
  309. NumberValue = i
  310. });
  311. }
  312. for (var i = 0; i < 2; i++)
  313. {
  314. _symbolNumberEntries.Add(new Entry
  315. {
  316. ID = (SymbolID)((int)(SymbolID.Buff) + i),
  317. File = 0,
  318. CustomPalette = 30,
  319. Location = new Vector2(i * 24, 16 * 3 + 24),
  320. Size = new Vector2(24, 24),
  321. NumberValue = 1 + (-2 * i)
  322. });
  323. }
  324. for (var i = 0; i < 3; i++)
  325. {
  326. _symbolNumberEntries.Add(new Entry
  327. {
  328. ID = (SymbolID)((int)(SymbolID.Win) + i),
  329. File = 1,
  330. CustomPalette = checked((sbyte)(1 + 3 * i)),
  331. Location = new Vector2(0, 48 * i),
  332. Size = new Vector2(256, 48),
  333. });
  334. }
  335. for (var i = 0; i < 3; i++)
  336. {
  337. _symbolNumberEntries.Add(new Entry
  338. {
  339. ID = (SymbolID)((int)(SymbolID.Same) + i),
  340. File = 2,
  341. CustomPalette = checked((sbyte)(2 + 3 * i)),
  342. Location = new Vector2(0, 64 * i),
  343. Size = new Vector2(256, 64),
  344. });
  345. }
  346. }
  347. }
  348. private void ReadTIM(int id, BinaryReader br, out TextureHandler[] tex, ushort ForceSetClutColors = 0, ushort ForceSetClutCount = 0)
  349. {
  350. var temp = new TIM2(br, EXE_Offsets.TIM[year][id]);
  351. if (ForceSetClutColors > 0)
  352. temp.ForceSetClutColors(ForceSetClutColors);
  353. if (ForceSetClutCount > 0)
  354. temp.ForceSetClutCount(ForceSetClutCount);
  355. var filename = $"ff8exe{id.ToString("D2")}";
  356. if (Memory.EnableDumpingData)
  357. Memory.MainThreadOnlyActions.Enqueue(() => { temp.SaveCLUT(Path.Combine(Path.GetTempPath(), $"{filename}.CLUT.png")); });
  358. tex = new TextureHandler[temp.GetClutCount == 0 ? 1 : temp.GetClutCount];
  359. for (ushort i = 0; i < temp.GetClutCount || i == 0 && temp.GetClutCount == 0; i++)
  360. {
  361. tex[i] = TextureHandler.Create(filename, temp, i);
  362. }
  363. }
  364. }
  365. }