/// <summary>
        /// Make texture for model.
        /// </summary>
        /// <param name="mod">NSBMD Model</param>
        private void MakeTexture(NsbmdModel mod)
        {
            Console.WriteLine("DEBUG: making texture for model '{0}'...", mod.Name);

            for (int i = 0; i < mod.Materials.Count; i++)
            {
                if (mod.Materials[i].format == 0) // format 0 is no texture
                    continue;
                var mat = mod.Materials[i];
                if (mat == null || mat.paldata == null)
                    continue;
                int pixelnum = mat.width*mat.height;

                var image = new RGBA[pixelnum];

                switch (mat.format)
                {
                        // No Texture
                    case 0:
                        //puts( "ERROR: format 0" );
                        continue;
                        break;
                        // A3I5 Translucent Texture (3bit Alpha, 5bit Color Index)
                    case 1:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            int index = mat.texdata[j] & 0x1f;
                            int alpha = (mat.texdata[j] >> 5) & 7;
                            alpha = ((alpha*4) + (alpha/2)) << 3;
                            image[j] = mat.paldata[index];
                            image[j].A = (byte) alpha;
                        }
                        break;
                        // 4-Color Palette Texture
                    case 2:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            uint index = mat.texdata[j/4];
                            index = (index >> ((j%4) << 1)) & 3;
                            image[j] = mat.paldata[index];
                        }
                        break;
                        // 16-Color Palette Texture
                    case 3:
                        if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                        for (int j = 0; j < pixelnum; j++)
                        {
                            var matindex = j/2;
                            if (mat.texdata.Length < matindex)
                                continue;
                            int index = mat.texdata[matindex];
                            index = (index >> ((j%2) << 2)) & 0x0f;
                            if (mat.paldata == null)
                                continue;
                            if (index < 0 || index >= mat.paldata.Length)
                                continue;
                            if (j < 0 || j >= pixelnum)
                                continue;
                            image[j] = mat.paldata[index];
                        }
                        break;
                        // 256-Color Palette Texture
                    case 4:
                        if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                        // made palette entry 0 transparent
                        for (int j = 0; j < pixelnum; j++)
                        {
                            image[j] = mat.paldata[mat.texdata[j]];
                        }
                        break;
                        // 4x4-Texel Compressed Texture
                    case 5:
                        convert_4x4texel_b(mat.texdata, mat.width, mat.height, mat.spdata, mat.paldata, image);
                        break;
                        // A5I3 Translucent Texture (5bit Alpha, 3bit Color Index)
                    case 6:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            int index = mat.texdata[j] & 0x7;
                            int alpha = (mat.texdata[j] >> 3) & 0x1f;
                            alpha = ((alpha*4) + (alpha/2)) << 3;
                            image[j] = mat.paldata[index];
                            image[j].A = (byte) alpha;
                        }
                        break;
                        // Direct Color Texture
                    case 7:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            UInt16 p = (ushort) (mat.texdata[j*2] + (mat.texdata[j*2 + 1] << 8));
                            image[j].R = (byte) (((p >> 0) & 0x1f) << 3);
                            image[j].G = (byte) (((p >> 5) & 0x1f) << 3);
                            image[j].B = (byte) (((p >> 10) & 0x1f) << 3);
                            image[j].A = (byte) (((p & 0x8000) != 0) ? 0xff : 0);
                        }
                        break;
                }

                /////////////////////////////////////////////////////
                // The trick to handle texture repetition in OpenGL
                // Flip is not supported in Win32 version of OpenGL
                // We have to manually resize the texture, and apply mirror/flip effect

                if (mat.repeat == 0x07)
                {
                    // repeat in s & t direction, flip in s direction
                    // double the width, add a mirror image along the right edge of the texture (s direction)
                    var newimage = new RGBA[pixelnum*2];

                    int newwidth = mat.width*2;
                    int newwidth_1 = newwidth - 1;
                    for (int y = 0; y < mat.height; y++)
                    {
                        int tbase = y*mat.width; // base in original texture
                        int newbase = y*newwidth; // base in new texture
                        for (int x = 0; x < mat.width; x++)
                        {
                            var pixel = image[tbase + x];
                            newimage[newbase + x] = pixel;
                            newimage[newbase + newwidth_1 - x] = pixel;
                        }
                    }
                    mat.width = newwidth;
                    image = newimage;
                }
                else if (mat.repeat == 0x0b)
                {
                    // repeat in s & t direction, flip in t direction
                    // double the height, add a mirror image along the bottom edge of the texture (t direction)
                    var newimage = new RGBA[pixelnum*2];

                    int newheight = mat.height*2;
                    int newheight_1 = mat.height - 1;
                    for (int y = 0; y < mat.height; y++)
                    {
                        int tbase = y*mat.width;
                        int newbase = (newheight_1 - y)*mat.width;
                        for (int x = 0; x < mat.width; x++)
                            newimage[newbase + x] = image[tbase + x];
                    }
                    mat.height = newheight;

                    image = newimage;
                }
                else if (mat.repeat == 0x0f)
                {
                    // repeat in s & t direction, flip in s & t direction
                    // double both width and height, add mirror images along both right and bottom edges
                    var newimage = new RGBA[pixelnum*4];

                    int newwidth = mat.width*2;
                    int newwidth_1 = newwidth - 1;
                    int newheight = mat.height*2;
                    int newheight_1 = newheight - 1;
                    for (int y = 0; y < mat.height; y++)
                    {
                        int tbase = y*mat.width; // base in original texture
                        int topbase = y*newwidth; // top base in new texture
                        int bottombase = (newheight_1 - y)*newwidth; // bottom base in new texture
                        for (int x = 0; x < mat.width; x++)
                        {
                            var pixel = image[tbase + x];
                            newimage[topbase + x] = pixel;
                            newimage[topbase + newwidth_1 - x] = pixel;
                            newimage[bottombase + x] = pixel;
                            newimage[bottombase + newwidth_1 - x] = pixel;
                        }
                    }
                    mat.width = newwidth;
                    mat.height = newheight;

                    image = newimage;
                }

                Console.WriteLine("convert matid = {0}", i);
                Console.WriteLine("\ttex '{0}': {1} [{2},{3}] texsize = {4}", mat.texname, TEXTURE_FORMATS[mat.format], mat.width,
                                  mat.height, mat.texsize);
                Console.WriteLine("\tpal '{0}': pixelnum = {1}, repeat = {2}", mat.palname, pixelnum, mat.repeat);

                var imageBytesList = new List<byte>();
                for (int k = 0; k < image.Length; ++k)
                {
                    imageBytesList.Add(image[k].R);
                    imageBytesList.Add(image[k].G);
                    imageBytesList.Add(image[k].B);
                    imageBytesList.Add(image[k].A);
                }

                var imageBytes = imageBytesList.ToArray();

                Gl.glBindTexture(Gl.GL_TEXTURE_2D, i + 1);

                Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, mat.width, mat.height, 0, Gl.GL_RGBA,
                                Gl.GL_UNSIGNED_BYTE,
                                imageBytes);

                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
            }
        }
Exemple #2
0
        /// <summary>
        /// Make texture for model.
        /// </summary>
        /// <param name="mod">NSBMD Model</param>
        private void MakeTexture(NsbmdModel mod)
        {
            Gl.glMatrixMode(Gl.GL_TEXTURE_MATRIX);
            Gl.glLoadIdentity();

            Console.WriteLine("DEBUG: making texture for model '{0}'...", mod.Name);

            for (int i = 0; i < mod.Materials.Count - 1; i++)
            {
                try
                {
                    if (mod.Materials[i].format == 0) // format 0 is no texture
                    {
                        matt.Add(new System.Windows.Media.ImageBrush());
                        continue;
                    }
                    var mat = mod.Materials[i];
                    if (mat == null || (mat.paldata == null && mat.format != 7))
                    {
                        matt.Add(new System.Windows.Media.ImageBrush());
                        continue;
                    }
                    int pixelnum = mat.width * mat.height;

                    var image = new RGBA[pixelnum];

                    switch (mat.format)
                    {
                        // No Texture
                        case 0:
                            //puts( "ERROR: format 0" );
                            mattt.Add(new System.Windows.Media.ImageBrush());
                            continue;
                        // A3I5 Translucent Texture (3bit Alpha, 5bit Color Index)
                        case 1:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                int index = mat.texdata[j] & 0x1f;
                                int alpha = (mat.texdata[j] >> 5);// & 7;
                                alpha = ((alpha * 4) + (alpha / 2)) * 8;// << 3;
                                image[j] = mat.paldata[index];
                                image[j].A = (byte)alpha;
                            }

                            break;
                        // 4-Color Palette Texture
                        case 2:
                            if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                            for (int j = 0; j < pixelnum; j++)
                            {
                                uint index = mat.texdata[j / 4];
                                index = (index >> ((j % 4) << 1)) & 3;
                                image[j] = mat.paldata[index];
                            }
                            break;
                        // 16-Color Palette Texture
                        case 3:
                            if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                            for (int j = 0; j < pixelnum; j++)
                            {
                                var matindex = j / 2;
                                if (mat.texdata.Length < matindex)
                                    continue;
                                int index = mat.texdata[matindex];
                                index = (index >> ((j % 2) << 2)) & 0x0f;
                                if (mat.paldata == null)
                                    continue;
                                if (index < 0 || index >= mat.paldata.Length)
                                    continue;
                                if (j < 0 || j >= pixelnum)
                                    continue;
                                image[j] = mat.paldata[index];
                            }
                            break;
                        // 256-Color Palette Texture
                        case 4:
                            if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                            // made palette entry 0 transparent
                            for (int j = 0; j < pixelnum; j++)
                            {
                                image[j] = mat.paldata[mat.texdata[j]];
                            }
                            break;
                        // 4x4-Texel Compressed Texture
                        case 5:
                            convert_4x4texel_b(mat.texdata, mat.width, mat.height, mat.spdata, mat.paldata, image);
                            break;
                        // A5I3 Translucent Texture (5bit Alpha, 3bit Color Index)
                        case 6:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                int index = mat.texdata[j] & 0x7;
                                int alpha = (mat.texdata[j] >> 3);
                                alpha *= 8; //((alpha * 4) + (alpha / 2)) << 3;
                                image[j] = mat.paldata[index];
                                image[j].A = (byte)alpha;
                            }
                            break;
                        // Direct Color Texture
                        case 7:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                //UInt16 p = (ushort)(mat.texdata[j * 2] + (mat.texdata[j * 2 + 1] << 8));
                                //image[j].R = (byte)(((p >> 0) & 0x1f) << 3);
                                //image[j].G = (byte)(((p >> 5) & 0x1f) << 3);
                                //image[j].B = (byte)(((p >> 10) & 0x1f) << 3);
                                //image[j].A = (byte)(((p & 0x8000) != 0) ? 0xff : 0);
                                image[j] = RGBA.fromColor(Tinke.Convertir.BGR555(mat.texdata[j * 2], mat.texdata[j * 2 + 1]));
                                UInt16 p = (ushort)(mat.texdata[j * 2] + (mat.texdata[j * 2 + 1] << 8));
                                image[j].A = (byte)(((p & 0x8000) != 0) ? 0xff : 0);
                            }
                            break;
                    }

                    Console.WriteLine("convert matid = {0}", i);
                    Console.WriteLine("\ttex '{0}': {1} [{2},{3}] texsize = {4}", mat.texname, TEXTURE_FORMATS[mat.format], mat.width,
                                      mat.height, mat.texsize);
                    Console.WriteLine("\tpal '{0}': pixelnum = {1}, repeat = {2}", mat.palname, pixelnum, mat.repeat);

                    var imageBytesList = new List<byte>();
                    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(mat.width, mat.height);
                    for (int k = 0; k < image.Length; ++k)
                    {
                        bitmap.SetPixel(k - ((k / (mat.width)) * (mat.width)), k / (mat.width), image[k].ToColor());
                        imageBytesList.Add(image[k].R);
                        imageBytesList.Add(image[k].G);
                        imageBytesList.Add(image[k].B);
                        //if (image[k].A != 0)
                        //{
                        //	imageBytesList.Add((byte)(image[k].A - (255 - (((mat.Alpha + 1) * 8) - 1))));
                        //}
                        //else
                        //{
                            imageBytesList.Add((byte)(image[k].A));
                        //}
                    }
                    var imageBytes = imageBytesList.ToArray();
                    if (mat.flipS == 1 && mat.flipT == 1)
                    {
                        //br.TileMode = System.Windows.Media.TileMode.FlipXY;
                        System.Drawing.Bitmap bitmap2 = new System.Drawing.Bitmap(mat.width * 2, mat.height * 2);
                        using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap2))
                        {
                            g.DrawImage(bitmap, 0, 0);
                            System.Drawing.Bitmap tmp = bitmap;
                            tmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX);
                            g.DrawImage(tmp, mat.width, 0);
                            tmp = bitmap;
                            tmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
                            g.DrawImage(tmp, mat.width, mat.height);
                            tmp = bitmap;
                            tmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX);
                            g.DrawImage(tmp, 0, mat.height);
                        }
                        bitmap = bitmap2;
                    }
                    else if (mat.flipS == 1)
                    {
                        //br.TileMode = System.Windows.Media.TileMode.FlipX;
                        System.Drawing.Bitmap bitmap2 = new System.Drawing.Bitmap(mat.width * 2, mat.height);
                        using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap2))
                        {
                            g.DrawImage(bitmap, 0, 0);
                            System.Drawing.Bitmap tmp = bitmap;
                            tmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX);
                            g.DrawImage(tmp, mat.width, 0);
                        }
                        bitmap = bitmap2;
                    }
                    else if (mat.flipT == 1)
                    {
                        //br.TileMode = System.Windows.Media.TileMode.FlipY;
                        System.Drawing.Bitmap bitmap2 = new System.Drawing.Bitmap(mat.width, mat.height * 2);
                        using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap2))
                        {
                            g.DrawImage(bitmap, 0, 0);
                            System.Drawing.Bitmap tmp = bitmap;
                            tmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
                            g.DrawImage(tmp, 0, mat.height);
                        }
                        bitmap = bitmap2;
                    }
                    else if (mat.repeatS == 1 || mat.repeatT == 1)
                    {
                        //br.TileMode = System.Windows.Media.TileMode.Tile;
                    }
                    else
                    {
                        //br.TileMode = System.Windows.Media.TileMode.None;
                    }
                    System.Windows.Media.ImageBrush br = new System.Windows.Media.ImageBrush(CreateBitmapSourceFromBitmap(bitmap));
                    br.Viewbox = new System.Windows.Rect(0, 0, br.ImageSource.Width, br.ImageSource.Height);
                    br.ViewboxUnits = System.Windows.Media.BrushMappingMode.Absolute;
                    br.Viewport = new System.Windows.Rect(0, 0, 1, 1);
                    br.ViewportUnits = System.Windows.Media.BrushMappingMode.Absolute;
                    br.Stretch = System.Windows.Media.Stretch.None;

                    //br.ImageSource = CreateBitmapSourceFromBitmap(bitmap);
                    br.Opacity = (double)(((mat.Alpha + 1) * 8) - 1) / 1.0d;
                    matt.Add(br);
                    //ttt
                    Gl.glBindTexture(Gl.GL_TEXTURE_2D, i + 1 + matstart);
                    Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, mat.width, mat.height, 0, Gl.GL_RGBA,
                                    Gl.GL_UNSIGNED_BYTE,
                                    imageBytes);
                    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);

                    if (mat.flipS == 1 && mat.repeatS == 1)
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_MIRRORED_REPEAT);
                    }
                    else if (mat.repeatS == 1)
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                    }
                    else
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP);
                    }
                    if (mat.flipT == 1 && mat.repeatT == 1)
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_MIRRORED_REPEAT);
                    }
                    else if (mat.repeatT == 1)
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                    }
                    else
                    {
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP);
                    }
                }
                catch
                {
                    matt.Add(new System.Windows.Media.ImageBrush());
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Decode objects.
        /// </summary>
        public static bool DecodeCode(Stream stream, uint codeoffset, uint codelimit, NsbmdModel mod, int maxstack)
        {
            var reader = new BinaryReader(stream);
            Console.WriteLine("DecodeCode");
            UInt32 codeptr = codeoffset;
            bool begin = false; // whether there is a 0x0b begin code
            int count = 0;

            int stackID = -1;
            int polyStack = -1;
            int polystack2 = -1;
            int curjoint = -1;
            int matid = -1;
            int emptystack = maxstack - 1;
            stream.Seek(codeoffset, SeekOrigin.Begin);
            while (codeptr < codelimit)
            {
                int c = reader.ReadByte();
                Console.WriteLine(BitConverter.ToString(new byte[] { (byte)c }, 0, 1));
                int d, e, f, g, h, i, j, k;
                switch (c)
                {
                    ////////////////////////////////////////////
                    // bone-definition related byte
                    case 0x06: //NodeDesc[000]
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        //			printf("DEBUG: %08x: 06: %02x --> %02x\n", codeptr, d, e);
                        codeptr += 4;
                        //curjoint = d;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = polystack2 = emptystack = emptystack+1;//stackID + 1;//-1;
                        mod.Objects[d].RestoreID = -1;
                        break;
                    case 0x26: //NodeDesc[001]
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // store stackID
                        //			printf("DEBUG: %08x: %02x: %02x --> %02x\n", codeptr, c, d, e);
                        codeptr += 5;
                        //curjoint = d;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = polystack2 = g;
                        mod.Objects[d].RestoreID = -1;
                        break;
                    case 0x46: // 4 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // restore stackID
                        //			printf("DEBUG: %08x: %02x: %02x --> %02x\n", codeptr, c, d, e);
                        codeptr += 5;
                        //curjoint = d;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = polystack2 = emptystack = emptystack+1; //stackID + 1;
                        mod.Objects[d].RestoreID = stackID = g;
                        break;
                    case 0x66: //NodeDesc[011]
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // store stackID
                        h = reader.ReadByte(); // restore stackID
                        //			printf("DEBUG: %08x: 66: %02x --> %02x\n", codeptr, d, e);
                        codeptr += 6;
                        //curjoint = d;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = polystack2 = g;
                        mod.Objects[d].RestoreID = h;
                        break;
                    ////////////////////////////////////////////
                    // node's visibility
                    case 0x02: //Node
                        d = reader.ReadByte(); // node ID
                        e = reader.ReadByte(); // 1 = visible, 0 = hide
                        curjoint = d;
                        //polystack2 = mod.Objects[d].StackID;
                        mod.Objects[d].visible = e == 1;
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr += 3;
                        break;
                    ////////////////////////////////////////////
                    // stackID for polygon
                    case 0x03: //Mtx
                        polyStack = reader.ReadByte();
                        codeptr += 2;
                        break;
                    ////////////////////////////////////////////
                    // unknown
                    case 0x07://NodeDesc_BB[000]
                        d = reader.ReadByte();
                        mod.Objects[d].isBillboard = true;
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr += 2;
                        break;
                    case 0x08:
                        d = reader.ReadByte();
                        mod.Objects[d].isBillboard = true;
                        mod.Objects[d].isYBillboard = true;
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr += 2;
                        break;
                    case 0x09://NodeMix[000] Weight
                        d = reader.ReadByte();
                        polyStack = d;
                        e = reader.ReadByte();
                        codeptr += 2;

                        for (int l = 0; l < e; l++)
                        {
                            int var0 = reader.ReadByte();
                            int var1 = reader.ReadByte();
                            int var2 = reader.ReadByte() & 0xff;
                            codeptr += 3;
                        }
                        codeptr += 1;
                        break;
                    ////////////////////////////////////////////
                    // look like BEGIN and END pair
                    case 0x0b: // 0 byte follows
                        if (begin)
                        {
                            //printf("DEBUG: %08x: previous 0x0b not ended.", codeptr);
                        }
                        begin = true;
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        break;
                    case 0x2b: // 0 byte follows
                        if (!begin)
                        {
                            //printf( "DEBUG: %08x: previous 0x0b already ended.", codeptr );
                        }
                        begin = false;
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        break;
                    ////////////////////////////////////////////
                    case 0x04: //Mat[000]
                    case 0x24:
                    case 0x44:
                        matid = reader.ReadByte();
                        codeptr+=2;
                        count++;
                        break;
                    case 0x05://Shp
                        d = reader.ReadByte();
                        mod.Polygons[d].MatId = matid;
                        if (polyStack != -1)
                        {
                            mod.Polygons[d].StackID = polyStack;
                        }
                        else
                        {
                            mod.Polygons[d].StackID = polystack2;
                        }
                        mod.Polygons[d].JointID = curjoint;
                        mod.Objects[curjoint].childs.Add(d);
                        matid = -1;
                        codeptr += 2;
                        break;
                    case 0x0C://EnvMap
                        d = reader.ReadByte();
                        mod.Materials[d].isEnvironmentMap = true;
                        codeptr += 2;
                        break;
                    ////////////////////////////////////////////
                    case 0x01: //Ret
                        //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        return true;
                    case 0x00://padding
                        //codeptr++;
                        break;
                    default:
                        // TODO
                        //printf( "DEBUG: %08x: decodecode: unknown code %02x.\n", codeptr, c );
                        //getchar();
                        return false;
                }
            }
            return false;
        }
Exemple #4
0
        /// <summary>
        /// Decode objects.
        /// </summary>
        public static bool DecodeCode(Stream stream, uint codeoffset, uint codelimit, NsbmdModel mod)
        {
            var reader = new BinaryReader(stream);

            UInt32 codeptr = codeoffset;
            bool begin = false; // whether there is a 0x0b begin code
            int count = 0;

            int stackID = 0;
            stream.Seek(codeoffset, SeekOrigin.Begin);
            while (codeptr < codelimit)
            {
                int c = reader.ReadByte();
                int d, e, f, g, h, i, j, k;
                switch (c)
                {
                        ////////////////////////////////////////////
                        // bone-definition related byte
                    case 0x06: // 3 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
            //			printf("DEBUG: %08x: 06: %02x --> %02x\n", codeptr, d, e);
                        codeptr += 4;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = -1;
                        mod.Objects[d].RestoreID = -1;
                        break;
                    case 0x26: // 4 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // store stackID
            //			printf("DEBUG: %08x: %02x: %02x --> %02x\n", codeptr, c, d, e);
                        codeptr += 5;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = g;
                        mod.Objects[d].RestoreID = -1;
                        break;
                    case 0x46: // 4 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // restore stackID
            //			printf("DEBUG: %08x: %02x: %02x --> %02x\n", codeptr, c, d, e);
                        codeptr += 5;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = -1;
                        mod.Objects[d].RestoreID = stackID = g;
                        break;
                    case 0x66: // 5 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte(); // dummy '0'
                        g = reader.ReadByte(); // store stackID
                        h = reader.ReadByte(); // restore stackID
            //			printf("DEBUG: %08x: 66: %02x --> %02x\n", codeptr, d, e);
                        codeptr += 6;
                        mod.Objects[d].ParentID = e;
                        mod.Objects[d].StackID = stackID = g;
                        mod.Objects[d].RestoreID = h;
                        break;
                        ////////////////////////////////////////////
                        // node's visibility
                    case 0x02: // 2 bytes follow
                        d = reader.ReadByte(); // node ID
                        e = reader.ReadByte(); // 1 = visible, 0 = hide
            //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr += 3;
                        break;
                        ////////////////////////////////////////////
                        // stackID for polygon
                    case 0x03: // 1 byte follows
                        stackID = reader.ReadByte();
                        codeptr += 2;
                        break;
                        ////////////////////////////////////////////
                        // unknown
                    case 0x07:
                    case 0x08:
                        d = reader.ReadByte();
            //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr += 2;
                        break;
                    case 0x09: // 8 bytes follow
                        d = reader.ReadByte();
                        e = reader.ReadByte();
                        f = reader.ReadByte();
                        g = reader.ReadByte();
                        h = reader.ReadByte();
                        i = reader.ReadByte();
                        j = reader.ReadByte();
                        k = reader.ReadByte();
                        codeptr += 9;
                        break;
                        ////////////////////////////////////////////
                        // look like BEGIN and END pair
                    case 0x0b: // 0 byte follows
                        if (begin)
                        {
                            //printf("DEBUG: %08x: previous 0x0b not ended.", codeptr);
                        }
                        begin = true;
            //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        break;
                    case 0x2b: // 0 byte follows
                        if (!begin)
                        {
                            //printf( "DEBUG: %08x: previous 0x0b already ended.", codeptr );
                        }
                        begin = true;
            //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        break;
                        ////////////////////////////////////////////
                    case 0x04: // 3 bytes follow
                    case 0x24:
                    case 0x44:
                        // 04 mm 05 pp
                        // mm - specify the material ID, pp - specify the polygon ID
                        // TODO
                        d = reader.ReadByte(); //assert( d < mod->matnum );
                        e = reader.ReadByte(); //assert( e == 0x05 );
                        f = reader.ReadByte(); //assert( f < mod->polynum );
                        mod.Polygons[f].MatId = d;
                        mod.Polygons[f].StackID = stackID;
            //			printf( "DEBUG: %08x: <%d> %02x %02x %02x %02x\n", codeptr, count, c, d, e, f );
                        codeptr += 4;
                        count++;
                        break;
                        ////////////////////////////////////////////
                    case 0x01: // end
            //			printf( "DEBUG: %08x: %02x\n", codeptr, c );
                        codeptr++;
                        return true;
                    default:
                        // TODO
                        //printf( "DEBUG: %08x: decodecode: unknown code %02x.\n", codeptr, c );
                        //getchar();
                        return false;
                }
            }
            return false;
        }