Basic palette and bitmap format.
bool flip = false; int magic = GT.ReadInt32(fs, 4, flip); int unknown = GT.ReadInt32(fs, 4, flip); width = GT.ReadInt32(fs, 4, flip); height = GT.ReadInt32(fs, 4, flip); long apal = fs.Position; long atex = 0x410; int HALFX = width / 2; int HALFY = height / 2; int TLONG = width * height + 1372; int XY = width * height; // Color Palette = RGBA8888 fs.Position = apal; Color[] palette = new Color[256]; for (int p = 0; p < 256; p++) { byte r = GT.ReadByte(fs); byte g = GT.ReadByte(fs); byte b = GT.ReadByte(fs); byte a = GT.ReadByte(fs); // Max is 127, is it alpha? //a = 255; //Console.WriteLine(r + " " + g + " " + b + " " + a); palette[p] = Color.FromArgb(a*2, r, g, b); } fs.Position = atex; bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { byte pix = GT.ReadByte(fs); bitmap.SetPixel(x, y, palette[pix]); } }
CMPR (basically DXT1 but reordered).
bool flip = true; int magic = GT.ReadInt32(fs, 4, flip); int stuff = GT.ReadInt32(fs, 4, flip); width = GT.ReadInt32(fs, 4, flip); height = GT.ReadInt32(fs, 4, flip); int unknown = GT.ReadInt32(fs, 4, flip); int format = GT.ReadInt32(fs, 4, flip); fs.Position = 0x20; //Only for Gamecube Color[][] blocks = DXT.ReadCMPR(fs, flip, width, height); bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int bi = 0; for (int y = 0; y < height / 4; y++) { for (int x = 0; x < width / 4; x++) { for (int i = 0; i < 16; i++) { int row = i / 4; int col = i - (row * 4); bitmap.SetPixel(x * 4 + col, y * 4 + row, blocks[bi][i]); } bi++; } }
Uses a mixture of DXT1, DXT3 and Morton Order bitmap.
bool flip = false; fs.Position = 0; int magic = GT.ReadInt32(fs, 4, flip); int stuff = GT.ReadInt32(fs, 4, flip); width = GT.ReadInt32(fs, 4, flip); height = GT.ReadInt32(fs, 4, flip); //int unknown = GT.ReadInt32(fs, 4, flip); fs.Position = 0x14; int format = GT.ReadInt32(fs, 4, flip); fs.Position = 0x80; //Only for Xbox Color[][] blocks = null; if (format == 0) blocks = DXT.ReadDXT1(fs, flip, width, height); else if (format == 1) blocks = DXT.ReadDXT3(fs, flip, width, height); else if (format == 2) { //Morton Order blocks = new Color[height][]; for (int y = 0; y < height; y++) { blocks[y] = new Color[width]; for (int x = 0; x < width; x++) { int idx = DXT.Morton2D(y, x); if ((idx * 4 + 4) > fs.Length - 0x80) idx = 0; fs.Position = 128 + idx * 4; blocks[y][x] = Color.FromArgb(GT.ReadInt32(fs, 4, flip)); } } } else if (format == 3) Console.WriteLine(); else throw new Exception(); bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (blocks.Length == height) { //RGB Style for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { bitmap.SetPixel(x, y, blocks[y][x]); } } } else { //DXT Style int bi = 0; for (int y = 0; y < height / 4; y++) { for (int x = 0; x < width / 4; x++) { for (int i = 0; i < 16; i++) { int row = i / 4; int col = i - (row * 4); bitmap.SetPixel(x * 4 + col, y * 4 + row, blocks[bi][i]); } bi++; } } }