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