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 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)); }