public Triangle(byte[] file, int address) : this() { Indexes[0] = ByteConverter.ToUInt16(file, address); Indexes[1] = ByteConverter.ToUInt16(file, address + 2); Indexes[2] = ByteConverter.ToUInt16(file, address + 4); }
public Quad(byte[] file, int address) : this() { Indexes[0] = ByteConverter.ToUInt16(file, address); Indexes[1] = ByteConverter.ToUInt16(file, address + 2); Indexes[2] = ByteConverter.ToUInt16(file, address + 4); Indexes[3] = ByteConverter.ToUInt16(file, address + 6); }
public Strip(byte[] file, int address) { Indexes = new ushort[ByteConverter.ToUInt16(file, address) & 0x7FFF]; Reversed = (ByteConverter.ToUInt16(file, address) & 0x8000) == 0x8000; address += 2; for (int i = 0; i < Indexes.Length; i++) { Indexes[i] = ByteConverter.ToUInt16(file, address); address += 2; } }
public PolyChunkVolume(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Size = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Header2 = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); int polyCount = Header2 & 0x3FFF; Polys = new List <Poly>(polyCount); for (int i = 0; i < polyCount; i++) { Poly str = Poly.CreatePoly(Type, file, address, UserFlags); Polys.Add(str); address += str.Size; } }
public PolyChunkStrip(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Size = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Header2 = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); int stripCount = Header2 & 0x3FFF; Strips = new List <Strip>(stripCount); for (int i = 0; i < stripCount; i++) { Strip str = new Strip(file, address, Type, UserFlags); Strips.Add(str); address += str.Size; } }
public Triangle(byte[] file, int address, byte userFlags) : this() { Indexes[0] = ByteConverter.ToUInt16(file, address); Indexes[1] = ByteConverter.ToUInt16(file, address + 2); Indexes[2] = ByteConverter.ToUInt16(file, address + 4); if (userFlags > 0) { UserFlags1 = ByteConverter.ToUInt16(file, address + 6); if (userFlags > 1) { UserFlags2 = ByteConverter.ToUInt16(file, address + 8); if (userFlags > 2) { UserFlags3 = ByteConverter.ToUInt16(file, address + 10); } } } }
public PolyChunkMaterialBump(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Size = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); DX = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); DY = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); DZ = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); UX = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); UY = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); UZ = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); }
public Strip(byte[] file, int address, byte userFlags) { Indexes = new ushort[ByteConverter.ToUInt16(file, address) & 0x7FFF]; Reversed = (ByteConverter.ToUInt16(file, address) & 0x8000) == 0x8000; if (userFlags > 0) { UserFlags1 = new ushort[Indexes.Length - 2]; } if (userFlags > 1) { UserFlags2 = new ushort[Indexes.Length - 2]; } if (userFlags > 2) { UserFlags3 = new ushort[Indexes.Length - 2]; } address += 2; for (int i = 0; i < Indexes.Length; i++) { Indexes[i] = ByteConverter.ToUInt16(file, address); address += 2; if (i > 1) { if (userFlags > 0) { UserFlags1[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; if (userFlags > 1) { UserFlags2[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; if (userFlags > 2) { UserFlags3[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; } } } } } }
public PolyChunkBitsDrawPolygonList(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); }
public byte[] GetBytes() { VertexChunk next = null; int vertlimit; int vertcount = Vertices.Count; switch (Type) { case ChunkType.Vertex_VertexSH: vertlimit = 65535 / 4; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormalSH: vertlimit = 65535 / 8; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_Vertex: vertlimit = 65535 / 3; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexDiffuse8: vertlimit = 65535 / 4; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Diffuse = Diffuse.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexUserFlags: vertlimit = 65535 / 4; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), UserFlags = UserFlags.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNinjaFlags: vertlimit = 65535 / 4; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), NinjaFlags = NinjaFlags.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexDiffuseSpecular5: case ChunkType.Vertex_VertexDiffuseSpecular4: vertlimit = 65535 / 4; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Diffuse = Diffuse.Skip(vertlimit).ToList(), Specular = Specular.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormal: vertlimit = 65535 / 6; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormalDiffuse8: vertlimit = 65535 / 7; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList(), Diffuse = Diffuse.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormalUserFlags: vertlimit = 65535 / 7; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList(), UserFlags = UserFlags.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormalNinjaFlags: vertlimit = 65535 / 7; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList(), NinjaFlags = NinjaFlags.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.Vertex_VertexNormalDiffuseSpecular5: case ChunkType.Vertex_VertexNormalDiffuseSpecular4: vertlimit = 65535 / 7; if (Vertices.Count > vertlimit) { next = new VertexChunk(Type) { Vertices = Vertices.Skip(vertlimit).ToList(), Normals = Normals.Skip(vertlimit).ToList(), Diffuse = Diffuse.Skip(vertlimit).ToList(), Specular = Specular.Skip(vertlimit).ToList() }; vertcount = vertlimit; } break; case ChunkType.End: break; default: throw new NotSupportedException("Unsupported chunk type " + Type + "."); } SetVertCount(vertcount); switch (Type) { case ChunkType.Vertex_Vertex: Size = (ushort)(vertcount * 3 + 1); break; case ChunkType.Vertex_VertexSH: case ChunkType.Vertex_VertexDiffuse8: case ChunkType.Vertex_VertexUserFlags: case ChunkType.Vertex_VertexNinjaFlags: case ChunkType.Vertex_VertexDiffuseSpecular5: case ChunkType.Vertex_VertexDiffuseSpecular4: Size = (ushort)(vertcount * 4 + 1); break; case ChunkType.Vertex_VertexNormal: Size = (ushort)(vertcount * 6 + 1); break; case ChunkType.Vertex_VertexNormalDiffuse8: case ChunkType.Vertex_VertexNormalUserFlags: case ChunkType.Vertex_VertexNormalNinjaFlags: case ChunkType.Vertex_VertexNormalDiffuseSpecular5: case ChunkType.Vertex_VertexNormalDiffuseSpecular4: Size = (ushort)(vertcount * 7 + 1); break; case ChunkType.Vertex_VertexNormalSH: Size = (ushort)(vertcount * 8 + 1); break; } List <byte> result = new List <byte>((Size * 4) + 4); result.AddRange(ByteConverter.GetBytes(Header1)); result.AddRange(ByteConverter.GetBytes(Header2)); for (int i = 0; i < vertcount; i++) { switch (Type) { case ChunkType.Vertex_VertexSH: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(1.0f)); break; case ChunkType.Vertex_VertexNormalSH: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(1.0f)); result.AddRange(Normals[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(1.0f)); break; case ChunkType.Vertex_Vertex: result.AddRange(Vertices[i].GetBytes()); break; case ChunkType.Vertex_VertexDiffuse8: result.AddRange(Vertices[i].GetBytes()); result.AddRange(VColor.GetBytes(Diffuse[i], ColorType.ARGB8888_32)); break; case ChunkType.Vertex_VertexUserFlags: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(UserFlags[i])); break; case ChunkType.Vertex_VertexNinjaFlags: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(NinjaFlags[i])); break; case ChunkType.Vertex_VertexDiffuseSpecular5: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes( ByteConverter.ToUInt16(VColor.GetBytes(Diffuse[i], ColorType.RGB565), 0) | (ByteConverter.ToUInt16(VColor.GetBytes(Specular[i], ColorType.RGB565), 0) << 16))); break; case ChunkType.Vertex_VertexDiffuseSpecular4: result.AddRange(Vertices[i].GetBytes()); result.AddRange(ByteConverter.GetBytes( ByteConverter.ToUInt16(VColor.GetBytes(Diffuse[i], ColorType.ARGB4444), 0) | (ByteConverter.ToUInt16(VColor.GetBytes(Specular[i], ColorType.RGB565), 0) << 16))); break; case ChunkType.Vertex_VertexNormal: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); break; case ChunkType.Vertex_VertexNormalDiffuse8: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); result.AddRange(VColor.GetBytes(Diffuse[i], ColorType.ARGB8888_32)); break; case ChunkType.Vertex_VertexNormalUserFlags: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(UserFlags[i])); break; case ChunkType.Vertex_VertexNormalNinjaFlags: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); result.AddRange(ByteConverter.GetBytes(NinjaFlags[i])); break; case ChunkType.Vertex_VertexNormalDiffuseSpecular5: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); result.AddRange(ByteConverter.GetBytes( ByteConverter.ToUInt16(VColor.GetBytes(Diffuse[i], ColorType.RGB565), 0) | (ByteConverter.ToUInt16(VColor.GetBytes(Specular[i], ColorType.RGB565), 0) << 16))); break; case ChunkType.Vertex_VertexNormalDiffuseSpecular4: result.AddRange(Vertices[i].GetBytes()); result.AddRange(Normals[i].GetBytes()); result.AddRange(ByteConverter.GetBytes( ByteConverter.ToUInt16(VColor.GetBytes(Diffuse[i], ColorType.ARGB4444), 0) | (ByteConverter.ToUInt16(VColor.GetBytes(Specular[i], ColorType.RGB565), 0) << 16))); break; } } if (next != null) { result.AddRange(next.GetBytes()); } return(result.ToArray()); }
public PolyChunkMaterial(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); Size = ByteConverter.ToUInt16(file, address); address += sizeof(ushort); switch (Type) { case ChunkType.Material_Diffuse: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: Diffuse = VColor.FromBytes(file, address, ColorType.ARGB8888_16); address += VColor.Size(ColorType.ARGB8888_16); break; } switch (Type) { case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: Ambient = VColor.FromBytes(file, address, ColorType.XRGB8888_16); address += VColor.Size(ColorType.XRGB8888_16); break; } switch (Type) { case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: Specular = VColor.FromBytes(file, address, ColorType.XRGB8888_16); SpecularExponent = (byte)(ByteConverter.ToUInt16(file, address + 2) >> 8); address += VColor.Size(ColorType.XRGB8888_16); break; } switch (Type) { case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: Second = true; break; } }
// Scan for Motions static void ScanMotions() { CurrentStep++; CurrentScanData = "Motions" + (ModelParts > 0 ? " with " + ModelParts.ToString() + " or more nodes" : ""); Console.WriteLine("Step {0}: Scanning for motions with at least {1} model parts... ", CurrentStep, ModelParts); if (ShortRot) { Console.WriteLine("Using short rotations"); } ByteConverter.BigEndian = BigEndian; if (!SingleOutputFolder) { Directory.CreateDirectory(Path.Combine(OutputFolder, "actions")); } for (uint address = StartAddress; address < EndAddress; address += 1) { if (CancelScan) { break; } if (ConsoleMode && address % 1000 == 0) { Console.Write("\r{0} ", address.ToString("X8")); } CurrentAddress = address; // Check for a valid MDATA pointer uint mdatap = ByteConverter.ToUInt32(datafile, (int)address); if (mdatap < ImageBase || mdatap >= datafile.Length - 12 + ImageBase || mdatap == 0) { //Console.WriteLine("Mdatap {0} fail", mdatap.ToString("X8")); continue; } uint frames = ByteConverter.ToUInt32(datafile, (int)address + 4); if (frames > 2000 || frames < 1) { //Console.WriteLine("Frames {0} fail", frames.ToString()); continue; } AnimFlags animtype = (AnimFlags)ByteConverter.ToUInt16(datafile, (int)address + 8); if (animtype == 0) { continue; } int mdata = 0; //Console.WriteLine("Flags: {0}", animtype.ToString()); if (animtype.HasFlag(AnimFlags.Position)) { mdata++; } if (animtype.HasFlag(AnimFlags.Rotation)) { mdata++; } if (animtype.HasFlag(AnimFlags.Scale)) { mdata++; } if (animtype.HasFlag(AnimFlags.Vector)) { mdata++; } if (animtype.HasFlag(AnimFlags.Vertex)) { mdata++; } if (animtype.HasFlag(AnimFlags.Normal)) { mdata++; } if (animtype.HasFlag(AnimFlags.Color)) { continue; } if (animtype.HasFlag(AnimFlags.Intensity)) { continue; } if (animtype.HasFlag(AnimFlags.Target)) { continue; } if (animtype.HasFlag(AnimFlags.Spot)) { continue; } if (animtype.HasFlag(AnimFlags.Point)) { continue; } if (animtype.HasFlag(AnimFlags.Roll)) { continue; } int mdatasize = 0; bool lost = false; switch (mdata) { case 1: case 2: mdatasize = 16; break; case 3: mdatasize = 24; break; case 4: mdatasize = 32; break; case 5: mdatasize = 40; break; default: lost = true; break; } if (lost) { continue; } // Check MKEY pointers int mdatas = 0; for (int u = 0; u < 255; u++) { for (int m = 0; m < mdata; m++) { if (lost) { continue; } uint pointer = ByteConverter.ToUInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * m); if (pointer < ImageBase || pointer >= datafile.Length - 8 + ImageBase) { if (pointer != 0) { lost = true; //Console.WriteLine("Mkey pointer {0} lost", pointer.ToString("X8")); } } if (!lost) { // Read frame count int framecount = ByteConverter.ToInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * mdata + 4 * m); if (framecount < 0 || framecount > 2000) { //Console.WriteLine("Framecount lost: {0}", framecount.ToString("X8")); lost = true; } if (pointer == 0 && framecount != 0) { //Console.WriteLine("Framecount non zero"); lost = true; } //if (!lost) Console.WriteLine("Mdata size: {0}, MkeyP: {1}, Frames: {2}", mdatasize, pointer.ToString("X8"), framecount.ToString()); } } if (!lost) { mdatas++; //Console.WriteLine("Mdata {0}, total {1}", u, mdatas); } } if (mdatas > 0 && mdatas >= ModelParts) { try { Console.WriteLine("\rAdding motion at {0}: {1} nodes", address.ToString("X8"), mdatas); //Console.WriteLine("trying Address: {0}, MdataP: {1}, mdatas: {2}", address.ToString("X8"), mdatap.ToString("X8"), mdata); NJS_MOTION mot = NJS_MOTION.ReadDirect(datafile, mdatas, (int)address, ImageBase, new Dictionary <int, Attach>(), ShortRot); if (mot.ModelParts <= 0) { continue; } if (mot.Frames <= 0) { continue; } if (mot.Models.Count == 0) { continue; } string fileOutputPath = Path.Combine(OutputFolder, "actions", address.ToString("X8") + ".saanim"); if (SingleOutputFolder) { fileOutputPath = Path.Combine(OutputFolder, address.ToString("X8") + ".saanim"); } mot.Save(fileOutputPath, NoMeta); FoundMotions++; addresslist.Add(address, "NJS_MOTION"); uint[] arr = new uint[2]; arr[0] = address; arr[1] = (uint)mot.ModelParts; actionlist.Add(address, arr); } catch (Exception ex) { Console.WriteLine("\rError adding motion at {0}: {1}", address.ToString("X8"), ex.Message); } } } Console.WriteLine("\rFound {0} motions", FoundMotions); }
public Strip(byte[] file, int address, ChunkType type, byte userFlags) { Indexes = new ushort[Math.Abs(ByteConverter.ToInt16(file, address))]; Reversed = (ByteConverter.ToUInt16(file, address) & 0x8000) == 0x8000; address += 2; switch (type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: UVs = new UV[Indexes.Length]; break; case ChunkType.Strip_StripColor: VColors = new Color[Indexes.Length]; break; case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: UVs = new UV[Indexes.Length]; VColors = new Color[Indexes.Length]; break; } if (userFlags > 0) { UserFlags1 = new ushort[Indexes.Length - 2]; } if (userFlags > 1) { UserFlags2 = new ushort[Indexes.Length - 2]; } if (userFlags > 2) { UserFlags3 = new ushort[Indexes.Length - 2]; } for (int i = 0; i < Indexes.Length; i++) { Indexes[i] = ByteConverter.ToUInt16(file, address); address += 2; switch (type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVN2: UVs[i] = new UV(file, address, false, true); address += UV.Size; break; case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_StripUVH2: UVs[i] = new UV(file, address, true, true); address += UV.Size; break; } switch (type) { case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: VColors[i] = VColor.FromBytes(file, address, ColorType.ARGB8888_16); address += VColor.Size(ColorType.ARGB8888_16); break; } if (i > 1) { if (userFlags > 0) { UserFlags1[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; if (userFlags > 1) { UserFlags2[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; if (userFlags > 2) { UserFlags3[i - 2] = ByteConverter.ToUInt16(file, address); address += 2; } } } } } }
public PolyChunkBitsSpecularExponent(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); }
public PolyChunkBitsMipmapDAdjust(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); }
public PolyChunkBitsBlendAlpha(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); }
public PolyChunkEnd(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); }
public static PolyChunk Load(byte[] file, int address) { ChunkType type = (ChunkType)(ByteConverter.ToUInt16(file, address) & 0xFF); switch (type) { case ChunkType.Null: return(new PolyChunkNull(file, address)); case ChunkType.Bits_BlendAlpha: return(new PolyChunkBitsBlendAlpha(file, address)); case ChunkType.Bits_MipmapDAdjust: return(new PolyChunkBitsMipmapDAdjust(file, address)); case ChunkType.Bits_SpecularExponent: return(new PolyChunkBitsSpecularExponent(file, address)); case ChunkType.Bits_CachePolygonList: return(new PolyChunkBitsCachePolygonList(file, address)); case ChunkType.Bits_DrawPolygonList: return(new PolyChunkBitsDrawPolygonList(file, address)); case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: return(new PolyChunkTinyTextureID(file, address)); case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: return(new PolyChunkMaterial(file, address)); case ChunkType.Material_Bump: return(new PolyChunkMaterialBump(file, address)); case ChunkType.Volume_Polygon3: case ChunkType.Volume_Polygon4: case ChunkType.Volume_Strip: return(new PolyChunkVolume(file, address)); case ChunkType.Strip_Strip: case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_Strip2: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: return(new PolyChunkStrip(file, address)); case ChunkType.End: return(new PolyChunkEnd(file, address)); default: throw new NotSupportedException("Unsupported chunk type " + type + " at " + address.ToString("X8") + "."); } }
public PolyChunkTinyTextureID(byte[] file, int address) { Header = ByteConverter.ToUInt16(file, address); Second = Type == ChunkType.Tiny_TextureID2; Data = ByteConverter.ToUInt16(file, address + 2); }
public static Color FromBytes(byte[] file, int address, ColorType type) { switch (type) { case ColorType.RGBA8888_32: if (address > file.Length - 4) { return(Color.FromArgb(0, 0, 0, 0)); } return(Color.FromArgb(file[address + 3], file[address], file[address + 1], file[address + 2])); case ColorType.ARGB8888_32: if (address > file.Length - 4) { return(Color.FromArgb(0, 0, 0, 0)); } // "Reverse" mode is for SADX Gamecube/SA2B/SA2PC where the color order is ABGR if (ByteConverter.BigEndian) { if (ByteConverter.Reverse) { return(Color.FromArgb(file[address + 3], file[address], file[address + 1], file[address + 2])); } else { return(Color.FromArgb(file[address], file[address + 1], file[address + 2], file[address + 3])); } } else if (ByteConverter.Reverse) { return(Color.FromArgb(file[address], file[address + 3], file[address + 2], file[address + 1])); } else { return(Color.FromArgb(file[address + 3], file[address + 2], file[address + 1], file[address])); } case ColorType.XRGB8888_32: return(Color.FromArgb(unchecked ((int)(ByteConverter.ToUInt32(file, address) | 0xFF000000u)))); case ColorType.ARGB8888_16: return(Color.FromArgb((ByteConverter.ToUInt16(file, address + 2) << 16) | ByteConverter.ToUInt16(file, address))); case ColorType.XRGB8888_16: return(Color.FromArgb(unchecked ((int)((uint)((ByteConverter.ToUInt16(file, address + 2) << 16) | ByteConverter.ToUInt16(file, address)) | 0xFF000000u)))); case ColorType.ARGB4444: ushort value = ByteConverter.ToUInt16(file, address); int a = value >> 12; int r = (value >> 8) & 0xF; int g = (value >> 4) & 0xF; int b = value & 0xF; return(Color.FromArgb( a | (a << 4), r | (r << 4), g | (g << 4), b | (b << 4) )); case ColorType.RGB565: value = ByteConverter.ToUInt16(file, address); r = value >> 11; g = (value >> 5) & 0x3F; b = value & 0x1F; return(Color.FromArgb( r << 3 | r >> 2, g << 2 | g >> 4, b << 3 | b >> 2 )); } throw new ArgumentOutOfRangeException("type"); }
public NJS_MESHSET(byte[] file, int address, uint imageBase, Dictionary <int, string> labels) { MaterialID = ByteConverter.ToUInt16(file, address); PolyType = (Basic_PolyType)(MaterialID >> 0xE); MaterialID &= 0x3FFF; Poly[] polys = new Poly[ByteConverter.ToInt16(file, address + 2)]; int tmpaddr = (int)(ByteConverter.ToUInt32(file, address + 4) - imageBase); if (labels.ContainsKey(tmpaddr)) { PolyName = labels[tmpaddr]; } else { PolyName = "poly_" + tmpaddr.ToString("X8"); } int striptotal = 0; for (int i = 0; i < polys.Length; i++) { polys[i] = SAModel.Poly.CreatePoly(PolyType, file, tmpaddr); striptotal += polys[i].Indexes.Length; tmpaddr += polys[i].Size; } Poly = new ReadOnlyCollection <Poly>(polys); PAttr = ByteConverter.ToInt32(file, address + 8); tmpaddr = ByteConverter.ToInt32(file, address + 0xC); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { PolyNormalName = labels[tmpaddr]; } else { PolyNormalName = "polynormal_" + tmpaddr.ToString("X8"); } PolyNormal = new Vertex[polys.Length]; for (int i = 0; i < polys.Length; i++) { PolyNormal[i] = new Vertex(file, tmpaddr); tmpaddr += Vertex.Size; } } else { PolyNormalName = "polynormal_" + Extensions.GenerateIdentifier(); } tmpaddr = ByteConverter.ToInt32(file, address + 0x10); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { VColorName = labels[tmpaddr]; } else { VColorName = "vcolor_" + tmpaddr.ToString("X8"); } VColor = new Color[striptotal]; for (int i = 0; i < striptotal; i++) { VColor[i] = SAModel.VColor.FromBytes(file, tmpaddr); tmpaddr += SAModel.VColor.Size(ColorType.ARGB8888_32); } } else { VColorName = "vcolor_" + Extensions.GenerateIdentifier(); } tmpaddr = ByteConverter.ToInt32(file, address + 0x14); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { UVName = labels[tmpaddr]; } else { UVName = "uv_" + tmpaddr.ToString("X8"); } UV = new UV[striptotal]; for (int i = 0; i < striptotal; i++) { UV[i] = new UV(file, tmpaddr); tmpaddr += SAModel.UV.Size; } } else { UVName = "uv_" + Extensions.GenerateIdentifier(); } }