Exemplo n.º 1
0
        public static int Play(Stream Stream, Stream OutStream)
        {
            var strt = Stream.ReadString(3);
            Stream.Position = 0;

            ushort bztmp = 0;
            if (strt == "ea3")
            {
                //we get ea3 header
                Console.WriteLine("ea3 header\n");
                Stream.Position = 0x6;
                var tmp = Stream.ReadBytes(4);
                int skipbytes = 0;
                for (int a0 = 0; a0 < 4; a0++)
                {
                    skipbytes <<= 7;
                    skipbytes += tmp[a0] & 0x7F;
                }
                Stream.Skip(skipbytes);
            }

            if (strt == "RIF") //RIFF
            {
                //we get RIFF header
                Console.WriteLine("RIFF header\n");
                Stream.Position = 0x10;
                var fmt_size = Stream.ReadStruct<int>();
                var fmt = Stream.ReadStruct<ushort>();
                if (fmt != 0xFFFE)
                {
                    Console.WriteLine("RIFF File fmt error\n");
                    return -1;
                }
                Stream.Skip(0x28);
                bztmp = Stream.ReadStruct<ushort_be>();
                Stream.Skip(fmt_size - 0x2c);

                //search the data chunk
                for (int a0 = 0; a0 < 0x100; a0++)
                {
                    if (Stream.ReadString(4) == "atad") break;
                }
                int tmpr = Stream.ReadStruct<int>();
            }
            else
            {
                //EA3 block that contains at3+ stream
                Console.WriteLine("EA3 header");
                Stream.Skip(0x22);

                Console.WriteLine("{0:X}", Stream.Position);
                bztmp = (ushort)Stream.ReadStruct<ushort_be>();
                Stream.Skip(0x3c);
            }
            int blocksz = bztmp & 0x3FF;

            var buf0 = new byte[0x3000];
            fixed (byte* buf0_ptr = buf0)
            {
                //calculate the frame block size here
                int block_size = blocksz * 8 + 8;

                Console.WriteLine("frame_block_size 0x{0:X}\n", block_size);

                //Console.ReadKey();

                //so we make a new at3+ frame decoder
                MaiAT3PlusFrameDecoder d2 = new MaiAT3PlusFrameDecoder();

                Stream.Read(buf0, 0, block_size);
                int chns = 0;
                short[] p_buf;
                int rs;
                //decode the first frame and get channel num
                //for (int n = 0; n < block_size; n++) Console.Write(buf0[n]);
                if ((rs = d2.decodeFrame(buf0_ptr, block_size, out chns, out p_buf)) != 0) Console.WriteLine("decode error {0}", rs);
                Console.WriteLine("channels: {0}\n", chns);
                if (chns > 2) Console.WriteLine("warning: waveout doesn't support {0} chns\n", chns);

                //just waveout
                //MaiWaveOutI *mwo0 = new MaiWaveOutI(chns, 44100, 16);

                //mwo0.play();
                while (!Stream.Eof())
                {
                    Stream.Read(buf0, 0, block_size);

                    //decode frame and get sample data
                    if ((rs = d2.decodeFrame(buf0_ptr, block_size, out chns, out p_buf)) != 0) Console.WriteLine("decode error {0}", rs);
                    //play it

                    OutStream.WriteStructVector(p_buf, 0x800 * chns);

                    //mwo0.enqueue((Mai_I8*)p_buf, 0x800 * chns * 2);
                }

                //while (mwo0.getRemainBufSize()) Mai_Sleep(1);
                return 0;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// ReadMld0.
        /// </summary>
        private static NsbmdModel[] ReadMdl0(Stream stream, int blockoffset)
        {
            var reader = new EndianBinaryReader(stream, Endianness.LittleEndian);

            int blocksize;
            int blockptr;
            int blocklimit;
            byte num;
            uint r;
            List<NsbmdModel> model = new List<NsbmdModel>();

            ////////////////////////////////////////////////
            // model
            blockptr = blockoffset + 4; // already read the ID, skip 4 bytes
            blocksize = reader.ReadInt32(); // block size
            blocklimit = blocksize + blockoffset;

            stream.Skip(1); // skip dummy '0'
            num = reader.ReadByte(); // no of model
            if (num <= 0)
                throw new Exception();
            for (var i = 0; i < num; ++i)
                model.Add(new NsbmdModel());
            var modelOffset = new UInt32[num];

            stream.Skip(10 + 4 + (num * 4)); // skip [char xyz], useless, go straight to model data offset
            blockptr += 10 + 4;

            ////////////////////////////////////////////////
            // copy model dataoffset
            for (var i = 0; i < num; i++)
                modelOffset[i] = (uint)(reader.ReadUInt32() + blockoffset);

            ////////////////////////////////////////////////
            // copy model names
            for (var i = 0; i < num; i++)
                model[i].Name = Utils.ReadNSBMDString(reader);

            ////////////////////////////////////////////////
            // parse model data

            uint totalsize_base = reader.ReadUInt32();
            uint codeoffset_base = reader.ReadUInt32();
            uint texpaloffset_base = reader.ReadUInt32();
            uint polyoffset_base = reader.ReadUInt32();
            uint polyend_base = reader.ReadUInt32();
            stream.Skip(4);
            uint matnum = reader.ReadByte(); // no. of material
            uint polynum = reader.ReadByte(); // no. of polygon
            byte laststack = reader.ReadByte();
            byte unknown1m = reader.ReadByte();
            float modelscale = (float)reader.ReadInt32() / 4096f;
            float boundscale = (float)reader.ReadInt32();// / 4096f;
            int vertexcount = reader.ReadInt16();
            int surfacecount = reader.ReadInt16();
            int trianglecount = reader.ReadInt16();
            int quadcount = reader.ReadInt16();

            model[0].laststackid = laststack;
            model[0].modelScale = modelscale;
            model[0].boundScale = boundscale;
            model[0].boundXmin = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;
            model[0].boundYmin = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;
            model[0].boundZmin = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;
            model[0].boundXmax = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;
            model[0].boundYmax = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;
            model[0].boundZmax = (float)NsbmdGlRenderer.sign(reader.ReadInt16(), 16) / 4096f;

            var polyOffsets = new UInt32[polynum];
            var polyDataSize = new UInt32[polynum];

            for (var i = 0; i < 1; i++)
            {
                var mod = model[i];

                stream.Seek(modelOffset[i], SeekOrigin.Begin);

                // the following variables are all offset values
                long totalsize;
                uint codeoffset;
                UInt32 texpaloffset;
                UInt32 polyoffset;
                long polyend;

                long texoffset;
                long paloffset;

                uint modoffset = modelOffset[i];
                totalsize = totalsize_base + modoffset;
                codeoffset = codeoffset_base + modoffset;
                // additional model data, bone definition etc., just follow NsbmdObject section
                texpaloffset = texpaloffset_base + modoffset;
                polyoffset = polyoffset_base + modoffset;
                polyend = polyend_base + modoffset;

                stream.Skip(5 * 4 + 4 + 2 + 38); // go straight to NsbmdObject

                ////////////////////////////////////////////////
                // NsbmdObject section
                UInt32 objnum;
                int objdatabase;
                UInt32[] objdataoffset;
                UInt32[] objdatasize;
                objdatabase = (int)stream.Position;
                stream.Skip(1); // skip dummy '0'
                objnum = reader.ReadByte(); // no of NsbmdObject

                stream.Skip(14 + (objnum * 4)); // skip bytes, go striaght to NsbmdObject data offset

                for (i = 0; i < objnum; ++i)
                    mod.Objects.Add(new NsbmdObject());

                objdataoffset = new UInt32[objnum];
                objdatasize = new UInt32[objnum];

                for (var j = 0; j < objnum; j++)
                    objdataoffset[j] = (UInt32)(reader.ReadUInt32() + objdatabase);

                for (var j = 0; j < objnum - 1; j++)
                    objdatasize[j] = objdataoffset[j + 1] - objdataoffset[j];
                objdatasize[objnum - 1] = (UInt32)(codeoffset - objdataoffset[objnum - 1]);

                ////////////////////////////////////////////////
                // copy NsbmdObject names
                for (var j = 0; j < objnum; j++)
                {
                    mod.Objects[j].Name = Utils.ReadNSBMDString(reader);
                    // TO DEBUG
                    Console.WriteLine(mod.Objects[j].Name);
                }

                ////////////////////////////////////////////////
                // parse NsbmdObject information
                for (var j = 0; j < objnum; j++)
                {
                    if (objdatasize[j] <= 4)
                        continue;

                    stream.Seek(objdataoffset[j], SeekOrigin.Begin);
                    ParseNsbmdObject(reader, mod.Objects[j], modelscale);
                }

                ////////////////////////////////////////////////
                // material section
                stream.Seek(texpaloffset, SeekOrigin.Begin); // now get the texture and palette offset
                texoffset = reader.ReadUInt16() + texpaloffset;
                paloffset = reader.ReadUInt16() + texpaloffset;

                // allocate memory for material
                for (var j = 0; j <= matnum; j++)//i <= matnum; ++i)
                    mod.Materials.Add(new NsbmdMaterial());

                ////////////////////////////////////////////////
                // parse material definition
                // defines RotA material by pairing texture and palette
                stream.Seek(16 + (matnum * 4), SeekOrigin.Current); // go straight to material data offset
                for (var j = 0; j < matnum; j++) // TODO: BAD!
                {
                    mod.Materials[j] = new NsbmdMaterial();
                    blockptr = (int)stream.Position;
                    r = reader.ReadUInt32() + texpaloffset/* + 4 + 12*/;// skip 18 bytes (+ 2 bytes for texoffset, 2 bytes for paloffset)
                    stream.Seek(r, SeekOrigin.Begin);
                    //mod.Materials[j].repeat = reader.ReadByte();
                    //reader.BaseStream.Position -= 1;
                    int dummy = reader.ReadInt16();
                    int sectionSize = reader.ReadInt16();
                    int unknown1 = reader.ReadInt32();//DifAmbColors
                    int unknown2 = reader.ReadInt32();//SpeEmiColors
                    int unknown3 = reader.ReadInt32();//PolyAttrib
                    int constant2 = reader.ReadInt32();//PolyAttrib Mask
                    int texVramOffset = reader.ReadInt16();
                    int texImageParam = reader.ReadInt16();
                    int constant3 = reader.ReadInt32();//texImageParam Mask
                    int constant4 = reader.ReadInt32();
                    int matWidth = reader.ReadInt16();
                    int matHeight = reader.ReadInt16();
                    int unknown4 = reader.ReadInt16();
                    int unknown5 = reader.ReadInt16();
                    int unknown6 = reader.ReadInt32();
                    //int unknown7 = reader.ReadInt32();//if srt S Scale
                    //int unknown8 = reader.ReadInt32();//if srt T Scale
                    //int unknown9 = reader.ReadInt16();//if srt & 60 Rot
                    //int unknownA = reader.ReadInt16();//if srt & 60 S Trans
                    //int unknownB = reader.ReadInt16();//if srt & 60 T Trans

                    //uint polyParam = reader.ReadUInt32();
                    //reader.ReadInt16();
                    //ushort texImageParam = reader.ReadUInt16();
                    mod.Materials[j].repeatS = texImageParam & 1;
                    mod.Materials[j].repeatT = texImageParam >> 1 & 1;
                    mod.Materials[j].flipS = texImageParam >> 2 & 1;
                    mod.Materials[j].flipT = texImageParam >> 3 & 1;
                    /*if ((texImageParam >> 14 & 0x03) == 1)
                    {
                        mod.Materials[j].scaleS = /*1 << /(texImageParam >> 12 & 2) + 1;
                        mod.Materials[j].scaleT = /*1 << /(texImageParam >> 14 & 2) + 1;
                    }
                    else
                    {
                        mod.Materials[j].scaleS = 1;
                        mod.Materials[j].scaleT = 1;
                    }*/
                    switch (texImageParam >> 14 & 0x03)
                    {
                        case 0:
                            mod.Materials[j].scaleS = 1;
                            mod.Materials[j].scaleT = 1;
                            mod.Materials[j].transS = 0;
                            mod.Materials[j].transT = 0;
                            break;

                        case 1:
                            {
                                int sscale = (int)reader.ReadInt32();// >> 0 & 0xFFFFFFFF;
                                sscale = NsbmdGlRenderer.sign(sscale, 32);
                                int tscale = (int)reader.ReadInt32();// >> 0 & 0xFFFFFFFF;
                                tscale = NsbmdGlRenderer.sign(tscale, 32);
                                //int strans = (int)unknown2 >> 0 & 0xFFFF;
                                //int ttrans = (int)unknown2 >> 16 & 0xFFFF;

                                mod.Materials[j].scaleS = (float)sscale / 4096f;
                                mod.Materials[j].scaleT = (float)tscale / 4096f;
                                if (sectionSize >= 60)
                                {
                                    mod.Materials[j].rot = (float)reader.ReadInt16() / 4096f;
                                    mod.Materials[j].transS = (float)reader.ReadInt16() / 4096f;
                                    mod.Materials[j].transT = (float)reader.ReadInt16() / 4096f;
                                }
                                else
                                {

                                }
                                break;
                            }
                        case 2:
                        case 3:
                            mod.Materials[j].mtx = new float[16];
                            for (int k = 0; k < 16; k++)
                            {
                                mod.Materials[j].mtx[k] = reader.ReadInt32();
                            }
                            break;

                        default:
                            break;
                        // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30));
                    }
                    mod.Materials[j].width = matWidth;
                    mod.Materials[j].height = matHeight;
                    int width = 8 << (texImageParam >> 4 & 7);
                    int height = 8 << (texImageParam >> 7 & 7);
                    //int m_DifAmbColors = reader.ReadInt32();
                    //int m_SpeEmiColors = reader.ReadInt32();
                    mod.Materials[j].DiffuseColor = SM64DSe.Helper.BGR15ToColor((ushort)(unknown1 & 0x7FFF));
                    mod.Materials[j].AmbientColor = SM64DSe.Helper.BGR15ToColor((ushort)(unknown1 >> 16 & 0x7FFF));
                    mod.Materials[j].SpecularColor = SM64DSe.Helper.BGR15ToColor((ushort)(unknown2 & 0x7FFF));
                    mod.Materials[j].EmissionColor = SM64DSe.Helper.BGR15ToColor((ushort)(unknown2 >> 16 & 0x7FFF));
                    int a = (int)((unknown3 >> 16) & 31);
                    mod.Materials[j].Alpha = a;//a * 2 + 1;//a * 2 + (a + 31) / 32;
                    mod.Materials[j].PolyAttrib = (uint)unknown3;
                    mod.Materials[j].diffuseColor = (unknown1 >> 15 & 1) == 1;
                    mod.Materials[j].shine = (unknown2 >> 15 & 1) == 1;
                    stream.Seek(blockptr + 4, SeekOrigin.Begin);
                }
                for (var j = 0; j < matnum; j++)
                {
                    mod.Materials[j].MaterialName = Utils.ReadNSBMDString(reader);
                }

                ////////////////////////////////////////////////
                // now go to read the texture definition
                stream.Seek(texoffset, SeekOrigin.Begin);
                stream.Skip(1); // skip dummy '0'
                int texnum = reader.ReadByte();
                Debug.Assert(texnum <= matnum);
                Console.WriteLine(String.Format("texnum: {0}", texnum));

                if (texnum > 0)
                {
                    stream.Seek(14 + (texnum * 4), SeekOrigin.Current); // go straight to data offsets
                    for (var j = 0; j < texnum; j++)
                    {
                        Int32 flags = reader.ReadInt32();
                        int numPairs = flags >> 16 & 0xf;
                        int dummy = flags >> 24 & 0xf;
                        blockptr = (int)stream.Position;
                        stream.Seek((flags & 0xffff) + texpaloffset, SeekOrigin.Begin);
                        NSBMDTexture t = new NSBMDTexture();
                        for (int k = 0; k < numPairs; k++)
                        {
                            uint texmatid = reader.ReadByte();
                            mod.tex_mat.Add((int)texmatid);
                            mod.Materials[j].texmatid.Add(texmatid);
                            t.texmatid.Add(texmatid);
                        }
                        mod.Textures.Add(t);
                        stream.Seek(blockptr, SeekOrigin.Begin);
                    }

                    for (var j = 0; j < texnum; j++) // copy texture names
                    {
                        NsbmdMaterial mat = mod.Materials[j];

                        mat.texname = Utils.ReadNSBMDString(reader);
                        reader.BaseStream.Position -= 16;
                        mod.Textures[j].texname = Utils.ReadNSBMDString(reader);

                        Console.WriteLine("tex (matid={0}): {1}", mat.texmatid, mat.texname);
                    }
                }

                ////////////////////////////////////////////////
                // now go to read the palette definition
                stream.Seek(paloffset, SeekOrigin.Begin);
                stream.Skip(1); // skip dummy '0'
                int palnum = reader.ReadByte(); // no of palette definition
                Debug.Assert(palnum <= matnum); // may not always hold?
                Console.WriteLine("DEBUG: palnum = {0}", palnum);

                if (palnum > 0)
                {
                    stream.Seek(14 + (palnum * 4), SeekOrigin.Current); // go straight to data offsets
                    for (var j = 0; j < palnum; j++) // matching palette with material
                    {
                        Int32 flags = reader.ReadInt32();
                        int numPairs = flags >> 16 & 0xf;
                        int dummy = flags >> 24 & 0xf;
                        blockptr = (int)stream.Position;
                        stream.Seek((flags & 0xffff) + texpaloffset, SeekOrigin.Begin);
                        NSBMDPalette t = new NSBMDPalette();
                        for (int k = 0; k < numPairs; k++)
                        {
                            uint texmatid = reader.ReadByte();
                            mod.tex_mat.Add((int)texmatid);
                            mod.Materials[j].texmatid.Add(texmatid);
                            t.palmatid.Add(texmatid);
                        }
                        mod.Palettes.Add(t);
                        stream.Seek(blockptr, SeekOrigin.Begin);
                    }
                    for (var j = 0; j < palnum; j++) // copy palette names
                    {
                        int palmatid = (int)mod.Materials[j].palmatid;
                        mod.Materials[palmatid].palname = Utils.ReadNSBMDString(reader);
                        reader.BaseStream.Position -= 16;
                        mod.Palettes[j].palname = Utils.ReadNSBMDString(reader);
                        // TO DEBUG
                        Console.WriteLine("pal (matid={0}): {1}", palmatid, mod.Materials[palmatid].palname);
                    }
                }
                ////////////////////////////////////////////////
                // Polygon
                stream.Seek(polyoffset, SeekOrigin.Begin);
                stream.Skip(1); // skip dummy '0'
                r = reader.ReadByte(); // no of polygon
                Console.WriteLine("DEBUG: polynum = {0}", polynum);

                for (var j = 0; j <= polynum; j++)
                {
                    mod.Polygons.Add(new NsbmdPolygon());
                }

                stream.Skip(14 + (polynum * 4)); // skip bytes, go straight to data offset

                for (var j = 0; j < polynum; j++)
                    polyOffsets[j] = reader.ReadUInt32() + polyoffset;
                try
                {
                    for (var j = 0; j < polynum; j++) // copy polygon names
                    {
                        mod.Polygons[j].Name = Utils.ReadNSBMDString(reader);
                        Console.WriteLine(mod.Polygons[j].Name);
                    }
                }
                catch { }
                ////////////////////////////////////////////////
                // now go to the polygon data, there is RotA 16-byte-header before geometry commands
                for (var j = 0; j < polynum; j++)
                {
                    var poly = mod.Polygons[j];
                    //////////////////////////////////////////////////////////
                    poly.MatId = -1; // DEFAULT: indicate no associated material
                    //////////////////////////////////////////////////////////
                    //stream.Seek(polyOffsets[j] + 8, SeekOrigin.Begin); // skip 8 unknown bytes
                    short dummy = reader.ReadInt16();
                    short headerSize = reader.ReadInt16();
                    int unknown2 = reader.ReadInt32();
                    polyOffsets[j] += reader.ReadUInt32();
                    polyDataSize[j] = reader.ReadUInt32();
                    //printf( "poly %2d '%-16s': dataoffset: %08x datasize %08x\n", j, poly->polyname, poly->dataoffset, poly->datasize );
                }
                //}

                ////////////////////////////////////////////////
                // read the polygon data into memory
                for (var j = 0; j < polynum; j++)
                {
                    var poly = mod.Polygons[j];
                    stream.Seek(polyOffsets[j], SeekOrigin.Begin);
                    poly.PolyData = reader.ReadBytes((int)polyDataSize[j]);
                }
                //}

                ////////////////////////////////////////////////
                // decode the additional model data
                DecodeCode(stream, codeoffset, texpaloffset, mod, laststack);
            }

            //modelnum = num;
            return model.ToArray();
        }
        /// <summary>
        /// ID3v2.3/2.4 タグから画像データの Stream を取り出します
        /// </summary>
        private Stream _ReadPictureInFrameHeaders(Stream file)
        {
            var count = 1;

            while (true)
            {
                // Frame Name
                var frameName = file.ReadAsAsciiString(4);

                // 有効な Frame Name であるかどうかを示す
                var validName = Regex.IsMatch(frameName, "^[A-Z0-9]+$");

                // 無効な Frame Name であれば、ループ終了
                if (!validName)
                {
                    break;
                }

                Debug.WriteLine($"frameName = {frameName}");
                var frameSize = file.ReadAsUInt();

                // フラグ読み飛ばし
                file.Skip(2);

                // APIC Frame の判定
                if (frameName == "APIC")
                {
                    var removeCount = 0;

                    file.Skip(1);
                    removeCount += 1;

                    while (file.ReadAsByte() != 0x00U)
                    {
                        removeCount++;
                    }

                    file.Skip(1);
                    removeCount += 1;

                    while (file.ReadAsByte() != 0x00U)
                    {
                        removeCount++;
                    }

                    var imageSource = file.ReadAsByteList((int)frameSize - removeCount);

                    return(new MemoryStream(imageSource.ToArray()));
                }

                // PIC Frame でないため、フレーム自体を読み飛ばす
                file.Skip((int)frameSize);

                if (count > 74)
                {
                    throw new InvalidDataException("フレーム数が正常な範囲を超えました");
                }

                count++;
            }

            return(null);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable <NsbmdMaterial> ReadTex0(Stream stream, int blockoffset, out int ptexnum, out int ppalnum, out List <NSBMDTexture> texs, out List <NSBMDPalette> pals)
        {
            EndianBinaryReader reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
            UInt32             blocksize, blockptr, blocklimit;
            int    texnum;
            UInt32 texdataoffset;
            int    texdatasize;
            UInt32 sptexoffset;  // for 4x4 compressed texels only
            int    sptexsize;    // for 4x4 compressed texels only
            UInt32 spdataoffset; // for 4x4 compressed texels only
            int    palnum;
            UInt32 paldefoffset;
            UInt32 paldataoffset;
            int    paldatasize;

            NsbmdMaterial[] material = null;
            int             i, j;

            texs = new List <NSBMDTexture>();
            pals = new List <NSBMDPalette>();

            blockptr   = (uint)(blockoffset + 4); // already read the block ID, so skip 4 bytes
            blocksize  = reader.ReadUInt32();     // block size
            blocklimit = (uint)(blocksize + blockoffset);
            Console.WriteLine("DEBUG: blockoffset = {0}, blocksize = {1}", blockoffset, blocksize);

            stream.Skip(4);                         // skip 4 padding 0s
            texdatasize = reader.ReadUInt16() << 3; // total texture data size div8
            stream.Skip(6);                         // skip 6 bytes
            texdataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            stream.Skip(4);                                           // skip 4 padding 0s
            sptexsize = reader.ReadUInt16() << 3;                     // for format 5 4x4-texel, data size div8
            stream.Skip(6);                                           // skip 6 bytesmhm
            sptexoffset  = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, data offset
            spdataoffset = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, palette info

            stream.Skip(4);                                           // skip 4 bytes
            paldatasize = reader.ReadUInt16() << 3;                   // total palette data size div8
            stream.Skip(2);                                           // skip 2 bytes
            paldefoffset  = (uint)(reader.ReadUInt32() + blockoffset);
            paldataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            //	printf( "texdataoffset = %08x texdatasize = %08x\n", texdataoffset, texdatasize );
            //	printf( "sptexoffset = %08x sptexsize = %08x spdataoffset = %08x\n", sptexoffset, sptexsize, spdataoffset );
            //	printf( "paldataoffset = %08x paldatasize = %08x\n", paldataoffset, paldatasize );

            ////////////////////////////////////////////////
            // texture definition

            stream.Skip(1);               // skip dummy '0'
            texnum   = reader.ReadByte(); // no of texture
            blockptr = (uint)stream.Position;
            stream.Seek(paldefoffset, SeekOrigin.Begin);
            stream.Skip(1);             // skip dummy '0'
            palnum = reader.ReadByte(); // no of palette
            stream.Seek(blockptr, SeekOrigin.Begin);

            Console.WriteLine("texnum = {0}, palnum = {1}", texnum, palnum);

            // allocate memory for material, great enough to hold all texture and palette
            material = new NsbmdMaterial[(texnum > palnum ? texnum : palnum)];
            for (i = 0; i < material.Length; i++)
            {
                material[i] = new NsbmdMaterial();
            }


            stream.Skip(14 + (texnum * 4)); // go straight to texture info

            for (i = 0; i < texnum; i++)
            {
                UInt32 offset;
                int    param;
                int    format;
                int    width;
                int    height;

                var mat = material[i];

                offset = (uint)(reader.ReadUInt16() << 3);
                param  = reader.ReadUInt16();   // texture parameter
                stream.Skip(4);                 // skip 4 bytes

                format     = (param >> 10) & 7; // format 0..7, see DSTek
                width      = 8 << ((param >> 4) & 7);
                height     = 8 << ((param >> 7) & 7);
                mat.color0 = (param >> 13) & 1;

                if (format == 5)
                {
                    mat.texoffset = offset + sptexoffset; // 4x4-Texel Compressed Texture
                }
                else
                {
                    mat.texoffset = offset + texdataoffset;
                }

                mat.format = format;
                mat.width  = width;
                mat.height = height;
                NSBMDTexture t = new NSBMDTexture();
                t.format = format;
                t.width  = width;
                t.height = height;
                t.color0 = (param >> 13) & 1;
                texs.Add(t);
            }

            ////////////////////////////////////////////
            // copy texture names
            for (i = 0; i < texnum; i++)
            {
                material[i].texname         = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                texs[i].texname             = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each texture's size
            for (i = 0; i < texnum; i++)
            {
                int[] bpp = { 0, 8, 2, 4, 8, 2, 8, 16 };

                var mat = material[i];
                mat.texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
                Console.WriteLine("tex {0} '{1}': offset = {2} size = {3} [W,H] = [{4}, {5}]",
                                  i, mat.texname, mat.texoffset, mat.texsize, mat.width, mat.height);
                texs[i].texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
            }

            ////////////////////////////////////////////////
            // palette definition
            stream.Seek(paldefoffset + 2, SeekOrigin.Begin);    // skip palnum, already read
            stream.Seek(14 + (palnum * 4), SeekOrigin.Current); // go straight to palette info
            for (i = 0; i < palnum; i++)
            {
                uint curOffset = (uint)((reader.ReadUInt16() << 3) + paldataoffset);
                stream.Seek(2, SeekOrigin.Current); // skip 2 bytes
                material[i].paloffset = curOffset;
                NSBMDPalette t = new NSBMDPalette();
                t.paloffset = curOffset;
                pals.Add(t);
            }

            ////////////////////////////////////////////////
            // copy palette names
            for (i = 0; i < palnum; i++)
            {
                var mat = material[i];
                mat.palname = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                pals[i].palname             = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each palette's size
            // assume the palettes are stored sequentially

            /*for (i = 0; i < palnum - 1; i++)
             * {
             *  int r;
             *  var mat = material[i];
             *  r = i;
             *  try { while (material[r].paloffset == mat.paloffset) r++; }
             *  catch { }
             *  // below is RotA stupid way to calculate the size of palette: next's offset - current's offset
             *  // it works most of the time
             *  if (r != palnum)
             *  {
             *      mat.palsize = material[r].paloffset - mat.paloffset;
             *      pals[i].palsize = material[r].paloffset - mat.paloffset;
             *  }
             *  else
             *  {
             *      mat.palsize = blocklimit - mat.paloffset;
             *      pals[i].palsize = blocklimit - mat.paloffset;
             *  }
             *  //printf("pal '%s' size = %d\n", mat->palname, mat->palsize);
             * }
             * material[i].palsize = blocklimit - material[i].paloffset;
             * pals[i].palsize = blocklimit - material[i].paloffset;*/
            List <int> offsets = new List <int>();

            for (int k = 0; k < pals.Count; k++)
            {
                if (!offsets.Contains((int)pals[k].paloffset))
                {
                    offsets.Add((int)pals[k].paloffset);
                }
            }
            offsets.Add((int)blocklimit);
            offsets.Sort();
            for (int k = 0; k < pals.Count; k++)
            {
                int pallength;
                int l = -1;
                do
                {
                    l++;
                }while (offsets[l] - pals[k].paloffset <= 0);//nsbtx.PalInfo.infoBlock.PalInfo[i + j].Palette_Offset - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset == 0)
                pallength = offsets[l] - (int)pals[k].paloffset;
                //RGBA[] c_ = pals[k].paldata;
                //List<RGBA> c = new List<RGBA>();
                //c.AddRange(pals[k].paldata.Take(pallength / 2));
                //pals[k].paldata = c.ToArray();
                pals[k].palsize     = (uint)pallength;
                material[k].palsize = (uint)pallength;
            }

            ////////////////////////////////////////////////
            // traverse each texture
            for (i = 0; i < texnum; i++)
            {
                var mat = material[i];
                stream.Seek(mat.texoffset, SeekOrigin.Begin);

                ////////////////////////////////////////////////
                // read texture into memory
                byte[] by = reader.ReadBytes((int)mat.texsize);
                mat.texdata     = by;
                texs[i].texdata = by;

                Console.WriteLine("DEBUG: texoffset = {0}, texsize = {1}", mat.texoffset, mat.texsize);

                ////////////////////////////////////////////////
                // additional data for format 5 4x4 compressed texels
                if (mat.format == 5)
                {
                    UInt32 r = mat.texsize / 2;//>> 1;
                    stream.Seek(spdataoffset + (mat.texoffset - sptexoffset) / 2, SeekOrigin.Begin);

                    by             = reader.ReadBytes((int)r);
                    mat.spdata     = by;
                    texs[i].spdata = by;
                    Console.WriteLine("DEBUG: 4x4-texel spdataoffset = {0}, spdatasize = {1}", spdataoffset, r);

                    //spdataoffset += r;
                }
            }


            ////////////////////////////////////////////////
            // traverse each palette
            for (i = 0; i < palnum; i++)
            {
                try
                {
                    NsbmdMaterial mat      = material[i];
                    var           palentry = mat.palsize >> 1;

                    RGBA[] rgbq = new RGBA[palentry];

                    Console.WriteLine("DEBUG: converting pal '{0}', palentry = {1}", mat.palname, palentry);

                    stream.Seek(mat.paloffset, SeekOrigin.Begin);
                    for (j = 0; j < palentry; j++)
                    {
                        UInt16 p = reader.ReadUInt16();
                        rgbq[j].R = (byte)(((p >> 0) & 0x1f) << 3);           // red
                        rgbq[j].G = (byte)(((p >> 5) & 0x1f) << 3);           // green
                        rgbq[j].B = (byte)(((p >> 10) & 0x1f) << 3);          // blue
                        //rgbq[j].RotA = (p&0x8000) ? 0xff : 0;
                        rgbq[j].A = (p & 0x8000) == 0 ? (byte)0xff : (byte)0; //0xff; // alpha
                    }
                    mat.paldata     = rgbq;
                    pals[i].paldata = rgbq;
                }
                catch
                {
                }
            }

            ptexnum = texnum;
            ppalnum = palnum;

            return(material);
        }
Exemplo n.º 5
0
 public static Stream SkipStringUnicode(this Stream stream)
 {
     stream.Skip(stream.ReadInt32() * -2);
     return(stream);
 }
Exemplo n.º 6
0
 /// <summary>
 ///  Skips <paramref name="count"/> number of bytes in the stream.
 /// </summary>
 /// <param name="stream">The stream to skip through.</param>
 /// <param name="count">The number of bytes to skip.</param>
 /// <returns>The number of bytes, actually skipped.</returns>
 ///
 /// <remarks>
 ///  This method utilizes <see cref="Stream.Seek(long, SeekOrigin)"/> if it's <see cref="Stream.CanSeek"/> is
 ///  true. Otherwise it reads bytes to a buffer of size 4096 until <paramref name="count"/> is reached.
 /// </remarks>
 ///
 /// <exception cref="ArgumentNullException">
 ///  <paramref name="stream"/> is null.
 /// </exception>
 /// <exception cref="ArgumentOutOfRangeException">
 ///  <paramref name="count"/> is negative.
 /// </exception>
 /// <exception cref="IOException">
 ///  An I/O error occurred.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///  The stream does not support seeking or reading.
 /// </exception>
 /// <exception cref="ObjectDisposedException">
 ///  The stream is closed.
 /// </exception>
 public static int Skip(this Stream stream, int count)
 {
     return(stream.Skip(count, 4096));
 }
Exemplo n.º 7
0
 private static bool Whitespace(Stream data)
 {
     return(data.Skip(" \t\r\n") > 0);
 }
Exemplo n.º 8
0
        public override void Write(Stream output, IDirectory inputDirectory)
        {
            const uint xorMask1 = 0x41441043;
            const uint xorMask2 = 0x11C22050;
            const uint xorMask3 = 0xD05608C3;
            const uint xorMask4 = 0x532C7319;
            const int headerSize = 32;
            int shift = (Flags & 0x800) > 0 ? 12 : 10;
            int alignment = 1 << shift;

            BinaryWriter writer = new BinaryWriter(output, Encoding.Default, true);
            long headerPosition = output.Position;
            output.Skip(headerSize);
            long tableOffset = output.Position;
            output.Skip(8 * Entries.Count);
            //long unknownTableOffset = output.Position;
            //output.Skip(16 * UnknownEntries.Count);

            output.AlignWrite(alignment, 0x00);
            long dataOffset = output.Position;
            ulong[] sections = new ulong[Entries.Count];
            for (int i = 0; i < Entries.Count; i++)
            {
                QarEntry entry = Entries[i];
                entry.CalculateHash();
                ulong section = (ulong) (output.Position >> shift) << 40
                                | (entry.Hash & 0xFF) << 32
                                | entry.Hash >> 32 & 0xFFFFFFFFFF;
                sections[i] = section;
                entry.Write(output, inputDirectory);
                output.AlignWrite(alignment, 0x00);
            }
            long endPosition = output.Position;
            uint endPositionHead = (uint) (endPosition >> shift);

            output.Position = headerPosition;
            writer.Write(QarMagicNumber); // SQAR
            writer.Write(Flags ^ xorMask1);
            writer.Write((uint)Entries.Count ^ xorMask2);
            writer.Write(xorMask3); // unknown count (not saved in the xml and output directory)
            writer.Write(endPositionHead ^ xorMask4);
            writer.Write((uint)dataOffset ^ xorMask1);
            writer.Write(1 ^ xorMask1);
            writer.Write(0 ^ xorMask2);

            output.Position = tableOffset;
            byte[] encryptedSectionsData = EncryptSections(sections);
            writer.Write(encryptedSectionsData);

            output.Position = endPosition;
        }
Exemplo n.º 9
0
        static void ParseFileList(Stream decompressedStream, long dataStreamLength)
        {
            var binaryReader = new BinaryReader(decompressedStream);
            var fileNumber   = binaryReader.ReadUInt16();

            filesInfos = new List <FileInfo>();
            decompressedStream.Skip(2);             // Unknown. Maybe fileNumber is 4 bytes?
            Bio.Cout("\n" + fileNumber + " files in installer\n");

            installerVersion = GetInstallerVersion(decompressedStream, binaryReader, fileNumber, dataStreamLength);
            Func <Stream, BinaryReader, FileInfo> parsingFunction = TryParse30;

            if (installerVersion >= 40)
            {
                parsingFunction = TryParse40;
            }
            else if (installerVersion >= 35)
            {
                parsingFunction = TryParse35;
            }
            else if (installerVersion >= 30)
            {
                parsingFunction = TryParse30;
            }
            else if (installerVersion >= 20)
            {
                parsingFunction = TryParse20;
            }
            else
            {
                Bio.Error($"Unsupported installer version {installerVersion}. Please send a bug report if you want the file to be supported in a future version.", Bio.EXITCODE.NOT_SUPPORTED);
            }

            Bio.Cout($"\nStarting extraction as installer version {installerVersion}\n");
            for (var i = 0; i < fileNumber; i++)
            {
                var fileInfo = parsingFunction(decompressedStream, binaryReader);
                Bio.Debug(string.Format("Node {0} at offset {1}, size: {2}, end: {3}", i, fileInfo.nodeStart, fileInfo.nodeSize, fileInfo.nodeEnd));

                if (!fileInfo.IsValid(dataStreamLength))
                {
                    Bio.Error($"The file could not be extracted as installer version {installerVersion}. Please try to manually set the correct version using the command line switch -v.", Bio.EXITCODE.RUNTIME_ERROR);
                }

#if DEBUG
                if (dumpBlocks)
                {
                    using (var ms = new MemoryStream((int)fileInfo.nodeSize)) {
                        decompressedStream.Position = fileInfo.nodeStart;
                        decompressedStream.Copy(ms, (int)fileInfo.nodeSize);
                        decompressedStream.Position = fileInfo.nodeEnd;
                        SaveToFile(ms, "FileMeta" + i + ".bin");
                    }
                }
#endif

                if (fileInfo.type != 0)
                {
                    decompressedStream.Position = fileInfo.nodeEnd;
                    continue;
                }

                filesInfos.Add(fileInfo);
                Bio.Debug(fileInfo);
            }
        }
Exemplo n.º 10
0
        private static OperatorType Operator(Stream data)
        {
            OperatorType result = OperatorType.None;

            char c = data.Peek();

            if (c != '=' && c != '*' && c != '/' && c != '+' && c != '-' && c != '!' && c != '?' && c != '<' && c != '>' &&
                c != '|' && c != ':' && c != '~' && c != '%' && c != '&' && c != '^')
            {
                return(result);
            }

            long streamPos = data.Position; data.Get();
            long last      = data.Skip("=+-*/&|^<>");

            if (last > 2)
            {
                last = 2;
            }
            last++;

            data.Position = streamPos;
            string streamBuff = data.Read(last);

            switch (c)
            {
            case ':':
            {
                result = OperatorType.AlternateOperator;
                break;
            }

            case '!':
                // !=
                if (last > 1 && streamBuff == "!=")
                {
                    result = OperatorType.NEqual;
                    break;
                }
                // !
                else
                {
                    result = OperatorType.Not;
                    break;
                }

            case '=':
                if (last > 1 && streamBuff == "==")
                {
                    result = OperatorType.Equal;
                }
                break;

            case '*':
            {
                result = OperatorType.Mult;
                break;
            }

            case '/':
            {
                result = OperatorType.Div;
                break;
            }

            case '+':
                // ++
                if (last > 1 && streamBuff == "++")
                {
                    result = OperatorType.Increment;
                    break;
                }
                // +
                else
                {
                    result = OperatorType.Add;
                    break;
                }

            case '-':
                // --
                if (last > 1 && streamBuff == "--")
                {
                    result = OperatorType.Decrement;
                    break;
                }
                // -
                else
                {
                    result = OperatorType.Sub;
                    break;
                }

            case '%':
            {
                result = OperatorType.Mod;
                break;
            }

            case '&':
                // &&
                if (last > 1 && streamBuff == "&&")
                {
                    result = OperatorType.LogicalAnd;
                    break;
                }
                // &
                else
                {
                    result = OperatorType.BitAnd;
                    break;
                }

            case '|':
                // ||
                if (last > 1 && streamBuff == "||")
                {
                    result = OperatorType.LogicalInclusiveOr;
                    break;
                }
                // |
                else
                {
                    result = OperatorType.BitInclusiveOr;
                    break;
                }

            case '^':
                // ^^
                if (last > 1 && streamBuff == "^^")
                {
                    result = OperatorType.LogicalExclusiveOr;
                    break;
                }
                // ^
                else
                {
                    result = OperatorType.BitExclusiveOr;
                    break;
                }

            case '<':
                // <<
                if (last > 1 && streamBuff == "<<")
                {
                    result = OperatorType.LBitShift;
                    break;
                }
                // <=
                else if (last > 1 && streamBuff == "<=")
                {
                    result = OperatorType.LeftRelationEqual;
                    break;
                }
                // <
                else
                {
                    result = OperatorType.LeftRelation;
                    break;
                }

            case '>':
                // >>
                if (last > 1 && streamBuff == ">>")
                {
                    result = OperatorType.RBitShift;
                    break;
                }
                // >=
                else if (last > 1 && streamBuff == ">=")
                {
                    result = OperatorType.RightRelationEqual;
                    break;
                }
                // >
                else
                {
                    result = OperatorType.RightRelation;
                    break;
                }

            case '~':
            {
                // ~
                result = OperatorType.ReverseOperator;
                break;
            }

            case '?':
            {
                // ?
                result = OperatorType.SelectOperator;
                break;
            }
            }

            data.Position = streamPos;
            return(result);
        }
Exemplo n.º 11
0
 public static bool SimpleWhitespace(Stream data)
 {
     return(data.Skip(" \t\r\n") > 0);
 }
Exemplo n.º 12
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable<NsbmdMaterial> ReadTex0(Stream stream, int blockoffset, out int ptexnum, out int ppalnum)
        {
            BinaryReader reader = new BinaryReader(stream);
            UInt32 blocksize, blockptr, blocklimit;
            int texnum;
            UInt32 texdataoffset;
            int texdatasize;
            UInt32 sptexoffset; // for 4x4 compressed texels only
            int sptexsize; // for 4x4 compressed texels only
            UInt32 spdataoffset; // for 4x4 compressed texels only
            int palnum;
            UInt32 paldefoffset;
            UInt32 paldataoffset;
            int paldatasize;
            NsbmdMaterial[] material = null;
            int i, j;

            blockptr = (uint) (blockoffset + 4); // already read the block ID, so skip 4 bytes
            blocksize = reader.ReadUInt32(); // block size
            blocklimit = (uint) (blocksize + blockoffset);
            Console.WriteLine("DEBUG: blockoffset = {0}, blocksize = {1}", blockoffset, blocksize);

            stream.Skip(4); // skip 4 padding 0s
            texdatasize = reader.ReadUInt16() << 3; // total texture data size div8
            stream.Skip(6); // skip 6 bytes
            texdataoffset = (uint) (reader.ReadUInt32() + blockoffset);

            stream.Skip(4); // skip 4 padding 0s
            sptexsize = reader.ReadUInt16() << 3; // for format 5 4x4-texel, data size div8
            stream.Skip(6); // skip 6 bytesmhm
            sptexoffset = (uint) (reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, data offset
            spdataoffset = (uint) (reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, palette info

            stream.Skip(4); // skip 4 bytes
            paldatasize = reader.ReadUInt16() << 3; // total palette data size div8
            stream.Skip(2); // skip 2 bytes
            paldefoffset = (uint) (reader.ReadUInt32() + blockoffset);
            paldataoffset = (uint) (reader.ReadUInt32() + blockoffset);

            //	printf( "texdataoffset = %08x texdatasize = %08x\n", texdataoffset, texdatasize );
            //	printf( "sptexoffset = %08x sptexsize = %08x spdataoffset = %08x\n", sptexoffset, sptexsize, spdataoffset );
            //	printf( "paldataoffset = %08x paldatasize = %08x\n", paldataoffset, paldatasize );

            ////////////////////////////////////////////////
            // texture definition

            stream.Skip(1); // skip dummy '0'
            texnum = reader.ReadByte(); // no of texture
            blockptr = (uint) stream.Position;
            stream.Seek(paldefoffset, SeekOrigin.Begin);
            stream.Skip(1); // skip dummy '0'
            palnum = reader.ReadByte(); // no of palette
            stream.Seek(blockptr, SeekOrigin.Begin);

            Console.WriteLine("texnum = {0}, palnum = {1}", texnum, palnum);

            // allocate memory for material, great enough to hold all texture and palette
            material = new NsbmdMaterial[(texnum > palnum ? texnum : palnum)];
            for (i = 0; i < material.Length; ++i)
                material[i] = new NsbmdMaterial();

            stream.Skip(14 + (texnum*4)); // go straight to texture info

            for (i = 0; i < texnum; i++)
            {
                UInt32 offset;
                int param;
                int format;
                int width;
                int height;

                var mat = material[i];

                offset = (uint) (reader.ReadUInt16() << 3);
                param = reader.ReadUInt16(); // texture parameter
                stream.Skip(4); // skip 4 bytes

                format = (param >> 10) & 7; // format 0..7, see DSTek
                width = 8 << ((param >> 4) & 7);
                height = 8 << ((param >> 7) & 7);
                mat.color0 = (param >> 13) & 1;

                if (format == 5)
                    mat.texoffset = offset + sptexoffset; // 4x4-Texel Compressed Texture
                else
                    mat.texoffset = offset + texdataoffset;

                mat.format = format;
                mat.width = width;
                mat.height = height;
            }

            ////////////////////////////////////////////
            // copy texture names
            for (i = 0; i < texnum; i++)
            {
                material[i].texname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each texture's size
            for (i = 0; i < texnum; i++)
            {
                int[] bpp = {0, 8, 2, 4, 8, 2, 8, 16};

                var mat = material[i];
                mat.texsize = (uint) (mat.width*mat.height*bpp[mat.format]/8);
                Console.WriteLine("tex {0} '{1}': offset = {2} size = {3} [W,H] = [{4}, {5}]",
                                  i, mat.texname, mat.texoffset, mat.texsize, mat.width, mat.height);
            }

            ////////////////////////////////////////////////
            // palette definition
            stream.Seek(paldefoffset + 2, SeekOrigin.Begin); // skip palnum, already read
            stream.Seek(14 + (palnum*4), SeekOrigin.Current); // go straight to palette info
            for (i = 0; i < palnum; i++)
            {
                uint curOffset = (uint) ((reader.ReadUInt16() << 3) + paldataoffset);
                stream.Seek(2, SeekOrigin.Current); // skip 2 bytes
                material[i].paloffset = curOffset;
            }

            ////////////////////////////////////////////////
            // copy palette names
            for (i = 0; i < palnum; i++)
            {
                var mat = material[i];
                mat.palname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each palette's size
            // assume the palettes are stored sequentially
            for (i = 0; i < palnum - 1; i++)
            {
                var mat = material[i];
                var r = i + 1;
                while (material[r].paloffset == mat.paloffset) r++;
                // below is RotA stupid way to calculate the size of palette: next's offset - current's offset
                // it works most of the time
                if (r != palnum)
                    mat.palsize = material[r].paloffset - mat.paloffset;
                else
                    mat.palsize = blocklimit - mat.paloffset;
                //printf("pal '%s' size = %d\n", mat->palname, mat->palsize);
            }
            material[i].palsize = blocklimit - material[i].paloffset;

            ////////////////////////////////////////////////
            // traverse each texture
            for (i = 0; i < texnum; i++)
            {
                var mat = material[i];
                stream.Seek(mat.texoffset, SeekOrigin.Begin);

                ////////////////////////////////////////////////
                // read texture into memory
                mat.texdata = reader.ReadBytes((int) mat.texsize);

                Console.WriteLine("DEBUG: texoffset = {0}, texsize = {1}", mat.texoffset, mat.texsize);

                ////////////////////////////////////////////////
                // additional data for format 5 4x4 compressed texels
                if (true) //(mat.format == 5)
                {
                    UInt32 r = mat.texsize >> 1;
                    stream.Seek(spdataoffset, SeekOrigin.Begin);

                    mat.spdata = reader.ReadBytes((int) r);

                    Console.WriteLine("DEBUG: 4x4-texel spdataoffset = {0}, spdatasize = {1}", spdataoffset, r);

                    spdataoffset += r;
                }
            }

            ////////////////////////////////////////////////
            // traverse each palette
            for (i = 0; i < palnum; i++)
            {
                try
                {
                    NsbmdMaterial mat = material[i];
                    var palentry = mat.palsize >> 1;

                    RGBA[] rgbq = new RGBA[palentry];

                    Console.WriteLine("DEBUG: converting pal '{0}', palentry = {1}", mat.palname, palentry);

                    stream.Seek(mat.paloffset, SeekOrigin.Begin);
                    for (j = 0; j < palentry; j++)
                    {
                        UInt16 p = reader.ReadUInt16();
                        rgbq[j].R = (byte) (((p >> 0) & 0x1f) << 3); // red
                        rgbq[j].G = (byte) (((p >> 5) & 0x1f) << 3); // green
                        rgbq[j].B = (byte) (((p >> 10) & 0x1f) << 3); // blue
                        //rgbq[j].RotA = (p&0x8000) ? 0xff : 0;
                        rgbq[j].A = 0xff; // alpha
                    }
                    mat.paldata = rgbq;
                }
                catch
                {
                }
            }

            ptexnum = texnum;
            ppalnum = palnum;

            return material;
        }
Exemplo n.º 13
0
 public static Stream SkipStringASCII(this Stream stream)
 {
     stream.Skip(stream.ReadInt32());
     return(stream);
 }
Exemplo n.º 14
0
        /**
         * Reads the LM file header
         *
         * @param stream the data stream of the LM file
         * @throws java.io.IOException
         */
        private void ReadHeader(Stream stream)
        {
            var headerLength = ReadInt(stream, _bigEndian);

            if ((headerLength != DarpaTgHeader.Length + 1) && (headerLength != DarpaQgHeader.Length + 1) && (headerLength != DarpaNgHeader.Length - 1))
            { // not big-endian
                headerLength = Utilities.SwapInteger(headerLength);
                if (headerLength == (DarpaTgHeader.Length + 1) || headerLength == (DarpaQgHeader.Length + 1) || headerLength == (DarpaNgHeader.Length - 1))
                {
                    _bigEndian = false;
                    // System.out.println("Little-endian");
                }
                else
                {
                    throw new Exception("Bad binary LM file magic number: "
                                        + headerLength + ", not an LM dumpfile?");
                }
            }
            else
            {
                // System.out.println("Big-endian");
            }

            // read and verify standard header string
            var header = ReadString(stream, headerLength - 1);

            stream.ReadByte(); // read the '\0'
            _bytesRead++;

            if (!header.Equals(DarpaTgHeader) & !header.Equals(DarpaQgHeader) /*& !Pattern.matches(DARPA_NG_HEADER, header)*/)
            {
                throw new Exception("Bad binary LM file header: " + header);
            }
            else
            {
                if (header.Equals(DarpaTgHeader))
                {
                    MaxDepth = 3;
                }
                else if (header.Equals(DarpaQgHeader))
                {
                    MaxDepth = 4;
                }
                else
                {
                    var p = Pattern.Compile("\\d");
                    var m = p.Matcher(header);
                    //Match m = Regex.Match(header, "\\d");
                    MaxDepth = Convert.ToInt32(m.Group(0), CultureInfo.InvariantCulture.NumberFormat);
                }
            }

            // read LM filename string size and string
            var fileNameLength = ReadInt(stream, _bigEndian);

            SkipStreamBytes(stream, fileNameLength);

            _numberNGrams      = new int[MaxDepth];
            _nGramOffset       = new long[MaxDepth];
            _nGramProbTable    = new float[MaxDepth][];
            _nGramBackoffTable = new float[MaxDepth][];
            _nGramSegmentTable = new int[MaxDepth][];

            _numberNGrams[0]     = 0;
            LogBigramSegmentSize = Log2NgramSegmentSize;

            // read version number, if present. it must be <= 0.

            var version = ReadInt(stream, _bigEndian);

            // System.out.println("Version: " + version);

            BytesPerField = 2;

            if (version <= 0)                // yes, its the version number
            {
                ReadInt(stream, _bigEndian); // read and skip timestamp

                // Means we are going 32 bits.
                if (version <= -3)
                {
                    BytesPerField = 4;
                }

                // read and skip format description
                int formatLength;
                for (; ;)
                {
                    if ((formatLength = ReadInt(stream, _bigEndian)) == 0)
                    {
                        break;
                    }
                    _bytesRead += stream.Skip(formatLength);
                }

                // read log NGram segment size if present
                // only for 16 bits version 2 LM
                if (version == -2)
                {
                    LogBigramSegmentSize = ReadInt(stream, _bigEndian);
                    if (LogBigramSegmentSize < 1 || LogBigramSegmentSize > 15)
                    {
                        throw new Exception("log2(bg_seg_sz) outside range 1..15");
                    }
                }

                _numberNGrams[0] = ReadInt(stream, _bigEndian);
            }
            else
            {
                _numberNGrams[0] = version;
            }

            if (_numberNGrams[0] <= 0)
            {
                throw new Exception("Bad number of unigrams: " + _numberNGrams[0]
                                    + ", must be > 0.");
            }

            for (var i = 1; i < MaxDepth; i++)
            {
                if ((_numberNGrams[i] = ReadInt(stream, _bigEndian)) < 0)
                {
                    throw new Exception("Bad number of " + i + "-grams: " + _numberNGrams[i]);
                }
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Read a list of attributes
        /// </summary>
        private void ReadAttributes(ConstantPool cp, IModifiableAttributeProvider provider)
        {
            var count = stream.ReadU2();

            for (var i = 0; i < count; i++)
            {
                var nameIndex = stream.ReadU2();
                var name      = cp.GetEntry <ConstantPoolUtf8>(nameIndex).Value;
                var length    = stream.ReadU4();

                Attribute attr;
                int       tmp;
                switch (name)
                {
                case CodeAttribute.AttributeName:
                    attr = ReadCodeAttribute((MethodDefinition)provider, cp);
                    break;

                case ConstantValueAttribute.AttributeName:
                    tmp  = stream.ReadU2();
                    attr = new ConstantValueAttribute(((IConstantPoolValue)cp[tmp]).Value);
                    break;

                case ExceptionsAttribute.AttributeName:
                    attr = ReadExceptionsAttribute(cp);
                    break;

                case InnerClassesAttribute.AttributeName:
                    attr = ReadInnerClassesAttribute(cp);
                    break;

                case SyntheticAttribute.AttributeName:
                    attr = new SyntheticAttribute();
                    break;

                case SourceFileAttribute.AttributeName:
                    tmp  = stream.ReadU2();
                    attr = new SourceFileAttribute(cp.GetEntry <ConstantPoolUtf8>(tmp).Value);
                    break;

                case LineNumberTableAttribute.AttributeName:
                    attr = ReadLineNumberTableAttribute();
                    break;

                case LocalVariableTableAttribute.AttributeName:
                    attr = ReadLocalVariableTableAttribute(cp);
                    break;

                case DeprecatedAttribute.AttributeName:
                    attr = new DeprecatedAttribute();
                    break;

                case OverrideAttribute.AttributeName:
                    attr = new OverrideAttribute();
                    break;

                case SignatureAttribute.AttributeName:
                    tmp  = stream.ReadU2();
                    attr = new SignatureAttribute(cp.GetEntry <ConstantPoolUtf8>(tmp).Value);
                    break;

                case RuntimeVisibleAnnotationsAttribute.AttributeName:
                    attr = new RuntimeVisibleAnnotationsAttribute(ReadAnnotationsAttribute(cp));
                    break;

                case RuntimeInvisibleAnnotationsAttribute.AttributeName:
                    attr = new RuntimeInvisibleAnnotationsAttribute(ReadAnnotationsAttribute(cp));
                    break;

                // The format of these is different from Runtime[In]]VisibleAnnotationsAttribute,
                // see 4.7.19. Since the parameter attributes are not used in the
                // code, we skip loading them for now.
                //case RuntimeVisibleParameterAnnotationsAttribute.AttributeName:
                //    attr = new RuntimeVisibleParameterAnnotationsAttribute(ReadParameterAnnotationsAttribute(cp));
                //    break;
                //case RuntimeInvisibleParameterAnnotationsAttribute.AttributeName:
                //    attr = new RuntimeInvisibleParameterAnnotationsAttribute(ReadParameterAnnotationsAttribute(cp));
                //    break;
                case AnnotationDefaultAttribute.AttributeName:
                    attr = new AnnotationDefaultAttribute(ReadElementValue(cp));
                    break;

                default:
                    stream.Skip(length);
                    attr = new UnknownAttribute(name);
                    break;
                }
                provider.Add(attr);
            }
            provider.AttributesLoaded();
        }
Exemplo n.º 16
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable<NsbmdMaterial> ReadTex0(Stream stream, int blockoffset, out int ptexnum, out int ppalnum, out List<NSBMDTexture> texs, out List<NSBMDPalette> pals)
        {
            EndianBinaryReader reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
            UInt32 blocksize, blockptr, blocklimit;
            int texnum;
            UInt32 texdataoffset;
            int texdatasize;
            UInt32 sptexoffset; // for 4x4 compressed texels only
            int sptexsize; // for 4x4 compressed texels only
            UInt32 spdataoffset; // for 4x4 compressed texels only
            int palnum;
            UInt32 paldefoffset;
            UInt32 paldataoffset;
            int paldatasize;
            NsbmdMaterial[] material = null;
            int i, j;
            texs = new List<NSBMDTexture>();
            pals = new List<NSBMDPalette>();

            blockptr = (uint)(blockoffset + 4); // already read the block ID, so skip 4 bytes
            blocksize = reader.ReadUInt32(); // block size
            blocklimit = (uint)(blocksize + blockoffset);
            Console.WriteLine("DEBUG: blockoffset = {0}, blocksize = {1}", blockoffset, blocksize);

            stream.Skip(4); // skip 4 padding 0s
            texdatasize = reader.ReadUInt16() << 3; // total texture data size div8
            stream.Skip(6); // skip 6 bytes
            texdataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            stream.Skip(4); // skip 4 padding 0s
            sptexsize = reader.ReadUInt16() << 3; // for format 5 4x4-texel, data size div8
            stream.Skip(6); // skip 6 bytesmhm
            sptexoffset = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, data offset
            spdataoffset = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, palette info

            stream.Skip(4); // skip 4 bytes
            paldatasize = reader.ReadUInt16() << 3; // total palette data size div8
            stream.Skip(2); // skip 2 bytes
            paldefoffset = (uint)(reader.ReadUInt32() + blockoffset);
            paldataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            //	printf( "texdataoffset = %08x texdatasize = %08x\n", texdataoffset, texdatasize );
            //	printf( "sptexoffset = %08x sptexsize = %08x spdataoffset = %08x\n", sptexoffset, sptexsize, spdataoffset );
            //	printf( "paldataoffset = %08x paldatasize = %08x\n", paldataoffset, paldatasize );

            ////////////////////////////////////////////////
            // texture definition

            stream.Skip(1); // skip dummy '0'
            texnum = reader.ReadByte(); // no of texture
            blockptr = (uint)stream.Position;
            stream.Seek(paldefoffset, SeekOrigin.Begin);
            stream.Skip(1); // skip dummy '0'
            palnum = reader.ReadByte(); // no of palette
            stream.Seek(blockptr, SeekOrigin.Begin);

            Console.WriteLine("texnum = {0}, palnum = {1}", texnum, palnum);

            // allocate memory for material, great enough to hold all texture and palette
            material = new NsbmdMaterial[(texnum > palnum ? texnum : palnum)];
            for (i = 0; i < material.Length; i++)
                material[i] = new NsbmdMaterial();

            stream.Skip(14 + (texnum * 4)); // go straight to texture info

            for (i = 0; i < texnum; i++)
            {
                UInt32 offset;
                int param;
                int format;
                int width;
                int height;

                var mat = material[i];

                offset = (uint)(reader.ReadUInt16() << 3);
                param = reader.ReadUInt16(); // texture parameter
                stream.Skip(4); // skip 4 bytes

                format = (param >> 10) & 7; // format 0..7, see DSTek
                width = 8 << ((param >> 4) & 7);
                height = 8 << ((param >> 7) & 7);
                mat.color0 = (param >> 13) & 1;

                if (format == 5)
                    mat.texoffset = offset + sptexoffset; // 4x4-Texel Compressed Texture
                else
                    mat.texoffset = offset + texdataoffset;

                mat.format = format;
                mat.width = width;
                mat.height = height;
                NSBMDTexture t = new NSBMDTexture();
                t.format = format;
                t.width = width;
                t.height = height;
                t.color0 = (param >> 13) & 1;
                texs.Add(t);
            }

            ////////////////////////////////////////////
            // copy texture names
            for (i = 0; i < texnum; i++)
            {
                material[i].texname = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                texs[i].texname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each texture's size
            for (i = 0; i < texnum; i++)
            {
                int[] bpp = { 0, 8, 2, 4, 8, 2, 8, 16 };

                var mat = material[i];
                mat.texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
                Console.WriteLine("tex {0} '{1}': offset = {2} size = {3} [W,H] = [{4}, {5}]",
                                  i, mat.texname, mat.texoffset, mat.texsize, mat.width, mat.height);
                texs[i].texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
            }

            ////////////////////////////////////////////////
            // palette definition
            stream.Seek(paldefoffset + 2, SeekOrigin.Begin); // skip palnum, already read
            stream.Seek(14 + (palnum * 4), SeekOrigin.Current); // go straight to palette info
            for (i = 0; i < palnum; i++)
            {
                uint curOffset = (uint)((reader.ReadUInt16() << 3) + paldataoffset);
                stream.Seek(2, SeekOrigin.Current); // skip 2 bytes
                material[i].paloffset = curOffset;
                NSBMDPalette t = new NSBMDPalette();
                t.paloffset = curOffset;
                pals.Add(t);
            }

            ////////////////////////////////////////////////
            // copy palette names
            for (i = 0; i < palnum; i++)
            {
                var mat = material[i];
                mat.palname = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                pals[i].palname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each palette's size
            // assume the palettes are stored sequentially
            /*for (i = 0; i < palnum - 1; i++)
            {
                int r;
                var mat = material[i];
                r = i;
                try { while (material[r].paloffset == mat.paloffset) r++; }
                catch { }
                // below is RotA stupid way to calculate the size of palette: next's offset - current's offset
                // it works most of the time
                if (r != palnum)
                {
                    mat.palsize = material[r].paloffset - mat.paloffset;
                    pals[i].palsize = material[r].paloffset - mat.paloffset;
                }
                else
                {
                    mat.palsize = blocklimit - mat.paloffset;
                    pals[i].palsize = blocklimit - mat.paloffset;
                }
                //printf("pal '%s' size = %d\n", mat->palname, mat->palsize);
            }
            material[i].palsize = blocklimit - material[i].paloffset;
            pals[i].palsize = blocklimit - material[i].paloffset;*/
            List<int> offsets = new List<int>();
            for (int k = 0; k < pals.Count; k++)
            {
                if (!offsets.Contains((int)pals[k].paloffset))
                {
                    offsets.Add((int)pals[k].paloffset);
                }
            }
            offsets.Add((int)blocklimit);
            offsets.Sort();
            for (int k = 0; k < pals.Count; k++)
            {
                int pallength;
                int l = -1;
                do
                {
                    l++;
                }
                while (offsets[l] - pals[k].paloffset <= 0);//nsbtx.PalInfo.infoBlock.PalInfo[i + j].Palette_Offset - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset == 0)
                pallength = offsets[l] - (int)pals[k].paloffset;
                //RGBA[] c_ = pals[k].paldata;
                //List<RGBA> c = new List<RGBA>();
                //c.AddRange(pals[k].paldata.Take(pallength / 2));
                //pals[k].paldata = c.ToArray();
                pals[k].palsize = (uint)pallength;
                material[k].palsize = (uint)pallength;
            }

            ////////////////////////////////////////////////
            // traverse each texture
            for (i = 0; i < texnum; i++)
            {
                var mat = material[i];
                stream.Seek(mat.texoffset, SeekOrigin.Begin);

                ////////////////////////////////////////////////
                // read texture into memory
                byte[] by = reader.ReadBytes((int)mat.texsize);
                mat.texdata = by;
                texs[i].texdata = by;

                Console.WriteLine("DEBUG: texoffset = {0}, texsize = {1}", mat.texoffset, mat.texsize);

                ////////////////////////////////////////////////
                // additional data for format 5 4x4 compressed texels
                if (mat.format == 5)
                {
                    UInt32 r = mat.texsize / 2;//>> 1;
                    stream.Seek(spdataoffset + (mat.texoffset - sptexoffset) / 2, SeekOrigin.Begin);

                    by = reader.ReadBytes((int)r);
                    mat.spdata = by;
                    texs[i].spdata = by;
                    Console.WriteLine("DEBUG: 4x4-texel spdataoffset = {0}, spdatasize = {1}", spdataoffset, r);

                    //spdataoffset += r;
                }
            }

            ////////////////////////////////////////////////
            // traverse each palette
            for (i = 0; i < palnum; i++)
            {
                try
                {
                    NsbmdMaterial mat = material[i];
                    var palentry = mat.palsize >> 1;

                    RGBA[] rgbq = new RGBA[palentry];

                    Console.WriteLine("DEBUG: converting pal '{0}', palentry = {1}", mat.palname, palentry);

                    stream.Seek(mat.paloffset, SeekOrigin.Begin);
                    for (j = 0; j < palentry; j++)
                    {
                        UInt16 p = reader.ReadUInt16();
                        rgbq[j].R = (byte)(((p >> 0) & 0x1f) << 3); // red
                        rgbq[j].G = (byte)(((p >> 5) & 0x1f) << 3); // green
                        rgbq[j].B = (byte)(((p >> 10) & 0x1f) << 3); // blue
                        //rgbq[j].RotA = (p&0x8000) ? 0xff : 0;
                        rgbq[j].A = (p & 0x8000) == 0 ? (byte)0xff : (byte)0;//0xff; // alpha
                    }
                    mat.paldata = rgbq;
                    pals[i].paldata = rgbq;
                }
                catch
                {
                }
            }

            ptexnum = texnum;
            ppalnum = palnum;

            return material;
        }
Exemplo n.º 17
0
        /// <summary>
        /// ReadMld0.
        /// </summary>
        private static NsbmdModel[] ReadMdl0(Stream stream, int blockoffset)
        {
            var reader = new BinaryReader(stream);

            int blocksize;
            int blockptr;
            int blocklimit;
            byte num;
            uint r;
            List<NsbmdModel> model = new List<NsbmdModel>();

            ////////////////////////////////////////////////
            // model
            blockptr = blockoffset + 4; // already read the ID, skip 4 bytes
            blocksize = reader.ReadInt32(); // block size
            blocklimit = blocksize + blockoffset;

            stream.Skip(1); // skip dummy '0'
            num = reader.ReadByte(); // no of model
            if (num <= 0)
                throw new Exception();
            for (var i = 0; i < num; ++i)
                model.Add(new NsbmdModel());
            var modelOffset = new UInt32[num];

            stream.Skip(10 + 4 + (num*4)); // skip [char xyz], useless, go straight to model data offset
            blockptr += 10 + 4;

            ////////////////////////////////////////////////
            // copy model dataoffset
            for (var i = 0; i < num; i++)
                modelOffset[i] = (uint) (reader.ReadUInt32() + blockoffset);

            ////////////////////////////////////////////////
            // copy model names
            for (var i = 0; i < num; i++)
                model[i].Name = Utils.ReadNSBMDString(reader);

            ////////////////////////////////////////////////
            // parse model data

            uint totalsize_base = reader.ReadUInt32();
            uint codeoffset_base = reader.ReadUInt32();
            uint texpaloffset_base = reader.ReadUInt32();
            uint polyoffset_base = reader.ReadUInt32();
            uint polyend_base = reader.ReadUInt32();
            stream.Skip(4);
            uint matnum = reader.ReadByte(); // no. of material
            uint polynum = reader.ReadByte(); // no. of polygon

            var polyOffsets = new UInt32[polynum];
            var polyDataSize = new UInt32[polynum];

            for (var i = 0; i < num; i++)
            {
                var mod = model[i];

                stream.Seek(modelOffset[i], SeekOrigin.Begin);

                // the following variables are all offset values
                long totalsize;
                uint codeoffset;
                UInt32 texpaloffset;
                UInt32 polyoffset;
                long polyend;

                long texoffset;
                long paloffset;

                uint modoffset = modelOffset[i];
                totalsize = totalsize_base + modoffset;
                codeoffset = codeoffset_base + modoffset;
                // additional model data, bone definition etc., just follow NsbmdObject section
                texpaloffset = texpaloffset_base + modoffset;
                polyoffset = polyoffset_base + modoffset;
                polyend = polyend_base + modoffset;

                stream.Skip(5*4 + 4 + 2 + 38); // go straight to NsbmdObject

                ////////////////////////////////////////////////
                // NsbmdObject section
                UInt32 objnum;
                int objdatabase;
                UInt32[] objdataoffset;
                UInt32[] objdatasize;
                objdatabase = (int) stream.Position;
                stream.Skip(1); // skip dummy '0'
                objnum = reader.ReadByte(); // no of NsbmdObject

                stream.Skip(14 + (objnum*4)); // skip bytes, go striaght to NsbmdObject data offset

                for (i = 0; i < objnum; ++i)
                    mod.Objects.Add(new NsbmdObject());

                objdataoffset = new UInt32[objnum];
                objdatasize = new UInt32[objnum];

                for (var j = 0; j < objnum; j++)
                    objdataoffset[j] = (UInt32) (reader.ReadUInt32() + objdatabase);

                for (var j = 0; j < objnum - 1; j++)
                    objdatasize[j] = objdataoffset[j + 1] - objdataoffset[j];
                objdatasize[objnum - 1] = (UInt32) (codeoffset - objdataoffset[objnum - 1]);

                ////////////////////////////////////////////////
                // copy NsbmdObject names
                for (var j = 0; j < objnum; j++)
                {
                    mod.Objects[j].Name = Utils.ReadNSBMDString(reader);
                    // TO DEBUG
                    Console.WriteLine(mod.Objects[j].Name);
                }

                ////////////////////////////////////////////////
                // parse NsbmdObject information
                for (var j = 0; j < objnum; j++)
                {
                    if (objdatasize[j] <= 4)
                        continue;

                    stream.Seek(objdataoffset[j], SeekOrigin.Begin);
                    ParseNsbmdObject(reader, mod.Objects[j]);
                }

                ////////////////////////////////////////////////
                // material section
                stream.Seek(texpaloffset, SeekOrigin.Begin); // now get the texture and palette offset
                texoffset = reader.ReadUInt16() + texpaloffset;
                paloffset = reader.ReadUInt16() + texpaloffset;

                // allocate memory for material
                for (var j = 0; i <= matnum; ++i)
                    mod.Materials.Add(new NsbmdMaterial());

                ////////////////////////////////////////////////
                // parse material definition
                // defines RotA material by pairing texture and palette
                stream.Seek(16 + (matnum*4), SeekOrigin.Current); // go straight to material data offset
                for (var j = 0; j < matnum; j++) // TODO: BAD!
                {
                    mod.Materials[j] = new NsbmdMaterial();
                    blockptr = (int) stream.Position;
                    r = reader.ReadUInt32() + texpaloffset + 4 + 18;
                        // skip 18 bytes (+ 2 bytes for texoffset, 2 bytes for paloffset)
                    stream.Seek(r, SeekOrigin.Begin);
                    mod.Materials[j].repeat = reader.ReadByte();
                    stream.Seek(blockptr + 4, SeekOrigin.Begin);
                }

                ////////////////////////////////////////////////
                // now go to read the texture definition
                stream.Seek(texoffset, SeekOrigin.Begin);
                stream.Skip(1); // skip dummy '0'
                int texnum = reader.ReadByte();
                Debug.Assert(texnum <= matnum);
                Console.WriteLine(String.Format("texnum: {0}", texnum));

                if (texnum > 0)
                {
                    stream.Seek(14 + (texnum*4), SeekOrigin.Current); // go straight to data offsets
                    for (var j = 0; j < texnum; j++)
                    {
                        UInt32 texmatid = ((reader.ReadUInt32() & 0xffff) + texpaloffset);
                        blockptr = (int) stream.Position;
                        stream.Seek(texmatid, SeekOrigin.Begin);
                        texmatid = reader.ReadByte();
                        mod.Materials[j].texmatid = texmatid;
                        stream.Seek(blockptr, SeekOrigin.Begin);
                    }

                    for (var j = 0; j < texnum; j++) // copy texture names
                    {
                        NsbmdMaterial mat = mod.Materials[j];

                        mat.texname = Utils.ReadNSBMDString(reader);

                        Console.WriteLine("tex (matid={0}): {1}", mat.texmatid, mat.texname);
                    }

                    ////////////////////////////////////////////////
                    // now go to read the palette definition
                    stream.Seek(paloffset, SeekOrigin.Begin);
                    stream.Skip(1); // skip dummy '0'
                    int palnum = reader.ReadByte(); // no of palette definition
                    Debug.Assert(palnum <= matnum); // may not always hold?
                    Console.WriteLine("DEBUG: palnum = {0}", palnum);

                    if (palnum > 0)
                    {
                        stream.Seek(14 + (palnum*4), SeekOrigin.Current); // go straight to data offsets
                        for (var j = 0; j < palnum; j++) // matching palette with material
                        {
                            var palmatid = (reader.ReadUInt32() & 0xffff) + texpaloffset;
                            blockptr = (int) stream.Position;
                            stream.Seek(palmatid, SeekOrigin.Begin);
                            palmatid = reader.ReadByte();
                            var mat = mod.Materials[j];
                            mat.palmatid = palmatid;
                            stream.Seek(blockptr, SeekOrigin.Begin);
                        }
                        for (var j = 0; j < palnum; j++) // copy palette names
                        {
                            int palmatid = (int) mod.Materials[j].palmatid;
                            mod.Materials[palmatid].palname = Utils.ReadNSBMDString(reader);
                            // TO DEBUG
                            Console.WriteLine("pal (matid={0}): {1}", palmatid, mod.Materials[palmatid].palname);
                        }

                        ////////////////////////////////////////////////
                        // Polygon
                        stream.Seek(polyoffset, SeekOrigin.Begin);
                        stream.Skip(1); // skip dummy '0'
                        r = reader.ReadByte(); // no of polygon
                        Console.WriteLine("DEBUG: polynum = {0}", polynum);

                        for (var j = 0; j <= polynum; ++j)
                            mod.Polygons.Add(new NsbmdPolygon());

                        stream.Skip(14 + (polynum*4)); // skip bytes, go straight to data offset

                        for (var j = 0; j < polynum; j++)
                            polyOffsets[j] = reader.ReadUInt32() + polyoffset;

                        for (var j = 0; j < polynum; j++) // copy polygon names
                        {
                            mod.Polygons[j].Name = Utils.ReadNSBMDString(reader);
                            Console.WriteLine(mod.Polygons[j].Name);
                        }

                        ////////////////////////////////////////////////
                        // now go to the polygon data, there is RotA 16-byte-header before geometry commands
                        for (var j = 0; j < polynum; j++)
                        {
                            var poly = mod.Polygons[j];
                            //////////////////////////////////////////////////////////
                            poly.MatId = -1; // DEFAULT: indicate no associated material
                            //////////////////////////////////////////////////////////
                            stream.Seek(polyOffsets[j] + 8, SeekOrigin.Begin); // skip 8 unknown bytes
                            polyOffsets[j] += reader.ReadUInt32();
                            polyDataSize[j] = reader.ReadUInt32();
                            //printf( "poly %2d '%-16s': dataoffset: %08x datasize %08x\n", j, poly->polyname, poly->dataoffset, poly->datasize );
                        }
                    }

                    ////////////////////////////////////////////////
                    // read the polygon data into memory
                    for (var j = 0; j < polynum; j++)
                    {
                        var poly = mod.Polygons[j];
                        stream.Seek(polyOffsets[j], SeekOrigin.Begin);
                        poly.PolyData = reader.ReadBytes((int) polyDataSize[j]);
                    }
                }

                ////////////////////////////////////////////////
                // decode the additional model data
                DecodeCode(stream, codeoffset, texpaloffset, mod);
            }

            //modelnum = num;
            return model.ToArray();
        }
Exemplo n.º 18
0
 internal void SkipParams(Stream reader)
 {
     switch (this.flags & OpcodeFlags.OperandType) {
     case OpcodeFlags.NoOperand:
         break;
     case OpcodeFlags.OperandSize1:
         reader.Skip (1);
         break;
     case OpcodeFlags.OperandSize2:
         reader.Skip (2);
         break;
     case OpcodeFlags.OperandSize4:
         reader.Skip (4);
         break;
     case OpcodeFlags.OperandSize8:
         reader.Skip (8);
         break;
     case OpcodeFlags.OperandSwitch: //FIXME implement me
         throw new Exception ("not supported");
     default:
         throw new Exception ("invalid opcode type " + this.flags);
     }
 }
Exemplo n.º 19
0
 public void Skip_zero_delta_does_nothing()
 {
     MoveTo(1);
     _stream.Skip(0);
     Assert.That(_stream.Position, Is.EqualTo(1));
 }