public static ConvertedTexture ConvertTexture(string name, string texname, string palname, Bitmap bmp) { int dswidth = 0, dsheight = 0, widthPowerOfTwo = 8, heightPowerOfTwo = 8; GetDSWidthAndHeight(bmp.Width, bmp.Height, out dswidth, out dsheight, out widthPowerOfTwo, out heightPowerOfTwo); // cheap resizing for textures whose dimensions aren't power-of-two if ((widthPowerOfTwo != bmp.Width) || (heightPowerOfTwo != bmp.Height)) { Bitmap newbmp = new Bitmap(widthPowerOfTwo, heightPowerOfTwo); Graphics g = Graphics.FromImage(newbmp); g.DrawImage(bmp, new Rectangle(0, 0, widthPowerOfTwo, heightPowerOfTwo)); bmp = newbmp; } bool alpha = false; for (int y = 0; y < heightPowerOfTwo; y++) { for (int x = 0; x < widthPowerOfTwo; x++) { int a = bmp.GetPixel(x, y).A; if (a >= 8 && a <= 248) { alpha = true; break; } } } int textype = 0; byte[] tex = null; byte[] pal = null; if (alpha) { // a5i3/a3i5 tex = new byte[widthPowerOfTwo * heightPowerOfTwo]; Palette _pal = new Palette(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), 32); int alphamask = 0; if (_pal.m_Palette.Count <= 8) { textype = 6; alphamask = 0xF8; } else { textype = 1; alphamask = 0xE0; } for (int y = 0; y < heightPowerOfTwo; y++) { for (int x = 0; x < widthPowerOfTwo; x++) { Color c = bmp.GetPixel(x, y); ushort bgr15 = Helper.ColorToBGR15(c); int a = c.A & alphamask; byte val = (byte)(_pal.FindClosestColorID(bgr15) | a); tex[(y * widthPowerOfTwo) + x] = val; } } pal = new byte[_pal.m_Palette.Count * 2]; for (int i = 0; i < _pal.m_Palette.Count; i++) { pal[i * 2] = (byte)(_pal.m_Palette[i] & 0xFF); pal[(i * 2) + 1] = (byte)(_pal.m_Palette[i] >> 8); } } else { // type5 - compressed textype = 5; tex = new byte[((widthPowerOfTwo * heightPowerOfTwo) / 16) * 6]; List<Palette> pallist = new List<Palette>(); List<ushort> paldata = new List<ushort>(); int texoffset = 0; int palidxoffset = ((widthPowerOfTwo * heightPowerOfTwo) / 16) * 4; for (int y = 0; y < heightPowerOfTwo; y += 4) { for (int x = 0; x < widthPowerOfTwo; x += 4) { bool transp = false; for (int y2 = 0; y2 < 4; y2++) { for (int x2 = 0; x2 < 4; x2++) { Color c = bmp.GetPixel(x + x2, y + y2); if (c.A < 8) transp = true; } } Palette txpal = new Palette(bmp, new Rectangle(x, y, 4, 4), transp ? 3 : 4); uint texel = 0; ushort palidx = (ushort)(transp ? 0x0000 : 0x8000); for (int y2 = 0; y2 < 4; y2++) { for (int x2 = 0; x2 < 4; x2++) { int px = 0; Color c = bmp.GetPixel(x + x2, y + y2); ushort bgr15 = Helper.ColorToBGR15(c); if (transp && c.A < 8) px = 3; else px = txpal.FindClosestColorID(bgr15); texel |= (uint)(px << ((2 * x2) + (8 * y2))); } } uint paloffset = 0; bool palfound = false; for (int i = 0; i < pallist.Count; i++) { if (Palette.AreSimilar(txpal, pallist[i])) { palfound = true; break; } paloffset += (uint)pallist[i].m_Palette.Count; if ((paloffset & 1) != 0) paloffset++; } paloffset /= 2; palidx |= (ushort)(paloffset & 0x3FFF); if (!palfound) { pallist.Add(txpal); foreach (ushort col in txpal.m_Palette) paldata.Add(col); if ((paldata.Count & 1) != 0) paldata.Add(0x7C1F); } tex[texoffset] = (byte)(texel & 0xFF); tex[texoffset + 1] = (byte)((texel >> 8) & 0xFF); tex[texoffset + 2] = (byte)((texel >> 16) & 0xFF); tex[texoffset + 3] = (byte)(texel >> 24); texoffset += 4; tex[palidxoffset] = (byte)(palidx & 0xFF); tex[palidxoffset + 1] = (byte)(palidx >> 8); palidxoffset += 2; } } pal = new byte[paldata.Count * 2]; for (int i = 0; i < paldata.Count; i++) { pal[i * 2] = (byte)(paldata[i] & 0xFF); pal[(i * 2) + 1] = (byte)(paldata[i] >> 8); } } uint dstp = GetDSTextureParamsPart1(dswidth, dsheight, textype, 0); return new ConvertedTexture(dstp, tex, pal, texname, palname); }