MLibrary.cs 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. using SlimDX;
  2. using SlimDX.Direct3D9;
  3. using System.IO.Compression;
  4. using Frame = Client.MirObjects.Frame;
  5. using Client.MirObjects;
  6. using System.Text.RegularExpressions;
  7. namespace Client.MirGraphics
  8. {
  9. public static class Libraries
  10. {
  11. public static bool Loaded;
  12. public static int Count, Progress;
  13. public static readonly MLibrary
  14. ChrSel = new MLibrary(Settings.DataPath + "ChrSel"),
  15. Prguse = new MLibrary(Settings.DataPath + "Prguse"),
  16. Prguse2 = new MLibrary(Settings.DataPath + "Prguse2"),
  17. Prguse3 = new MLibrary(Settings.DataPath + "Prguse3"),
  18. UI_32bit = new MLibrary(Settings.DataPath + "UI_32bit"),
  19. BuffIcon = new MLibrary(Settings.DataPath + "BuffIcon"),
  20. Help = new MLibrary(Settings.DataPath + "Help"),
  21. MiniMap = new MLibrary(Settings.DataPath + "MMap"),
  22. MapLinkIcon = new MLibrary(Settings.DataPath + "MapLinkIcon"),
  23. Title = new MLibrary(Settings.DataPath + "Title"),
  24. MagIcon = new MLibrary(Settings.DataPath + "MagIcon"),
  25. MagIcon2 = new MLibrary(Settings.DataPath + "MagIcon2"),
  26. Magic = new MLibrary(Settings.DataPath + "Magic"),
  27. Magic2 = new MLibrary(Settings.DataPath + "Magic2"),
  28. Magic3 = new MLibrary(Settings.DataPath + "Magic3"),
  29. Effect = new MLibrary(Settings.DataPath + "Effect"),
  30. MagicC = new MLibrary(Settings.DataPath + "MagicC"),
  31. GuildSkill = new MLibrary(Settings.DataPath + "GuildSkill"),
  32. Weather = new MLibrary(Settings.DataPath + "Weather");
  33. public static readonly MLibrary
  34. Background = new MLibrary(Settings.DataPath + "Background");
  35. public static readonly MLibrary
  36. Dragon = new MLibrary(Settings.DataPath + "Dragon");
  37. //Map
  38. public static readonly MLibrary[] MapLibs = new MLibrary[400];
  39. //Items
  40. public static readonly MLibrary
  41. Items = new MLibrary(Settings.DataPath + "Items"),
  42. StateItems = new MLibrary(Settings.DataPath + "StateItem"),
  43. FloorItems = new MLibrary(Settings.DataPath + "DNItems"),
  44. Items_Tooltip_32bit = new MLibrary(Settings.DataPath + "Items_Tooltip_32bit");
  45. //Deco
  46. public static readonly MLibrary
  47. Deco = new MLibrary(Settings.DataPath + "Deco");
  48. public static MLibrary[] CArmours,
  49. CWeapons,
  50. CWeaponEffect,
  51. CHair,
  52. CHumEffect,
  53. AArmours,
  54. AWeaponsL,
  55. AWeaponsR,
  56. AHair,
  57. AHumEffect,
  58. ARArmours,
  59. ARWeapons,
  60. ARWeaponsS,
  61. ARHair,
  62. ARHumEffect,
  63. Monsters,
  64. Gates,
  65. Flags,
  66. Siege,
  67. Mounts,
  68. NPCs,
  69. Fishing,
  70. Pets,
  71. Transform,
  72. TransformMounts,
  73. TransformEffect,
  74. TransformWeaponEffect;
  75. static Libraries()
  76. {
  77. //Wiz/War/Tao
  78. InitLibrary(ref CArmours, Settings.CArmourPath, "00");
  79. InitLibrary(ref CHair, Settings.CHairPath, "00");
  80. InitLibrary(ref CWeapons, Settings.CWeaponPath, "00");
  81. InitLibrary(ref CWeaponEffect, Settings.CWeaponEffectPath, "00");
  82. InitLibrary(ref CHumEffect, Settings.CHumEffectPath, "00");
  83. //Assassin
  84. InitLibrary(ref AArmours, Settings.AArmourPath, "00");
  85. InitLibrary(ref AHair, Settings.AHairPath, "00");
  86. InitLibrary(ref AWeaponsL, Settings.AWeaponPath, "00", " L");
  87. InitLibrary(ref AWeaponsR, Settings.AWeaponPath, "00", " R");
  88. InitLibrary(ref AHumEffect, Settings.AHumEffectPath, "00");
  89. //Archer
  90. InitLibrary(ref ARArmours, Settings.ARArmourPath, "00");
  91. InitLibrary(ref ARHair, Settings.ARHairPath, "00");
  92. InitLibrary(ref ARWeapons, Settings.ARWeaponPath, "00");
  93. InitLibrary(ref ARWeaponsS, Settings.ARWeaponPath, "00", " S");
  94. InitLibrary(ref ARHumEffect, Settings.ARHumEffectPath, "00");
  95. //Other
  96. InitLibrary(ref Monsters, Settings.MonsterPath, "000");
  97. InitLibrary(ref Gates, Settings.GatePath, "00");
  98. InitLibrary(ref Flags, Settings.FlagPath, "00");
  99. InitLibrary(ref Siege, Settings.SiegePath, "00");
  100. InitLibrary(ref NPCs, Settings.NPCPath, "00");
  101. InitLibrary(ref Mounts, Settings.MountPath, "00");
  102. InitLibrary(ref Fishing, Settings.FishingPath, "00");
  103. InitLibrary(ref Pets, Settings.PetsPath, "00");
  104. InitLibrary(ref Transform, Settings.TransformPath, "00");
  105. InitLibrary(ref TransformMounts, Settings.TransformMountsPath, "00");
  106. InitLibrary(ref TransformEffect, Settings.TransformEffectPath, "00");
  107. InitLibrary(ref TransformWeaponEffect, Settings.TransformWeaponEffectPath, "00");
  108. #region Maplibs
  109. //wemade mir2 (allowed from 0-99)
  110. MapLibs[0] = new MLibrary(Settings.DataPath + "Map\\WemadeMir2\\Tiles");
  111. MapLibs[1] = new MLibrary(Settings.DataPath + "Map\\WemadeMir2\\Smtiles");
  112. MapLibs[2] = new MLibrary(Settings.DataPath + "Map\\WemadeMir2\\Objects");
  113. for (int i = 2; i < 28; i++)
  114. {
  115. MapLibs[i + 1] = new MLibrary(Settings.DataPath + "Map\\WemadeMir2\\Objects" + i.ToString());
  116. }
  117. MapLibs[90] = new MLibrary(Settings.DataPath + "Map\\WemadeMir2\\Objects_32bit");
  118. //shanda mir2 (allowed from 100-199)
  119. MapLibs[100] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\Tiles");
  120. for (int i = 1; i < 10; i++)
  121. {
  122. MapLibs[100 + i] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\Tiles" + (i + 1));
  123. }
  124. MapLibs[110] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\SmTiles");
  125. for (int i = 1; i < 10; i++)
  126. {
  127. MapLibs[110 + i] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\SmTiles" + (i + 1));
  128. }
  129. MapLibs[120] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\Objects");
  130. for (int i = 1; i < 31; i++)
  131. {
  132. MapLibs[120 + i] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\Objects" + (i + 1));
  133. }
  134. MapLibs[190] = new MLibrary(Settings.DataPath + "Map\\ShandaMir2\\AniTiles1");
  135. //wemade mir3 (allowed from 200-299)
  136. string[] Mapstate = { "", "wood\\", "sand\\", "snow\\", "forest\\"};
  137. for (int i = 0; i < Mapstate.Length; i++)
  138. {
  139. MapLibs[200 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Tilesc");
  140. MapLibs[201 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Tiles30c");
  141. MapLibs[202 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Tiles5c");
  142. MapLibs[203 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Smtilesc");
  143. MapLibs[204 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Housesc");
  144. MapLibs[205 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Cliffsc");
  145. MapLibs[206 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Dungeonsc");
  146. MapLibs[207 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Innersc");
  147. MapLibs[208 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Furnituresc");
  148. MapLibs[209 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Wallsc");
  149. MapLibs[210 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "smObjectsc");
  150. MapLibs[211 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Animationsc");
  151. MapLibs[212 +(i*15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Object1c");
  152. MapLibs[213 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\WemadeMir3\\" + Mapstate[i] + "Object2c");
  153. }
  154. Mapstate = new string[] { "", "wood", "sand", "snow", "forest"};
  155. //shanda mir3 (allowed from 300-399)
  156. for (int i = 0; i < Mapstate.Length; i++)
  157. {
  158. MapLibs[300 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Tilesc" + Mapstate[i]);
  159. MapLibs[301 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Tiles30c" + Mapstate[i]);
  160. MapLibs[302 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Tiles5c" + Mapstate[i]);
  161. MapLibs[303 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Smtilesc" + Mapstate[i]);
  162. MapLibs[304 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Housesc" + Mapstate[i]);
  163. MapLibs[305 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Cliffsc" + Mapstate[i]);
  164. MapLibs[306 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Dungeonsc" + Mapstate[i]);
  165. MapLibs[307 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Innersc" + Mapstate[i]);
  166. MapLibs[308 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Furnituresc" + Mapstate[i]);
  167. MapLibs[309 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Wallsc" + Mapstate[i]);
  168. MapLibs[310 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "smObjectsc" + Mapstate[i]);
  169. MapLibs[311 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Animationsc" + Mapstate[i]);
  170. MapLibs[312 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Object1c" + Mapstate[i]);
  171. MapLibs[313 + (i * 15)] = new MLibrary(Settings.DataPath + "Map\\ShandaMir3\\" + "Object2c" + Mapstate[i]);
  172. }
  173. #endregion
  174. LoadLibraries();
  175. Thread thread = new Thread(LoadGameLibraries) { IsBackground = true };
  176. thread.Start();
  177. }
  178. static void InitLibrary(ref MLibrary[] library, string path, string toStringValue, string suffix = "")
  179. {
  180. if (!Directory.Exists(path))
  181. {
  182. Directory.CreateDirectory(path);
  183. }
  184. var allFiles = Directory.GetFiles(path, "*" + suffix + MLibrary.Extention, SearchOption.TopDirectoryOnly).OrderBy(x => int.Parse(Regex.Match(x, @"\d+").Value));
  185. var lastFile = allFiles.Count() > 0 ? Path.GetFileName(allFiles.Last()) : "0";
  186. var count = int.Parse(Regex.Match(lastFile, @"\d+").Value) + 1;
  187. library = new MLibrary[count];
  188. for (int i = 0; i < count; i++)
  189. {
  190. library[i] = new MLibrary(path + i.ToString(toStringValue) + suffix);
  191. }
  192. }
  193. static void LoadLibraries()
  194. {
  195. ChrSel.Initialize();
  196. Progress++;
  197. Prguse.Initialize();
  198. Progress++;
  199. Prguse2.Initialize();
  200. Progress++;
  201. Prguse3.Initialize();
  202. Progress++;
  203. UI_32bit.Initialize();
  204. Progress++;
  205. Title.Initialize();
  206. Progress++;
  207. }
  208. private static void LoadGameLibraries()
  209. {
  210. Count = MapLibs.Length + Monsters.Length + Gates.Length + Flags.Length + Siege.Length + NPCs.Length + CArmours.Length +
  211. CHair.Length + CWeapons.Length + CWeaponEffect.Length + AArmours.Length + AHair.Length + AWeaponsL.Length + AWeaponsR.Length +
  212. ARArmours.Length + ARHair.Length + ARWeapons.Length + ARWeaponsS.Length +
  213. CHumEffect.Length + AHumEffect.Length + ARHumEffect.Length + Mounts.Length + Fishing.Length + Pets.Length +
  214. Transform.Length + TransformMounts.Length + TransformEffect.Length + TransformWeaponEffect.Length + 19;
  215. Dragon.Initialize();
  216. Progress++;
  217. BuffIcon.Initialize();
  218. Progress++;
  219. Help.Initialize();
  220. Progress++;
  221. MiniMap.Initialize();
  222. Progress++;
  223. MapLinkIcon.Initialize();
  224. Progress++;
  225. MagIcon.Initialize();
  226. Progress++;
  227. MagIcon2.Initialize();
  228. Progress++;
  229. Magic.Initialize();
  230. Progress++;
  231. Magic2.Initialize();
  232. Progress++;
  233. Magic3.Initialize();
  234. Progress++;
  235. MagicC.Initialize();
  236. Progress++;
  237. Effect.Initialize();
  238. Progress++;
  239. Weather.Initialize();
  240. Progress++;
  241. GuildSkill.Initialize();
  242. Progress++;
  243. Background.Initialize();
  244. Progress++;
  245. Deco.Initialize();
  246. Progress++;
  247. Items.Initialize();
  248. Progress++;
  249. StateItems.Initialize();
  250. Progress++;
  251. FloorItems.Initialize();
  252. Progress++;
  253. Items_Tooltip_32bit.Initialize();
  254. Progress++;
  255. for (int i = 0; i < MapLibs.Length; i++)
  256. {
  257. if (MapLibs[i] == null)
  258. MapLibs[i] = new MLibrary("");
  259. else
  260. MapLibs[i].Initialize();
  261. Progress++;
  262. }
  263. for (int i = 0; i < Monsters.Length; i++)
  264. {
  265. Monsters[i].Initialize();
  266. Progress++;
  267. }
  268. for (int i = 0; i < Gates.Length; i++)
  269. {
  270. Gates[i].Initialize();
  271. Progress++;
  272. }
  273. for (int i = 0; i < Flags.Length; i++)
  274. {
  275. Flags[i].Initialize();
  276. Progress++;
  277. }
  278. for (int i = 0; i < Siege.Length; i++)
  279. {
  280. Siege[i].Initialize();
  281. Progress++;
  282. }
  283. for (int i = 0; i < NPCs.Length; i++)
  284. {
  285. NPCs[i].Initialize();
  286. Progress++;
  287. }
  288. for (int i = 0; i < CArmours.Length; i++)
  289. {
  290. CArmours[i].Initialize();
  291. Progress++;
  292. }
  293. for (int i = 0; i < CHair.Length; i++)
  294. {
  295. CHair[i].Initialize();
  296. Progress++;
  297. }
  298. for (int i = 0; i < CWeapons.Length; i++)
  299. {
  300. CWeapons[i].Initialize();
  301. Progress++;
  302. }
  303. for (int i = 0; i < CWeaponEffect.Length; i++)
  304. {
  305. CWeaponEffect[i].Initialize();
  306. Progress++;
  307. }
  308. for (int i = 0; i < AArmours.Length; i++)
  309. {
  310. AArmours[i].Initialize();
  311. Progress++;
  312. }
  313. for (int i = 0; i < AHair.Length; i++)
  314. {
  315. AHair[i].Initialize();
  316. Progress++;
  317. }
  318. for (int i = 0; i < AWeaponsL.Length; i++)
  319. {
  320. AWeaponsL[i].Initialize();
  321. Progress++;
  322. }
  323. for (int i = 0; i < AWeaponsR.Length; i++)
  324. {
  325. AWeaponsR[i].Initialize();
  326. Progress++;
  327. }
  328. for (int i = 0; i < ARArmours.Length; i++)
  329. {
  330. ARArmours[i].Initialize();
  331. Progress++;
  332. }
  333. for (int i = 0; i < ARHair.Length; i++)
  334. {
  335. ARHair[i].Initialize();
  336. Progress++;
  337. }
  338. for (int i = 0; i < ARWeapons.Length; i++)
  339. {
  340. ARWeapons[i].Initialize();
  341. Progress++;
  342. }
  343. for (int i = 0; i < ARWeaponsS.Length; i++)
  344. {
  345. ARWeaponsS[i].Initialize();
  346. Progress++;
  347. }
  348. for (int i = 0; i < CHumEffect.Length; i++)
  349. {
  350. CHumEffect[i].Initialize();
  351. Progress++;
  352. }
  353. for (int i = 0; i < AHumEffect.Length; i++)
  354. {
  355. AHumEffect[i].Initialize();
  356. Progress++;
  357. }
  358. for (int i = 0; i < ARHumEffect.Length; i++)
  359. {
  360. ARHumEffect[i].Initialize();
  361. Progress++;
  362. }
  363. for (int i = 0; i < Mounts.Length; i++)
  364. {
  365. Mounts[i].Initialize();
  366. Progress++;
  367. }
  368. for (int i = 0; i < Fishing.Length; i++)
  369. {
  370. Fishing[i].Initialize();
  371. Progress++;
  372. }
  373. for (int i = 0; i < Pets.Length; i++)
  374. {
  375. Pets[i].Initialize();
  376. Progress++;
  377. }
  378. for (int i = 0; i < Transform.Length; i++)
  379. {
  380. Transform[i].Initialize();
  381. Progress++;
  382. }
  383. for (int i = 0; i < TransformEffect.Length; i++)
  384. {
  385. TransformEffect[i].Initialize();
  386. Progress++;
  387. }
  388. for (int i = 0; i < TransformWeaponEffect.Length; i++)
  389. {
  390. TransformWeaponEffect[i].Initialize();
  391. Progress++;
  392. }
  393. for (int i = 0; i < TransformMounts.Length; i++)
  394. {
  395. TransformMounts[i].Initialize();
  396. Progress++;
  397. }
  398. Loaded = true;
  399. }
  400. }
  401. public sealed class MLibrary
  402. {
  403. public const string Extention = ".Lib";
  404. public const int LibVersion = 3;
  405. private readonly string _fileName;
  406. private MImage[] _images;
  407. private FrameSet _frames;
  408. private int[] _indexList;
  409. private int _count;
  410. private bool _initialized;
  411. private BinaryReader _reader;
  412. private FileStream _fStream;
  413. public FrameSet Frames
  414. {
  415. get { return _frames; }
  416. }
  417. public MLibrary(string filename)
  418. {
  419. _fileName = Path.ChangeExtension(filename, Extention);
  420. }
  421. public void Initialize()
  422. {
  423. _initialized = true;
  424. if (!File.Exists(_fileName))
  425. return;
  426. try
  427. {
  428. _fStream = new FileStream(_fileName, FileMode.Open, FileAccess.Read);
  429. _reader = new BinaryReader(_fStream);
  430. int currentVersion = _reader.ReadInt32();
  431. if (currentVersion < 2)
  432. {
  433. System.Windows.Forms.MessageBox.Show("Wrong version, expecting lib version: " + LibVersion.ToString() + " found version: " + currentVersion.ToString() + ".", _fileName, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1);
  434. System.Windows.Forms.Application.Exit();
  435. return;
  436. }
  437. _count = _reader.ReadInt32();
  438. int frameSeek = 0;
  439. if (currentVersion >= 3)
  440. {
  441. frameSeek = _reader.ReadInt32();
  442. }
  443. _images = new MImage[_count];
  444. _indexList = new int[_count];
  445. for (int i = 0; i < _count; i++)
  446. _indexList[i] = _reader.ReadInt32();
  447. if (currentVersion >= 3)
  448. {
  449. _fStream.Seek(frameSeek, SeekOrigin.Begin);
  450. var frameCount = _reader.ReadInt32();
  451. if (frameCount > 0)
  452. {
  453. _frames = new FrameSet();
  454. for (int i = 0; i < frameCount; i++)
  455. {
  456. _frames.Add((MirAction)_reader.ReadByte(), new Frame(_reader));
  457. }
  458. }
  459. }
  460. }
  461. catch (Exception)
  462. {
  463. _initialized = false;
  464. throw;
  465. }
  466. }
  467. private bool CheckImage(int index)
  468. {
  469. if (!_initialized)
  470. Initialize();
  471. if (_images == null || index < 0 || index >= _images.Length)
  472. return false;
  473. if (_images[index] == null)
  474. {
  475. _fStream.Position = _indexList[index];
  476. _images[index] = new MImage(_reader);
  477. }
  478. MImage mi = _images[index];
  479. if (!mi.TextureValid)
  480. {
  481. if ((mi.Width == 0) || (mi.Height == 0))
  482. return false;
  483. _fStream.Seek(_indexList[index] + 17, SeekOrigin.Begin);
  484. mi.CreateTexture(_reader);
  485. }
  486. return true;
  487. }
  488. public Point GetOffSet(int index)
  489. {
  490. if (!_initialized) Initialize();
  491. if (_images == null || index < 0 || index >= _images.Length)
  492. return Point.Empty;
  493. if (_images[index] == null)
  494. {
  495. _fStream.Seek(_indexList[index], SeekOrigin.Begin);
  496. _images[index] = new MImage(_reader);
  497. }
  498. return new Point(_images[index].X, _images[index].Y);
  499. }
  500. public Size GetSize(int index)
  501. {
  502. if (!_initialized) Initialize();
  503. if (_images == null || index < 0 || index >= _images.Length)
  504. return Size.Empty;
  505. if (_images[index] == null)
  506. {
  507. _fStream.Seek(_indexList[index], SeekOrigin.Begin);
  508. _images[index] = new MImage(_reader);
  509. }
  510. return new Size(_images[index].Width, _images[index].Height);
  511. }
  512. public Size GetTrueSize(int index)
  513. {
  514. if (!_initialized)
  515. Initialize();
  516. if (_images == null || index < 0 || index >= _images.Length)
  517. return Size.Empty;
  518. if (_images[index] == null)
  519. {
  520. _fStream.Position = _indexList[index];
  521. _images[index] = new MImage(_reader);
  522. }
  523. MImage mi = _images[index];
  524. if (mi.TrueSize.IsEmpty)
  525. {
  526. if (!mi.TextureValid)
  527. {
  528. if ((mi.Width == 0) || (mi.Height == 0))
  529. return Size.Empty;
  530. _fStream.Seek(_indexList[index] + 17, SeekOrigin.Begin);
  531. mi.CreateTexture(_reader);
  532. }
  533. return mi.GetTrueSize();
  534. }
  535. return mi.TrueSize;
  536. }
  537. public void Draw(int index, int x, int y)
  538. {
  539. if (x >= Settings.ScreenWidth || y >= Settings.ScreenHeight)
  540. return;
  541. if (!CheckImage(index))
  542. return;
  543. MImage mi = _images[index];
  544. if (x + mi.Width < 0 || y + mi.Height < 0)
  545. return;
  546. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)x, (float)y, 0.0F), Color.White);
  547. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  548. }
  549. public void Draw(int index, Point point, Color colour, bool offSet = false)
  550. {
  551. if (!CheckImage(index))
  552. return;
  553. MImage mi = _images[index];
  554. if (offSet) point.Offset(mi.X, mi.Y);
  555. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  556. return;
  557. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), colour);
  558. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  559. }
  560. public void Draw(int index, Point point, Color colour, bool offSet, float opacity)
  561. {
  562. if (!CheckImage(index))
  563. return;
  564. MImage mi = _images[index];
  565. if (offSet) point.Offset(mi.X, mi.Y);
  566. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  567. return;
  568. DXManager.DrawOpaque(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), colour, opacity);
  569. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  570. }
  571. public void DrawBlend(int index, Point point, Color colour, bool offSet = false, float rate = 1)
  572. {
  573. if (!CheckImage(index))
  574. return;
  575. MImage mi = _images[index];
  576. if (offSet) point.Offset(mi.X, mi.Y);
  577. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  578. return;
  579. bool oldBlend = DXManager.Blending;
  580. DXManager.SetBlend(true, rate);
  581. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), colour);
  582. DXManager.SetBlend(oldBlend);
  583. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  584. }
  585. public void Draw(int index, Rectangle section, Point point, Color colour, bool offSet)
  586. {
  587. if (!CheckImage(index))
  588. return;
  589. MImage mi = _images[index];
  590. if (offSet) point.Offset(mi.X, mi.Y);
  591. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  592. return;
  593. if (section.Right > mi.Width)
  594. section.Width -= section.Right - mi.Width;
  595. if (section.Bottom > mi.Height)
  596. section.Height -= section.Bottom - mi.Height;
  597. DXManager.Draw(mi.Image, section, new Vector3((float)point.X, (float)point.Y, 0.0F), colour);
  598. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  599. }
  600. public void Draw(int index, Rectangle section, Point point, Color colour, float opacity)
  601. {
  602. if (!CheckImage(index))
  603. return;
  604. MImage mi = _images[index];
  605. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  606. return;
  607. if (section.Right > mi.Width)
  608. section.Width -= section.Right - mi.Width;
  609. if (section.Bottom > mi.Height)
  610. section.Height -= section.Bottom - mi.Height;
  611. DXManager.DrawOpaque(mi.Image, section, new Vector3((float)point.X, (float)point.Y, 0.0F), colour, opacity);
  612. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  613. }
  614. public void Draw(int index, Point point, Size size, Color colour)
  615. {
  616. if (!CheckImage(index))
  617. return;
  618. MImage mi = _images[index];
  619. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + size.Width < 0 || point.Y + size.Height < 0)
  620. return;
  621. float scaleX = (float)size.Width / mi.Width;
  622. float scaleY = (float)size.Height / mi.Height;
  623. Matrix matrix = Matrix.Scaling(scaleX, scaleY, 0);
  624. DXManager.Sprite.Transform = matrix;
  625. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X / scaleX, (float)point.Y / scaleY, 0.0F), Color.White);
  626. DXManager.Sprite.Transform = Matrix.Identity;
  627. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  628. }
  629. public void DrawTinted(int index, Point point, Color colour, Color Tint, bool offSet = false)
  630. {
  631. if (!CheckImage(index))
  632. return;
  633. MImage mi = _images[index];
  634. if (offSet) point.Offset(mi.X, mi.Y);
  635. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  636. return;
  637. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), colour);
  638. if (mi.HasMask)
  639. {
  640. DXManager.Draw(mi.MaskImage, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), Tint);
  641. }
  642. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  643. }
  644. public void DrawUp(int index, int x, int y)
  645. {
  646. if (x >= Settings.ScreenWidth)
  647. return;
  648. if (!CheckImage(index))
  649. return;
  650. MImage mi = _images[index];
  651. y -= mi.Height;
  652. if (y >= Settings.ScreenHeight)
  653. return;
  654. if (x + mi.Width < 0 || y + mi.Height < 0)
  655. return;
  656. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3(x, y, 0.0F), Color.White);
  657. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  658. }
  659. public void DrawUpBlend(int index, Point point)
  660. {
  661. if (!CheckImage(index))
  662. return;
  663. MImage mi = _images[index];
  664. point.Y -= mi.Height;
  665. if (point.X >= Settings.ScreenWidth || point.Y >= Settings.ScreenHeight || point.X + mi.Width < 0 || point.Y + mi.Height < 0)
  666. return;
  667. bool oldBlend = DXManager.Blending;
  668. DXManager.SetBlend(true, 1);
  669. DXManager.Draw(mi.Image, new Rectangle(0, 0, mi.Width, mi.Height), new Vector3((float)point.X, (float)point.Y, 0.0F), Color.White);
  670. DXManager.SetBlend(oldBlend);
  671. mi.CleanTime = CMain.Time + Settings.CleanDelay;
  672. }
  673. public bool VisiblePixel(int index, Point point, bool accuate)
  674. {
  675. if (!CheckImage(index))
  676. return false;
  677. if (accuate)
  678. return _images[index].VisiblePixel(point);
  679. int accuracy = 2;
  680. for (int x = -accuracy; x <= accuracy; x++)
  681. for (int y = -accuracy; y <= accuracy; y++)
  682. if (_images[index].VisiblePixel(new Point(point.X + x, point.Y + y)))
  683. return true;
  684. return false;
  685. }
  686. }
  687. public sealed class MImage
  688. {
  689. public short Width, Height, X, Y, ShadowX, ShadowY;
  690. public byte Shadow;
  691. public int Length;
  692. public bool TextureValid;
  693. public Texture Image;
  694. //layer 2:
  695. public short MaskWidth, MaskHeight, MaskX, MaskY;
  696. public int MaskLength;
  697. public Texture MaskImage;
  698. public Boolean HasMask;
  699. public long CleanTime;
  700. public Size TrueSize;
  701. public unsafe byte* Data;
  702. public MImage(BinaryReader reader)
  703. {
  704. //read layer 1
  705. Width = reader.ReadInt16();
  706. Height = reader.ReadInt16();
  707. X = reader.ReadInt16();
  708. Y = reader.ReadInt16();
  709. ShadowX = reader.ReadInt16();
  710. ShadowY = reader.ReadInt16();
  711. Shadow = reader.ReadByte();
  712. Length = reader.ReadInt32();
  713. //check if there's a second layer and read it
  714. HasMask = ((Shadow >> 7) == 1) ? true : false;
  715. if (HasMask)
  716. {
  717. reader.ReadBytes(Length);
  718. MaskWidth = reader.ReadInt16();
  719. MaskHeight = reader.ReadInt16();
  720. MaskX = reader.ReadInt16();
  721. MaskY = reader.ReadInt16();
  722. MaskLength = reader.ReadInt32();
  723. }
  724. }
  725. public unsafe void CreateTexture(BinaryReader reader)
  726. {
  727. int w = Width;// + (4 - Width % 4) % 4;
  728. int h = Height;// + (4 - Height % 4) % 4;
  729. Image = new Texture(DXManager.Device, w, h, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
  730. DataRectangle stream = Image.LockRectangle(0, LockFlags.Discard);
  731. Data = (byte*)stream.Data.DataPointer;
  732. DecompressImage(reader.ReadBytes(Length), stream.Data);
  733. stream.Data.Dispose();
  734. Image.UnlockRectangle(0);
  735. if (HasMask)
  736. {
  737. reader.ReadBytes(12);
  738. w = Width;// + (4 - Width % 4) % 4;
  739. h = Height;// + (4 - Height % 4) % 4;
  740. MaskImage = new Texture(DXManager.Device, w, h, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
  741. stream = MaskImage.LockRectangle(0, LockFlags.Discard);
  742. DecompressImage(reader.ReadBytes(Length), stream.Data);
  743. stream.Data.Dispose();
  744. MaskImage.UnlockRectangle(0);
  745. }
  746. DXManager.TextureList.Add(this);
  747. TextureValid = true;
  748. CleanTime = CMain.Time + Settings.CleanDelay;
  749. }
  750. public unsafe void DisposeTexture()
  751. {
  752. DXManager.TextureList.Remove(this);
  753. if (Image != null && !Image.Disposed)
  754. {
  755. Image.Dispose();
  756. }
  757. if (MaskImage != null && !MaskImage.Disposed)
  758. {
  759. MaskImage.Dispose();
  760. }
  761. TextureValid = false;
  762. Image = null;
  763. MaskImage = null;
  764. Data = null;
  765. }
  766. public unsafe bool VisiblePixel(Point p)
  767. {
  768. if (p.X < 0 || p.Y < 0 || p.X >= Width || p.Y >= Height)
  769. return false;
  770. int w = Width;
  771. bool result = false;
  772. if (Data != null)
  773. {
  774. int x = p.X;
  775. int y = p.Y;
  776. int index = (y * (w << 2)) + (x << 2) + 3;
  777. byte col = Data[index];
  778. if (col == 0) return false;
  779. else return true;
  780. }
  781. return result;
  782. }
  783. public Size GetTrueSize()
  784. {
  785. if (TrueSize != Size.Empty) return TrueSize;
  786. int l = 0, t = 0, r = Width, b = Height;
  787. bool visible = false;
  788. for (int x = 0; x < r; x++)
  789. {
  790. for (int y = 0; y < b; y++)
  791. {
  792. if (!VisiblePixel(new Point(x, y))) continue;
  793. visible = true;
  794. break;
  795. }
  796. if (!visible) continue;
  797. l = x;
  798. break;
  799. }
  800. visible = false;
  801. for (int y = 0; y < b; y++)
  802. {
  803. for (int x = l; x < r; x++)
  804. {
  805. if (!VisiblePixel(new Point(x, y))) continue;
  806. visible = true;
  807. break;
  808. }
  809. if (!visible) continue;
  810. t = y;
  811. break;
  812. }
  813. visible = false;
  814. for (int x = r - 1; x >= l; x--)
  815. {
  816. for (int y = 0; y < b; y++)
  817. {
  818. if (!VisiblePixel(new Point(x, y))) continue;
  819. visible = true;
  820. break;
  821. }
  822. if (!visible) continue;
  823. r = x + 1;
  824. break;
  825. }
  826. visible = false;
  827. for (int y = b - 1; y >= t; y--)
  828. {
  829. for (int x = l; x < r; x++)
  830. {
  831. if (!VisiblePixel(new Point(x, y))) continue;
  832. visible = true;
  833. break;
  834. }
  835. if (!visible) continue;
  836. b = y + 1;
  837. break;
  838. }
  839. TrueSize = Rectangle.FromLTRB(l, t, r, b).Size;
  840. return TrueSize;
  841. }
  842. private static byte[] DecompressImage(byte[] image)
  843. {
  844. using (GZipStream stream = new GZipStream(new MemoryStream(image), CompressionMode.Decompress))
  845. {
  846. const int size = 4096;
  847. byte[] buffer = new byte[size];
  848. using (MemoryStream memory = new MemoryStream())
  849. {
  850. int count = 0;
  851. do
  852. {
  853. count = stream.Read(buffer, 0, size);
  854. if (count > 0)
  855. {
  856. memory.Write(buffer, 0, count);
  857. }
  858. }
  859. while (count > 0);
  860. return memory.ToArray();
  861. }
  862. }
  863. }
  864. private static void DecompressImage(byte[] data, Stream destination)
  865. {
  866. using (var stream = new GZipStream(new MemoryStream(data), CompressionMode.Decompress))
  867. {
  868. stream.CopyTo(destination);
  869. }
  870. }
  871. }
  872. }