Card_Game.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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. using (var fs = new FileStream(Path.Combine(Path.GetTempPath(), $"{filename}_{page}.png"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  121. pagetex.SaveAsPng(fs, cardback.Height, cardback.Height);
  122. th.Add(TextureHandler.Create($"{filename}_{page}.png", new Texture2DWrapper(pagetex)));
  123. page++;
  124. }
  125. CardFaces = th.ToArray();
  126. // if (Memory.EnableDumpingData)
  127. // using (FileStream fs = new FileStream(Path.Combine(Path.GetTempPath(), $"{filename}.combined.png"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  128. // combined.SaveAsPng(fs, cardback.Width, cardback.Height);
  129. //}
  130. }
  131. }
  132. private void GenernateCardFaceEntries()
  133. {
  134. if (_cardFacesEntries == null || _cardFacesEntries.Count == 0)
  135. {
  136. _cardFacesEntries = new List<Entry>();
  137. var CardValues = (Cards.ID[])Enum.GetValues(typeof(Cards.ID));
  138. Array.Sort(CardValues);
  139. const int size = 64;
  140. const int numberofcardsperpage = 8;
  141. const int cols = 2;
  142. const int rows = 4;
  143. for (var i = 0; i < CardValues.Length && CardValues[i] <= Cards.ID.Card_Back; i++)
  144. {
  145. new Entry
  146. {
  147. ID = CardValues[i],
  148. File = checked((byte)(i / numberofcardsperpage)),
  149. X = i % cols == 1 ? size : 0,
  150. Y = ((i / cols) % rows) * size,
  151. Height = size,
  152. Width = size,
  153. CustomPalette = checked((sbyte)i),
  154. };
  155. }
  156. }
  157. }
  158. private enum SymbolID
  159. {
  160. None,
  161. HexNumbers,
  162. Fire,
  163. Ice,
  164. Lightning,
  165. Earth,
  166. Poison,
  167. Wind,
  168. Water,
  169. Holy,
  170. Score,
  171. Buff,
  172. Debuff,
  173. Win,
  174. Lose,
  175. Draw,
  176. Same,
  177. Plus,
  178. Combo,
  179. }
  180. private void ReadSymbolsNumbers(int id, BinaryReader br)
  181. {
  182. const int pages = 3;
  183. var th = new List<TextureHandler>(pages);
  184. //3 pages, 256x256; inside () is palette ID +1.
  185. //page 1 = 5 rows. first 3 rows are 16x16 grid, last 2 rows are a 24x24 grid
  186. // row 1 has 11 hex numbers: 0-A (1)
  187. // row 2 4 of 4 frame animations: fire(4), ice(7), lightning(10), earth(13)
  188. // row 3 4 of 4 frame animations: poison(16), wind(19), water(22), holy(25)
  189. // row 4 has 9 numbers: 0-9 (28)
  190. // row 5 has 2 items: +1, -1 (31 or 34)
  191. //page 2 = 3 rows of 256x48: You Win!(2), You Lose...(5), Draw(8)
  192. //page 3 = 3 rows of 256x64: Same!(9), Plus!(6), Combo!(9)
  193. GenerateEntriesSymbolsNumbers();
  194. var temp = new TIM2(br, EXE_Offsets.TIM[year][id]);
  195. //temp.ForceSetClutColors(16);
  196. //temp.ForceSetClutCount(48);
  197. var size = 256;
  198. //Rectangle pagesrc = new Rectangle(new Point(size * (page), size), new Point(size));
  199. //Rectangle dst;
  200. //using (Texture2D combined = new Texture2D(Memory.graphics.GraphicsDevice, size * 3, temp.GetHeight))
  201. //{
  202. Texture2D texture = null;
  203. Texture2D pagetex = null;
  204. sbyte CustomPalette = -1;
  205. sbyte File = -1;
  206. var filename = "";
  207. //string combinedfilename = $"text_combined.png";
  208. foreach (var e in SymbolNumberEntries)
  209. {
  210. if (File != e.File)
  211. {
  212. savepagetex();
  213. File = checked((sbyte)e.File);
  214. pagetex = new Texture2D(Memory.Graphics.GraphicsDevice, size, size);
  215. filename = $"text_{File}.png";
  216. }
  217. if (CustomPalette != e.CustomPalette)
  218. {
  219. if (texture != null)
  220. texture.Dispose();
  221. CustomPalette = e.CustomPalette;
  222. texture = temp.GetTexture((ushort)CustomPalette);
  223. }
  224. var data = new Color[(int)(e.Width * e.Height)];
  225. var src = e.GetRectangle;
  226. var dst = src;
  227. src.Offset(e.File * 256, 0);
  228. texture.GetData(0, src, data, 0, data.Length);
  229. pagetex.SetData(0, dst, data, 0, data.Length);
  230. //dst = src;
  231. //combined.SetData(0, dst, data, 0, data.Length);
  232. }
  233. texture.Dispose();
  234. savepagetex();
  235. void savepagetex()
  236. {
  237. if (pagetex != null)
  238. {
  239. if (Memory.EnableDumpingData)
  240. using (var fs = new FileStream(Path.Combine(Path.GetTempPath(), filename), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  241. pagetex.SaveAsPng(fs, pagetex.Width, pagetex.Height);
  242. th.Add(TextureHandler.Create(filename, new Texture2DWrapper(pagetex)));
  243. }
  244. }
  245. //if (Memory.EnableDumpingData)
  246. // using (FileStream fs = new FileStream(Path.Combine(Path.GetTempPath(), combinedfilename), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
  247. // combined.SaveAsPng(fs, combined.Width, combined.Height);
  248. //}
  249. //if (Memory.EnableDumpingData)
  250. // Memory.MainThreadOnlyActions.Enqueue(() => { temp.SaveCLUT(Path.Combine(Path.GetTempPath(), $"{filename}.CLUT.png")); });
  251. //SymbolsNumbers = new TextureHandler[temp.GetClutCount];
  252. //for (ushort i = 0; i < temp.GetClutCount; i++)
  253. //{
  254. // SymbolsNumbers[i] = TextureHandler.Create(filename, temp, i);
  255. // //Memory.MainThreadOnlyActions.Enqueue(SymbolsNumbers[i].Save);
  256. //}
  257. if (Memory.EnableDumpingData)
  258. {
  259. filename = $"text_raw.png";
  260. for (ushort i = 0; i < temp.GetClutCount || i == 0 && temp.GetClutCount == 0; i++)
  261. {
  262. th.Add(TextureHandler.Create(filename, temp, i));
  263. }
  264. }
  265. _symbolsNumbers = th.ToArray();
  266. }
  267. private void GenerateEntriesSymbolsNumbers()
  268. {
  269. if (_symbolNumberEntries == null || _symbolNumberEntries.Count == 0)
  270. {
  271. _symbolNumberEntries = new List<Entry>();
  272. for (var i = 0; i < 11; i++)
  273. {
  274. _symbolNumberEntries.Add(new Entry
  275. {
  276. ID = SymbolID.HexNumbers,
  277. File = 0,
  278. CustomPalette = 0,
  279. Location = new Vector2(i * 16, 0),
  280. Size = new Vector2(16, 16),
  281. NumberValue = i
  282. });
  283. }
  284. for (var k = 0; k < 2; k++)
  285. for (var j = 0; j < 4; j++)
  286. for (var i = 0; i < 4; i++)
  287. {
  288. _symbolNumberEntries.Add(new Entry
  289. {
  290. ID = (SymbolID)((int)(SymbolID.Fire) + j + (k * 4)),
  291. File = 0,
  292. CustomPalette = checked((sbyte)(3 * (j + 1 + (k * 4)))),
  293. Location = new Vector2((i + (4 * j)) * 16, 16 * (k + 1)),
  294. Size = new Vector2(16, 16),
  295. Frame = i,
  296. });
  297. }
  298. for (var i = 0; i < 9; i++)
  299. {
  300. _symbolNumberEntries.Add(new Entry
  301. {
  302. ID = SymbolID.Score,
  303. File = 0,
  304. CustomPalette = 27,
  305. Location = new Vector2(i * 24, 16 * 3),
  306. Size = new Vector2(24, 24),
  307. NumberValue = i
  308. });
  309. }
  310. for (var i = 0; i < 2; i++)
  311. {
  312. _symbolNumberEntries.Add(new Entry
  313. {
  314. ID = (SymbolID)((int)(SymbolID.Buff) + i),
  315. File = 0,
  316. CustomPalette = 30,
  317. Location = new Vector2(i * 24, 16 * 3 + 24),
  318. Size = new Vector2(24, 24),
  319. NumberValue = 1 + (-2 * i)
  320. });
  321. }
  322. for (var i = 0; i < 3; i++)
  323. {
  324. _symbolNumberEntries.Add(new Entry
  325. {
  326. ID = (SymbolID)((int)(SymbolID.Win) + i),
  327. File = 1,
  328. CustomPalette = checked((sbyte)(1 + 3 * i)),
  329. Location = new Vector2(0, 48 * i),
  330. Size = new Vector2(256, 48),
  331. });
  332. }
  333. for (var i = 0; i < 3; i++)
  334. {
  335. _symbolNumberEntries.Add(new Entry
  336. {
  337. ID = (SymbolID)((int)(SymbolID.Same) + i),
  338. File = 2,
  339. CustomPalette = checked((sbyte)(2 + 3 * i)),
  340. Location = new Vector2(0, 64 * i),
  341. Size = new Vector2(256, 64),
  342. });
  343. }
  344. }
  345. }
  346. private void ReadTIM(int id, BinaryReader br, out TextureHandler[] tex, ushort ForceSetClutColors = 0, ushort ForceSetClutCount = 0)
  347. {
  348. var temp = new TIM2(br, EXE_Offsets.TIM[year][id]);
  349. if (ForceSetClutColors > 0)
  350. temp.ForceSetClutColors(ForceSetClutColors);
  351. if (ForceSetClutCount > 0)
  352. temp.ForceSetClutCount(ForceSetClutCount);
  353. var filename = $"ff8exe{id.ToString("D2")}";
  354. if (Memory.EnableDumpingData)
  355. Memory.MainThreadOnlyActions.Enqueue(() => { temp.SaveCLUT(Path.Combine(Path.GetTempPath(), $"{filename}.CLUT.png")); });
  356. tex = new TextureHandler[temp.GetClutCount == 0 ? 1 : temp.GetClutCount];
  357. for (ushort i = 0; i < temp.GetClutCount || i == 0 && temp.GetClutCount == 0; i++)
  358. {
  359. tex[i] = TextureHandler.Create(filename, temp, i);
  360. }
  361. }
  362. }
  363. }