Skip to content

Instantly share code, notes, and snippets.

@AraHaan
Last active February 20, 2020 21:32
Show Gist options
  • Save AraHaan/9411cb0162b868a447ea216a53b4406f to your computer and use it in GitHub Desktop.
Save AraHaan/9411cb0162b868a447ea216a53b4406f to your computer and use it in GitHub Desktop.
Some bmp converter that should convert 256 color bitmap data to an Crash Bandicoot Texture Chunk.
private void Menu_ConvertBMP()
{
byte[] data = FileUtil.OpenFile(out string fileName, FileFilters.BMP);
if (data == null)
return;
string ename = fileName.Substring(0, 5);
// first things first generate some stuff.
List<byte> fileHeader = new List<byte>();
fileHeader.AddRange(BitConverter.GetBytes((short)0x1234));
fileHeader.AddRange(BitConverter.GetBytes((short)1));
fileHeader.AddRange(BitConverter.GetBytes(Entry.ENameToEID(ename)));
fileHeader.AddRange(BitConverter.GetBytes(5));
fileHeader.AddRange(new byte[] { (byte)0, (byte)0, (byte)0, (byte)0 });
using (MemoryStream ms = new MemoryStream(data))
using (Bitmap bmp = new Bitmap(ms))
{
List<List<short>> paletteDatas = new List<List<short>>();
ColorPalette palette = bmp.Palette;
List<Color> colors = palette.Entries.ToList();
// now we must row out the palette data properly.
for (int row = 0; row < 16; row++)
{
List<short> paletteData = new List<short>();
if (row == 0)
{
// paletteData.AddRange(new short[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
foreach (var palcol in colors)
{
paletteData.Add(PixelConv.Convert8888_5551(palcol));
}
// after this now we must finish off the first row.
// for (int i = 256; i < 512; i++)
// {
// paletteData.Add(PixelConv.Pack1555(1, 0, 0, 0));
// paletteData.Add(PixelConv.Convert8888_5551(Color.FromArgb(0, 0, 0)));
// }
paletteDatas.Add(paletteData);
}
else
{
// for (int i = 0; i < 256; i++)
// {
// paletteData.Add(PixelConv.Convert8888_5551(Color.FromArgb(0, 0, 0)));
// }
// paletteDatas.Add(paletteData);
}
}
// now we need the raw pixel data that references the palette indexes somehow...
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
int length = bitmapData.Stride * bitmapData.Height;
byte[] bytes = new byte[length];
// Copy bitmap to byte[]
Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
bmp.UnlockBits(bitmapData);
List<byte> converted = new List<byte>();
foreach (List<short> paletteData in paletteDatas)
{
foreach (short paletteCol in paletteData)
{
converted.Add(Convert.ToByte(paletteCol));
}
}
// paletteDatas.RemoveRange(0, paletteDatas.Count);
if (converted.Count + bytes.Length < 0xFFF0)
{
do
{
converted.Add((byte)0);
}
while (converted.Count + bytes.Length < 0xFFF0);
// Debug.WriteLine($"Texture data is {converted.Count + bytes.Length}/65520 bytes!!!");
}
else
{
Debug.WriteLine($"Texture data is {converted.Count + bytes.Length}/65520 bytes!!!");
}
converted.AddRange(bytes);
if (converted.Count == 0xFFF0)
{
Debug.WriteLine($"Texture data should be ok now.");
}
else
{
Debug.WriteLine($"Texture data is bad: over by {converted.Count - 65520} bytes!!!");
}
fileHeader.AddRange(converted);
byte[] fileBytes = fileHeader.ToArray();
int current_checksum = BitConv.FromInt32(fileBytes, 12);
int correct_checksum = Chunk.CalculateChecksum(fileBytes);
if (current_checksum == correct_checksum)
{
Debug.WriteLine("Checksum was already correct.");
_ = FileUtil.SaveFile(fileBytes, FileFilters.Any);
return;
}
BitConv.ToInt32(fileBytes, 12, correct_checksum);
Debug.WriteLine("Checksum was incorrect and has been corrected.");
_ = FileUtil.SaveFile(fileBytes, FileFilters.Any);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment