public Tim GetTrueColorTexture(int x, int y, int w, int h) { ushort[] buf = new ushort[w * h]; //Console.WriteLine(width + "x" + height); int ptr = 1024 * y + x; // tl.PageY * 1024 * (1024 * 2 / 16) + tl.frame.Y * 1024 + tl.PageX * (1024 * 2 / 16) + tl.frame.X; for (int i = 0; i < h; i++) { Buffer.BlockCopy( this.data, ptr * 2, buf, i * w * 2, w * 2); ptr += 1024; } Tim tim = new Tim(new Rectangle(x, y, w, h)); tim.data = buf; tim.flags = 2; //4 bit + pal = 8 return(tim); }
/// <summary> /// Returns bitmap object. /// </summary> /// <param name="tl"></param> /// <param name="path"></param> /// <param name="name"></param> /// <returns></returns> public Bitmap GetTexture(TextureLayout tl, string path = "", string name = "") { try { Tim x = GetTimTexture(tl); if (x.region.Width <= 0 || x.region.Height <= 0) { Helpers.Panic(this, "negative or null size"); return(new Bitmap(1, 1)); } using (MemoryStream stream = new MemoryStream(x.SaveBMPToStream(CtrClutToBmpPalette(x.clutdata)))) { Bitmap oldBmp = (Bitmap)Bitmap.FromStream(stream); Bitmap newBmp = new Bitmap(oldBmp); if (!textures.ContainsKey(tl.Tag())) { textures.Add(tl.Tag(), newBmp); } return(newBmp); } } catch (Exception ex) { Helpers.Panic(this, "GetTexture fails: " + " " + ex.Message + "\r\n" + ex.ToString() + "\r\n"); return(null); } }
/// <summary> /// Cuts a Tim subtexture from current Tim, based on TextureLayout data. /// </summary> /// <param name="tl">TextureLayout object.</param> /// <returns>Tim object.</returns> public Tim GetTimTexture(TextureLayout tl) { int bpp = 4; if (tl.f1 > 0 && tl.f2 > 0 && tl.f3 > 0) { bpp = 8; } //Directory.CreateDirectory(path); //int width = (tl.width / 4) * 2; int width = (int)(tl.width * (bpp / 8.0f)); int height = tl.height; Console.WriteLine(width + "x" + height); ushort[] buf = new ushort[(width / 2) * height]; //Console.WriteLine(width + "x" + height); int ptr = tl.Position * 2; // tl.PageY * 1024 * (1024 * 2 / 16) + tl.frame.Y * 1024 + tl.PageX * (1024 * 2 / 16) + tl.frame.X; for (int i = 0; i < height; i++) { Buffer.BlockCopy( this.data, ptr, buf, i * width, width); ptr += CtrVrm.Width * 2; } Tim x = new Tim(tl.frame); x.data = buf; x.region = new Rectangle(tl.RealX, tl.RealY, tl.width / 4, tl.height); x.clutregion = new Rectangle(tl.PalX * 16, tl.PalY, 16, 1); x.clutdata = GetCtrClut(tl); x.clutsize = (uint)(x.clutregion.Width * 2 + 12); x.flags = 8; //4 bit + pal = 8 /* * Rectangle r = x.clutregion; * * if (r.Width % 4 != 0) * r.Width += 16; * * Tim x2 = new Tim(r); * x2.DrawTim(x); */ //Console.WriteLine(x.clutdata.Length); return(x); }
public Tim GetVram() { Tim buffer = new Tim(new Rectangle(0, 0, Width, Height)); foreach (var tim in Tims) { buffer.DrawTim(tim); } return(buffer); }
/// <summary> /// Draws one TIM over another. /// Not a failproof implementation, ensure that target TIM is larger than original. /// In CTR context only used to draw 2 TIM regions in a single TIM. /// </summary> /// <param name="src">Source TIM to draw.</param> public void DrawTim(Tim src) { int dstptr = (this.region.Width * src.region.Y + src.region.X) * 2; int srcptr = 0; for (int i = 0; i < src.region.Height; i++) { //Console.WriteLine(srcptr + "\t" + dstptr); //Console.ReadKey(); Buffer.BlockCopy( src.data, srcptr, this.data, dstptr, src.region.Width * 2); dstptr += this.region.Width * 2; srcptr += src.region.Width * 2; } }
/// <summary> /// Draws one TIM over another. /// Not a failproof implementation, ensure that target TIM is larger than original. /// In CTR context only used to draw 2 TIM regions in a single TIM. /// </summary> /// <param name="src">Source TIM to draw.</param> public void DrawTim(Tim src) { if (src.data == null) { Helpers.Panic(this, "missing tim data."); return; } //int dstptr = (this.region.Width * src.region.Y + src.region.X) * 2; int srcptr = 0; int dstptr = this.region.Width * src.region.Y * 2 + src.region.X * 2; for (int i = 0; i < src.region.Height; i++) { //Console.WriteLine(srcptr + "\t" + dstptr); //Console.ReadKey(); Buffer.BlockCopy( src.data, srcptr, this.data, dstptr, src.region.Width * 2); dstptr += this.region.Width * 2; srcptr += src.region.Width * 2; } if (src.clutdata == null) { Helpers.Panic(this, "clutdata is missing"); return; } Buffer.BlockCopy( src.clutdata, 0, this.data, (this.region.Width * src.clutregion.Y + src.clutregion.X) * 2, src.clutdata.Length * 2); //keep in mind there will be leftover garbage if palette is less than 16 colors. }
public static Tim FromStream(Stream str) { frames.Clear(); buffer = new Tim(new Rectangle(0, 0, Width, Height)); using (BinaryReaderEx br = new BinaryReaderEx(str)) { if (br.ReadInt32() == 0x20) { for (int i = 0; i < 2; i++) { br.ReadInt32(); Tim tim = new Tim(br); //tim.Write("vram" + i.ToString("X2") + ".tim"); buffer.DrawTim(tim); frames.Add(tim.region); Console.WriteLine(tim.ToString()); } } else { br.BaseStream.Position = 0; Tim tim = new Tim(br); //tim.Write("vram01.tim"); buffer.DrawTim(tim); frames.Add(tim.region); Console.WriteLine(tim.ToString()); } //use this to dump whole vram as a single grayscale image //buffer.SaveBMP("vram.png", BMPHeader.GrayScalePalette(16)); //buffer.Write("vram.tim"); return(buffer); } }
public static Tim FromFile(string fn) { Tim buffer = new Tim(new Rectangle(0, 0, Width, Height)); if (File.Exists(fn)) { using (BinaryReaderEx br = new BinaryReaderEx(File.OpenRead(fn))) { if (br.ReadInt32() == 0x20) { for (int i = 0; i < 2; i++) { br.ReadInt32(); Tim tim = new Tim(br); //tim.Write("vram" + i.ToString("X2") + ".tim"); buffer.DrawTim(tim); frames.Add(tim.region); Console.WriteLine(tim.ToString()); } } else { br.BaseStream.Position = 0; Tim tim = new Tim(br); //tim.Write("vram01.tim"); buffer.DrawTim(tim); frames.Add(tim.region); Console.WriteLine(tim.ToString()); } } } return(buffer); }
public void GetTexture(TextureLayout tl, string path, string name = "") { try { Directory.CreateDirectory(path); int width = (tl.width / 4) * 2; int height = tl.height; ushort[] buf = new ushort[(width / 2) * height]; //Console.WriteLine(width + "x" + height); int ptr = tl.Position * 2; // tl.PageY * 1024 * (1024 * 2 / 16) + tl.frame.Y * 1024 + tl.PageX * (1024 * 2 / 16) + tl.frame.X; for (int i = 0; i < height; i++) { Buffer.BlockCopy( this.data, ptr, buf, i * width, width); ptr += CtrVrm.Width * 2; } Tim x = new Tim(tl.frame); x.data = buf; x.region = new Rectangle(tl.RealX, tl.RealY, tl.width / 4, tl.height); x.clutregion = new Rectangle(tl.PalX * 16, tl.PalY, 16, 1); x.clutdata = GetCtrClut(tl); x.clutsize = (uint)(x.clutregion.Width * 2 + 12); x.flags = 8; //4 bit + pal = 8 /* * Rectangle r = x.clutregion; * * if (r.Width % 4 != 0) * r.Width += 16; * * Tim x2 = new Tim(r); * x2.DrawTim(x); */ //Console.WriteLine(x.clutdata.Length); if (x.region.Width > 0 && x.region.Height > 0) { string n = path + "\\" + (name == "" ? tl.Tag() : name); //if (!File.Exists(n + ".tim")) x.Write(n + ".tim"); //if (!File.Exists(n + ".bmp")) x.SaveBMP(n + ".bmp", CtrClutToBmpPalette(x.clutdata)); //if (!File.Exists(n + ".png")) using (Bitmap oldBmp = new Bitmap(n + ".bmp")) using (Bitmap newBmp = new Bitmap(oldBmp)) { newBmp.Save(n + ".png", System.Drawing.Imaging.ImageFormat.Png); } } else { throw new Exception("negative or null size"); Console.WriteLine("failed!" + tl.ToString()); Console.ReadKey(); } } catch (Exception ex) { Helpers.Panic(this, "GetTexture fails: " + path + " " + ex.Message + "\r\n" + ex.ToString() + "\r\n"); } }