/// <summary> /// Output 32 bit Color data for image. /// </summary> /// <param name="br">Binary reader pointing to memory stream of data.</param> /// <param name="palette">Color[] palette</param> /// <param name="bIgnoreSize"> /// If true skip size check useful for files with more than just Tim /// </param> /// <returns>Color[]</returns> /// <remarks> /// This allows null palette but it doesn't seem to handle the palette being null /// </remarks> protected TextureBuffer CreateImageBuffer(BinaryReader br, Color[] palette = null) { br.BaseStream.Seek(TextureDataPointer, SeekOrigin.Begin); var buffer = new TextureBuffer(Texture.Width, Texture.Height); //ARGB if (Assert((buffer.Length / BPP) <= br.BaseStream.Length - br.BaseStream.Position)) //make sure the buffer is large enough { return(null); } if (BPP == 8) { for (var i = 0; i < buffer.Length; i++) { var colorKey = br.ReadByte(); if (colorKey < Texture.NumOfColors) { buffer[i] = palette[colorKey]; //color key } //else // buffer[i] = Color.TransparentBlack; // trying something out of ordinary. } } else if (BPP == 4) { for (var i = 0; i < buffer.Length; i++) { var colorKey = br.ReadByte(); buffer[i] = palette[colorKey & 0xf]; buffer[++i] = palette[colorKey >> 4]; } } else if (BPP == 16) //copied from overture { for (var i = 0; i < buffer.Length && br.BaseStream.Position + 2 < br.BaseStream.Length; i++) { buffer[i] = ABGR1555toRGBA32bit(br.ReadUInt16(), IgnoreAlpha); } } else if (BPP == 24) //could be wrong. // assuming it is BGR { for (var i = 0; i < buffer.Length && br.BaseStream.Position + 2 < br.BaseStream.Length; i++) { var pixel = br.ReadBytes(3); buffer[i] = new Color { r = pixel[2], g = pixel[1], b = pixel[0], a = 0xFF }; } } else { throw new Exception($"TIM_v2::CreateImageBuffer::TIM unsupported bits per pixel = {BPP}"); } //Then in bs debug where ReadTexture store for all cluts //data and then create Texture2D from there. (array of e.g. 15 texture2D) return(buffer); }
/// <summary> /// Get Texture2D converted to 32bit color /// </summary> /// <param name="forcePalette">Desired Palette, see texture.NumOfPalettes. -1 is default.</param> /// <param name="colors">Override colors of palette; Array size must match texture.NumOfColorsPerPalette</param> /// <returns>32bit Texture2D</returns> /// <remarks> /// Some paletts are 256 but the game only uses 16 colors might need to make the restriction /// more lax and allow any size array and only throw errors if the colorkey is greater than /// size of array. Or we could treat any of those bad matches as transparent. /// </remarks> public override Texture2D GetTexture(Color[] colors) { if (Memory.graphics.GraphicsDevice == null) { return(null); } if (texture.PaletteFlag != 0) { if (colors == null) { throw new ArgumentNullException(nameof(colors)); } //if (colors != null && colors.Length != texture.NumOfColours) //{ // //if (colors.Length > texture.NumOfColours) //truncate colors to the correct amount. in some // // colors = colors.Take(texture.NumOfColours).ToArray(); // //else // might need to expand the array the other way if we get more mismatches. // //Array.Resize(ref colors,texture.NumOfColours); // //throw new Exception($" custom colors parameter set but array size to match palette size: {texture.NumOfColours}"); //} MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); for (int i = 0; i < convertBuffer.Length && ms.Position < ms.Length; i++) { byte colorKey = br.ReadByte(); if (colorKey > colors.Length) { continue; } convertBuffer[i] = colors[colorKey]; } return(convertBuffer.GetTexture()); } } else { if (texture.bytesPerPixel == 2) { MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); for (int i = 0; ms.Position + 2 < ms.Length; i++) { convertBuffer[i] = ABGR1555toRGBA32bit(br.ReadUInt16()); } return(convertBuffer.GetTexture()); } } else if (texture.bytesPerPixel == 3) { // not tested but vincent tim had support for it so i guess it's possible RGB or BGR MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); Color color; color.A = 0xFF; for (int i = 0; ms.Position + 3 < ms.Length; i++) { //RGB or BGR so might need to reorder things to RGB color.B = br.ReadByte(); color.G = br.ReadByte(); color.R = br.ReadByte(); convertBuffer[i] = color; } return(convertBuffer.GetTexture()); } } } return(null); }
/// <summary> /// Get Texture2D converted to 32bit color /// </summary> /// <param name="forcePalette">Desired Palette, see texture.NumOfPalettes. -1 is default.</param> /// <param name="colors">Override colors of palette; Array size must match texture.NumOfColorsPerPalette</param> /// <returns>32bit Texture2D</returns> /// <remarks> /// Some paletts are 256 but the game only uses 16 colors might need to make the restriction /// more lax and allow any size array and only throw errors if the colorkey is greater than /// size of array. Or we could treat any of those bad matches as transparent. /// </remarks> public override Texture2D GetTexture(Color[] colors = null) { if (Memory.graphics.GraphicsDevice != null) { if (texture.PaletteFlag != 0) { if (colors != null && colors.Length != texture.NumOfColours) { throw new Exception($" custom colors parameter set but array size to match palette size: {texture.NumOfColours}"); } MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); for (int i = 0; i < convertBuffer.Length && ms.Position < ms.Length; i++) { convertBuffer[i] = colors[br.ReadByte()]; //colorkey } return(convertBuffer.GetTexture()); } } else if (texture.bytesPerPixel == 2) { MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); for (int i = 0; ms.Position + 2 < ms.Length; i++) { convertBuffer[i] = ABGR1555toRGBA32bit(br.ReadUInt16()); } return(convertBuffer.GetTexture()); } } else if (texture.bytesPerPixel == 3) { // not tested but vincent tim had support for it so i guess it's possible RGB or BGR MemoryStream ms; using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer))) { ms.Seek(TextureLocator, SeekOrigin.Begin); TextureBuffer convertBuffer = new TextureBuffer(texture.Width, texture.Height); Color color; color.A = 0xFF; for (int i = 0; ms.Position + 3 < ms.Length; i++) { //RGB or BGR so might need to reorder things to RGB color.B = br.ReadByte(); color.G = br.ReadByte(); color.R = br.ReadByte(); convertBuffer[i] = color; } return(convertBuffer.GetTexture()); } } } return(null); }