public static STim Decode4(byte[] picbin, byte[] palbin, int tbw, int cx, int cy) { Bitmap pic = new Bitmap(cx, cy, global::System.Drawing.Imaging.PixelFormat.Format4bppIndexed); tbw /= 2; XDebug.Assert(tbw != 0, "Invalid"); byte[] bin = OpenKh.Kh2.Ps2.Decode4(picbin, tbw, Math.Max(1, picbin.Length / 8192 / tbw)); BitmapData bd = pic.LockBits(Rectangle.FromLTRB(0, 0, pic.Width, pic.Height), ImageLockMode.WriteOnly, global::System.Drawing.Imaging.PixelFormat.Format4bppIndexed); try { int buffSize = bd.Stride * bd.Height; global::System.Runtime.InteropServices.Marshal.Copy(bin, 0, bd.Scan0, Math.Min(bin.Length, buffSize)); } finally { pic.UnlockBits(bd); } ColorPalette pals = pic.Palette; int psi = 0; for (int pi = 0; pi < 16; pi++) { pals.Entries[pi] = CUtil.Gamma(Color.FromArgb( AcUt.GetA(palbin[psi + 4 * pi + 3]), palbin[psi + 4 * pi + 0], palbin[psi + 4 * pi + 1], palbin[psi + 4 * pi + 2] ), γ); } pic.Palette = pals; return(new STim(pic)); }
public STim Do2(Stream si) { BinaryReader br = new BinaryReader(si); UInt64 command; UInt64 r3f = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x3F); // 0x3F TEXFLUSH UInt64 r34 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x34); // 0x34 MIPTBP1_1 UInt64 r36 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x36); // 0x36 MIPTBP2_1 UInt64 r16 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x16); // 0x16 TEX2_1 int t2PSM = ((int)(r16 >> 20)) & 0x3F; int t2CBP = ((int)(r16 >> 37)) & 0x3FFF; int t2CPSM = ((int)(r16 >> 51)) & 0xF; int t2CSM = ((int)(r16 >> 55)) & 0x1; int t2CSA = ((int)(r16 >> 56)) & 0x1F; int t2CLD = ((int)(r16 >> 61)) & 0x7; XTrace.Assert(t2PSM == 19); // PSMT8 XTrace.Assert(t2CPSM == 0); // PSMCT32 XTrace.Assert(t2CSM == 0); // CSM1 XTrace.Assert(t2CSA == 0); XTrace.Assert(t2CLD == 4); UInt64 r14 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x14);// 0x14 TEX1_1 int t1LCM = ((int)(r14 >> 0)) & 1; int t1MXL = ((int)(r14 >> 2)) & 7; int t1MMAG = ((int)(r14 >> 5)) & 1; int t1MMIN = ((int)(r14 >> 6)) & 7; int t1MTBA = ((int)(r14 >> 9)) & 1; int t1L = ((int)(r14 >> 19)) & 3; int t1K = ((int)(r14 >> 32)) & 0xFFF; UInt64 r06 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x06);// 0x06 TEX0_1 int t0TBP0 = ((int)(r06 >> 0)) & 0x3FFF; int t0TBW = ((int)(r06 >> 14)) & 0x3F; t0PSM = ((int)(r06 >> 20)) & 0x3F; int t0TW = ((int)(r06 >> 26)) & 0xF; int t0TH = ((int)(r06 >> 30)) & 0xF; int t0TCC = ((int)(r06 >> 34)) & 0x1; int t0TFX = ((int)(r06 >> 35)) & 0x3; int t0CBP = ((int)(r06 >> 37)) & 0x3FFF; int t0CPSM = ((int)(r06 >> 51)) & 0xF; int t0CSM = ((int)(r06 >> 55)) & 0x1; int t0CSA = ((int)(r06 >> 56)) & 0x1F; int t0CLD = ((int)(r06 >> 61)) & 0x7; XTrace.Assert(t0PSM == 19 || t0PSM == 20); XTrace.Assert(t0TCC == 1); XTrace.Assert(t0CPSM == 0); XTrace.Assert(t0CSM == 0); //XTrace.Assert(t0CSA == 0); XTrace.Assert(t0CLD == 0); UInt64 r08 = br.ReadUInt64(); XTrace.Assert((command = br.ReadUInt64()) == 0x08);// 0x08 CLAMP_1 int c1WMS = ((int)(r08 >> 0)) & 0x3; int c1WMT = ((int)(r08 >> 2)) & 0x3; int c1MINU = ((int)(r08 >> 4)) & 0x3FF; int c1MAXU = ((int)(r08 >> 14)) & 0x3FF; int c1MINV = ((int)(r08 >> 24)) & 0x3FF; int c1MAXV = ((int)(r08 >> 34)) & 0x3FF; int sizetbp0 = (1 << t0TW) * (1 << t0TH); byte[] buftbp0 = new byte[Math.Max(8192, sizetbp0)]; // needs at least 8kb Array.Copy(gs, 256 * t0TBP0, buftbp0, 0, Math.Min(gs.Length - 256 * t0TBP0, Math.Min(buftbp0.Length, sizetbp0))); byte[] bufcbpX = new byte[8192]; Array.Copy(gs, 256 * t0CBP, bufcbpX, 0, bufcbpX.Length); XDebug.WriteLine(string.Format("# p2 {0:x4} {1:x4} {2,2}", t0TBP0, t0CBP, t0CSA)); STim st = null; if (t0PSM == 0x13) { st = TexUt2.Decode8(buftbp0, bufcbpX, t0TBW, 1 << t0TW, 1 << t0TH); } if (t0PSM == 0x14) { st = TexUt2.Decode4Ps(buftbp0, bufcbpX, t0TBW, 1 << t0TW, 1 << t0TH, t0CSA); } if (st != null) { st.tfx = (TFX)t0TFX; st.tcc = (TCC)t0TCC; st.wms = (WM)c1WMS; st.wmt = (WM)c1WMT; st.minu = c1MINU; st.maxu = c1MAXU; st.minv = c1MINV; st.maxv = c1MAXV; } return(st); }
public Bitmap Generate() { if (wms == WM.RRepeat && wmt == WM.RRepeat) { Bitmap p = new Bitmap(UMSK + 1, VMSK + 1); using (Graphics cv = Graphics.FromImage(p)) { cv.DrawImage( pic, new Point[] { new Point(0, 0), new Point(p.Width, 0), new Point(0, p.Height), }, new Rectangle(UFIX, VFIX, UMSK + 1, VMSK + 1), GraphicsUnit.Pixel ); } return(p); } else if (wms == WM.RClamp && wmt == WM.RClamp) { Bitmap p = new Bitmap(pic); using (Graphics cv = Graphics.FromImage(p)) { int x0 = 0, y0 = 0; int x1 = minu, y1 = minv; int x2 = maxu, y2 = maxv; int x3 = p.Width, y3 = p.Height; cv.CompositingMode = global::System.Drawing.Drawing2D.CompositingMode.SourceCopy; //TL cv.FillRectangle( new SolidBrush(p.GetPixel(x1, y1)), Rectangle.FromLTRB(x0, y0, x1, y1) ); //TC cv.DrawImage( p, new Point[] { new Point(x1, y0), new Point(x2, y0), new Point(x1, y1), }, Rectangle.FromLTRB(x1, y1, x2, y1 + 1), GraphicsUnit.Pixel ); //TR cv.FillRectangle( new SolidBrush(p.GetPixel(x2, y1)), Rectangle.FromLTRB(x2, y0, x3, y1) ); //ML cv.DrawImage( p, new Point[] { new Point(x0, y1), new Point(x1, y1), new Point(x0, y2), }, Rectangle.FromLTRB(x1, y1, x1 + 1, y2), GraphicsUnit.Pixel ); //MR cv.DrawImage( p, new Point[] { new Point(x2, y1), new Point(x3, y1), new Point(x2, y2), }, Rectangle.FromLTRB(x2 - 1, y1, x2, y2), GraphicsUnit.Pixel ); //BL cv.FillRectangle( new SolidBrush(p.GetPixel(x1, y2)), Rectangle.FromLTRB(x0, y2, x1, y3) ); //BC cv.DrawImage( p, new Point[] { new Point(x1, y2), new Point(x2, y2), new Point(x1, y3), }, Rectangle.FromLTRB(x1, y2 - 1, x2, y2), GraphicsUnit.Pixel ); //BR cv.FillRectangle( new SolidBrush(p.GetPixel(x2, y2)), Rectangle.FromLTRB(x2, y2, x3, y3) ); } return(p); } else if (wms != wmt) { XDebug.Fail(wms + " ≠ " + wmt); } return(pic); }
public void Do1(Stream si) { BinaryReader br = new BinaryReader(si); UInt64 cm; UInt64 r50 = br.ReadUInt64(); cm = br.ReadUInt64(); XDebug.Assert(0x50 == cm, cm.ToString("X16") + " ≠ 0x50"); // 0x50 BITBLTBUF int SBP = ((int)(r50)) & 0x3FFF; int SBW = ((int)(r50 >> 16)) & 0x3F; int SPSM = ((int)(r50 >> 24)) & 0x3F; int DBP = ((int)(r50 >> 32)) & 0x3FFF; int DBW = ((int)(r50 >> 48)) & 0x3F; int DPSM = ((int)(r50 >> 56)) & 0x3F; XTrace.Assert(SBP == 0); XTrace.Assert(SBW == 0); XTrace.Assert(SPSM == 0); XTrace.Assert(DPSM == 0 || DPSM == 19 || DPSM == 20); UInt64 r51 = br.ReadUInt64(); cm = br.ReadUInt64(); XDebug.Assert(0x51 == cm, cm.ToString("X16") + " ≠ 0x51"); // 0x51 TRXPOS int SSAX = ((int)(r51)) & 0x7FF; int SSAY = ((int)(r51 >> 16)) & 0x7FF; int DSAX = ((int)(r51 >> 32)) & 0x7FF; int DSAY = ((int)(r51 >> 48)) & 0x7FF; int DIR = ((int)(r51 >> 59)) & 3; XTrace.Assert(SSAX == 0); XTrace.Assert(SSAY == 0); //! XTrace.Assert(DSAX == 0); //! XTrace.Assert(DSAY == 0); //! XTrace.Assert(DIR == 0); //! UInt64 r52 = br.ReadUInt64(); cm = br.ReadUInt64(); XDebug.Assert(0x52 == cm, cm.ToString("X16") + " ≠ 0x52"); // 0x52 TRXREG int RRW = ((int)(r52 >> 0)) & 0xFFF; int RRH = ((int)(r52 >> 32)) & 0xFFF; UInt64 r53 = br.ReadUInt64(); cm = br.ReadUInt64(); XDebug.Assert(0x53 == cm, cm.ToString("X16") + " ≠ 0x53"); // 0x53 TRXDIR int XDIR = ((int)(r53)) & 2; XTrace.Assert(XDIR == 0); int eop = br.ReadUInt16(); XTrace.Assert(8 != (eop & 0x8000)); si.Position += 18; offBin = br.ReadInt32(); int cbTex = (eop & 0x7FFF) << 4; int MyDBH = cbTex / 8192 / DBW; { byte[] binTmp = new byte[Math.Max(8192, cbTex)]; // decoder needs at least 8kb si.Position = offBin; si.Read(binTmp, 0, cbTex); byte[] binDec; if (DPSM == 0) { binDec = OpenKh.Kh2.Ps2.Encode32(binTmp, DBW, MyDBH); } else if (DPSM == 19) { binDec = OpenKh.Kh2.Ps2.Encode8(binTmp, DBW / 2, cbTex / 8192 / (DBW / 2)); } else if (DPSM == 20) { binDec = OpenKh.Kh2.Ps2.Encode4(binTmp, DBW / 2, cbTex / 8192 / Math.Max(1, DBW / 2)); } else { throw new NotSupportedException("DPSM = " + DPSM + "?"); } Array.Copy(binDec, 0, gs, 256 * DBP, cbTex); } XDebug.WriteLine(string.Format("# p1 {0:x4} {1,6} {2}", DBP, cbTex, DPSM)); }