public SDATInfo(NitroFile sdat, uint offset)
            {
                m_Offset       = offset;
                m_Type         = sdat.ReadString(m_Offset + 0x00, 4).ToCharArray();
                m_Size         = sdat.Read32(m_Offset + 0x04);
                m_RecordOffset = new uint[8];
                for (int i = 0; i < 8; i++)
                {
                    m_RecordOffset[i] = sdat.Read32(m_Offset + 0x08 + (uint)(i * 4));
                }
                m_Reserved = sdat.ReadBlock(m_Offset + 0x28, 24);

                m_Records = new SDATInfoRecord[8];
                for (int i = 0; i < 8; i++)
                {
                    m_Records[i] = new SDATInfoRecord(sdat, m_Offset + m_RecordOffset[i]);
                }
                m_Records0SEQ = new SDATInfoSEQ[m_Records[0].m_Count];
                for (int i = 0; i < m_Records[0].m_Count; i++)
                {
                    m_Records0SEQ[i] = new SDATInfoSEQ(sdat, m_Offset + m_Records[0].m_EntryOffset[i]);
                }
                m_Records1SEQARC = new SDATInfoSEQARC[m_Records[1].m_Count];
                for (int i = 0; i < m_Records[1].m_Count; i++)
                {
                    m_Records1SEQARC[i] = new SDATInfoSEQARC(sdat, m_Offset + m_Records[1].m_EntryOffset[i]);
                }
                m_Records2BANK = new SDATInfoBANK[m_Records[2].m_Count];
                for (int i = 0; i < m_Records[2].m_Count; i++)
                {
                    m_Records2BANK[i] = new SDATInfoBANK(sdat, m_Offset + m_Records[2].m_EntryOffset[i]);
                }
                m_Records3WAVEARC = new SDATInfoWAVEARC[m_Records[3].m_Count];
                for (int i = 0; i < m_Records[3].m_Count; i++)
                {
                    m_Records3WAVEARC[i] = new SDATInfoWAVEARC(sdat, m_Offset + m_Records[3].m_EntryOffset[i]);
                }
                m_Records4PLAYER = new SDATInfoPLAYER[m_Records[4].m_Count];
                for (int i = 0; i < m_Records[4].m_Count; i++)
                {
                    m_Records4PLAYER[i] = new SDATInfoPLAYER(sdat, m_Offset + m_Records[4].m_EntryOffset[i]);
                }
                m_Records5GROUP = new SDATInfoGROUP[m_Records[5].m_Count];
                for (int i = 0; i < m_Records[5].m_Count; i++)
                {
                    m_Records5GROUP[i] = new SDATInfoGROUP(sdat, m_Offset + m_Records[5].m_EntryOffset[i]);
                }
                m_Records6PLAYER2 = new SDATInfoPLAYER2[m_Records[6].m_Count];
                for (int i = 0; i < m_Records[6].m_Count; i++)
                {
                    m_Records6PLAYER2[i] = new SDATInfoPLAYER2(sdat, m_Offset + m_Records[6].m_EntryOffset[i]);
                }
                m_Records7STREAM = new SDATInfoSTREAM[m_Records[7].m_Count];
                for (int i = 0; i < m_Records[7].m_Count; i++)
                {
                    m_Records7STREAM[i] = new SDATInfoSTREAM(sdat, m_Offset + m_Records[7].m_EntryOffset[i]);
                }
            }
 public SDATInfoRecord(NitroFile sdat, uint offset)
 {
     m_Offset      = offset;
     m_Count       = sdat.Read32(m_Offset);
     m_EntryOffset = new uint[m_Count];
     for (int i = 0; i < m_Count; i++)
     {
         m_EntryOffset[i] = sdat.Read32(m_Offset + 0x04 + (uint)(i * 4));
     }
 }
예제 #3
0
        private void UpdateEntries(String msg, int index)
        {
            m_MsgData[index]       = msg;
            m_ShortVersions[index] = ShortVersion(msg, index);
            int lengthDif = EncodeString(msg).Count - m_StringLengths[index];

            m_StringLengths[index] += lengthDif;

            //Make or remove room for the new string if needed (don't need to for last entry)
            if (lengthDif > 0 && index != m_MsgData.Length - 1)
            {
                uint   curStringStart  = m_StringHeaderData[index] + m_DAT1Start;
                uint   nextStringStart = m_StringHeaderData[index + 1] + m_DAT1Start;
                byte[] followingData   = file.ReadBlock(nextStringStart, (uint)(file.m_Data.Length - nextStringStart));
                for (int i = (int)curStringStart; i < (int)nextStringStart + lengthDif; i++)
                {
                    file.Write8((uint)i, 0);// Fill the gap with zeroes
                }
                file.WriteBlock((uint)(nextStringStart + lengthDif), followingData);
            }
            else if (lengthDif < 0 && index != m_MsgData.Length - 1)
            {
                // lengthDif is negative, -- +
                uint   nextStringStart = m_StringHeaderData[index + 1] + m_DAT1Start;
                byte[] followingData   = file.ReadBlock(nextStringStart, (uint)(file.m_Data.Length - nextStringStart));
                file.WriteBlock((uint)(nextStringStart + lengthDif), followingData);
                int oldSize = file.m_Data.Length;
                Array.Resize(ref file.m_Data, oldSize + lengthDif);// Remove duplicate data at end of file
            }

            // Update pointers to string entry data
            if (lengthDif != 0)
            {
                for (int i = index + 1; i < m_MsgData.Length; i++)
                {
                    if (lengthDif > 0)
                    {
                        m_StringHeaderData[i] += (uint)lengthDif;
                    }
                    else if (lengthDif < 0)
                    {
                        m_StringHeaderData[i] = (uint)(m_StringHeaderData[i] + lengthDif);
                    }

                    file.Write32(m_StringHeaderAddr[i], m_StringHeaderData[i]);
                    file.Write16(m_StringWidthAddr[i], m_StringWidth[i]);
                    file.Write16(m_StringHeightAddr[i], m_StringHeight[i]);
                }
            }
            // Update total file size
            file.Write32(0x08, (uint)(int)(file.Read32(0x08) + lengthDif));
            // Update DAT1 size
            file.Write32(m_DAT1Start - 0x04, (uint)(int)(file.Read32(m_DAT1Start - 0x04) + lengthDif));
        }
예제 #4
0
파일: KCL.cs 프로젝트: RicoPlays/sm64dse
            public OctreeNode(NitroFile file, uint baseoffset, uint offset, Vector3 pos, Vector3 size)
            {
                m_Pos       = pos;
                m_Size      = size;
                m_LOL       = false;
                m_PlaneList = new List <int>();

                uint node = file.Read32(offset);

                if ((node & 0x80000000) != 0)
                {
                    uint   lolz = baseoffset + (node & 0x7FFFFFFF) + 2;
                    int    n    = 0;
                    string lmao = "";
                    for (; ;)
                    {
                        ushort p = file.Read16(lolz);
                        if (p == 0)
                        {
                            break;
                        }
                        else if (p == 37)
                        {
                            m_LOL = true;
                        }

                        m_PlaneList.Add(p - 1);
                        lmao += (p - 1).ToString() + " ";
                        lolz += 2;
                        n++;
                    }

                    if (n > maxkids)
                    {
                        maxkids = n;
                    }

                    //if (m_LOL)
                    //   MessageBox.Show(lmao);

                    m_NumPlanes = n;
                    OctreeNode.m_List.Add(this);
                }
                else
                {
                    uint parentoffset = baseoffset + node;
                    uint child0offset = parentoffset;
                    size /= 2f;
                    for (int z = 0; z < 2; z++)
                    {
                        for (int y = 0; y < 2; y++)
                        {
                            for (int x = 0; x < 2; x++)
                            {
                                new OctreeNode(file, child0offset, parentoffset, pos + new Vector3(size.X * x, size.Y * y, size.Z * z), size); parentoffset += 4;
                            }
                        }
                    }
                }
            }
            public byte[] m_Reserved;      // unused, 0s	(16)

            public SDATHeader(NitroFile sdat)
            {
                m_Type            = sdat.ReadBlock(0x00, 4);
                m_Magic           = sdat.Read32(0x04);
                m_FileSize        = sdat.Read32(0x08);
                m_Size            = sdat.Read16(0x0C);
                m_Block           = sdat.Read16(0x0E);
                m_SymbolOffset    = sdat.Read32(0x10);
                m_SymbolSize      = sdat.Read32(0x14);
                m_InfoOffset      = sdat.Read32(0x18);
                m_InfoSize        = sdat.Read32(0x1C);
                m_FatOffset       = sdat.Read32(0x20);
                m_FatSize         = sdat.Read32(0x24);
                m_FileBlockOffset = sdat.Read32(0x28);
                m_FileBlockSize   = sdat.Read32(0x2C);
                m_Reserved        = sdat.ReadBlock(0x30, 16);
            }
예제 #6
0
            public byte[] m_Type; // 'SDAT' (4)

            #endregion Fields

            #region Constructors

            public SDATHeader(NitroFile sdat)
            {
                m_Type = sdat.ReadBlock(0x00, 4);
                m_Magic = sdat.Read32(0x04);
                m_FileSize = sdat.Read32(0x08);
                m_Size = sdat.Read16(0x0C);
                m_Block = sdat.Read16(0x0E);
                m_SymbolOffset = sdat.Read32(0x10);
                m_SymbolSize = sdat.Read32(0x14);
                m_InfoOffset = sdat.Read32(0x18);
                m_InfoSize = sdat.Read32(0x1C);
                m_FatOffset = sdat.Read32(0x20);
                m_FatSize = sdat.Read32(0x24);
                m_FileBlockOffset = sdat.Read32(0x28);
                m_FileBlockSize = sdat.Read32(0x2C);
                m_Reserved = sdat.ReadBlock(0x30, 16);
            }
                public SDATInfoPLAYER(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_SequenceMax         = sdat.Read8(m_Offset + 0x00);
                    m_Padding             = sdat.Read8(m_Offset + 0x01);
                    m_AllocChannelBitFlag = sdat.Read16(m_Offset + 0x02);
                    m_HeapSize            = sdat.Read32(m_Offset + 0x04);
                }
                    /* Value	Type
                     * 0x0700	SEQ
                     * 0x0803	SEQARC
                     * 0x0601	BANK
                     * 0x0402	WAVEARC
                     *
                     * m_Index is the entry number in the relevant Record (SEQ/SEQARC/BANK/WAVEARC).
                     */

                    public GroupEntry(NitroFile sdat, uint offset)
                    {
                        m_Offset = offset;

                        m_Type     = sdat.Read8(m_Offset + 0x00);
                        m_LoadFlag = sdat.Read8(m_Offset + 0x01);
                        m_Padding  = sdat.Read16(m_Offset + 0x02);
                        m_Index    = sdat.Read32(m_Offset + 0x04);
                    }
                public SDATInfoBANK(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID  = sdat.Read32(m_Offset + 0x00);
                    m_WaveArc = new ushort[4];
                    for (int i = 0; i < 4; i++)
                    {
                        m_WaveArc[i] = sdat.Read16(m_Offset + 0x04 + (uint)(i * 2));
                    }
                }
                public SDATInfoWAVEARC(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    uint num = sdat.Read32(m_Offset + 0x00);

                    m_FileID = (num & 16777215u);
                    m_Flag   = (byte)(num >> 24);

                    //er.Write((uint)((long)((long)this.flags << 24) | (long)((ulong)(this.fileID & 16777215u))));
                }
                public SDATInfoGROUP(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_Count        = sdat.Read32(m_Offset + 0x00);
                    m_GroupEntries = new GroupEntry[m_Count];
                    for (int i = 0; i < m_Count; i++)
                    {
                        m_GroupEntries[i] = new GroupEntry(sdat, m_Offset + 0x04 + (uint)(i * 8));
                    }
                }
                public SDATInfoSEQ(NitroFile sdat, uint offset)
                {
                    m_File   = sdat;
                    m_Offset = offset;

                    m_FileID          = sdat.Read32(m_Offset + 0x00);
                    m_Bank            = sdat.Read16(m_Offset + 0x04);
                    m_Volume          = sdat.Read8(m_Offset + 0x06);
                    m_ChannelPriority = sdat.Read8(m_Offset + 0x07);
                    m_PlayerPriority  = sdat.Read8(m_Offset + 0x08);
                    m_PlayerNumber    = sdat.Read8(m_Offset + 0x09);
                    m_Unknown2        = sdat.ReadBlock(m_Offset + 0x0A, 2);
                }
                public SDATInfoSTREAM(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID         = sdat.Read32(m_Offset + 0x00);
                    m_Volume         = sdat.Read8(m_Offset + 0x04);
                    m_PlayerPriority = sdat.Read8(m_Offset + 0x05);
                    m_PlayerNumber   = sdat.Read8(m_Offset + 0x06);
                    m_Reserved       = new byte[5];
                    for (int i = 0; i < 5; i++)
                    {
                        m_Reserved[i] = sdat.Read8(m_Offset + 0x07 + (uint)(i));
                    }
                }
예제 #14
0
        private void WriteChanges()
        {
            NitroFile kclFile = m_KCL.m_File;

            uint planeStart = (kclFile.Read32(8));

            planeStart += (uint)(0x10);

            for (int i = 0; i < m_Planes.Count; i++)
            {
                uint posColType = (uint)(planeStart + (i * 16) + 0x0E); //Get the address of this plane's Collision Type variable

                kclFile.Write16(posColType, (ushort)m_Planes[i].type);  //Write the new value to file
            }

            kclFile.SaveChanges();
        }
예제 #15
0
        public void LoadTexture()
        {
            //Console.WriteLine($"offset = 0x{Convert.ToString(offset, 16)}");
            if (m_ParticleTexFile.Read32(0x0) != 0x53505420)
            {
                MessageBox.Show(string.Format("This SPT file is invalid."),
                                "Bad texture");
                Close();
                return;
            }

            uint flags        = m_ParticleTexFile.Read32(0x04);
            uint texelArrSize = m_ParticleTexFile.Read32(0x08);
            uint palOffset    = m_ParticleTexFile.Read32(0x0c);
            uint palSize      = m_ParticleTexFile.Read32(0x10);
            uint totalSize    = m_ParticleTexFile.Read32(0x1c);

            byte[] texels  = m_ParticleTexFile.ReadBlock(0x20, texelArrSize);
            byte[] palette = m_ParticleTexFile.ReadBlock(palOffset, palSize);

            int  width        = 1 << (((int)flags >> 4 & 0xf) + 3);
            int  height       = 1 << (((int)flags >> 8 & 0xf) + 3);
            bool color0Transp = ((flags & 0x8) | (flags & 0x10000)) != 0;
            int  type         = (int)flags & 0x7;

            Particle.Texture.RepeatMode repeatX = (flags & 0x4000) != 0 ?
                                                  Particle.Texture.RepeatMode.FLIP : (flags & 0x1000) != 0 ?
                                                  Particle.Texture.RepeatMode.REPEAT :
                                                  Particle.Texture.RepeatMode.CLAMP;
            Particle.Texture.RepeatMode repeatY = (flags & 0x8000) != 0 ?
                                                  Particle.Texture.RepeatMode.FLIP : (flags & 0x2000) != 0 ?
                                                  Particle.Texture.RepeatMode.REPEAT :
                                                  Particle.Texture.RepeatMode.CLAMP;

            m_Texture = new Particle.Texture(texels, palette, width, height,
                                             (byte)(color0Transp ? 1 : 0), type, repeatX, repeatY, 0);
        }
예제 #16
0
파일: KCL.cs 프로젝트: RicoPlays/sm64dse
        public KCL(NitroFile file)
        {
            m_File = file;

            m_Planes = new List<ColFace>();

            m_PointsSectionOffset = m_File.Read32(0x00);
            m_NormalsSectionOffset = m_File.Read32(0x04);
            m_PlanesSectionOffset = m_File.Read32(0x08);
            m_OctreeSectionOffset = m_File.Read32(0x0C);

            int planeid = 0;
            for (uint offset = m_PlanesSectionOffset + 0x10; offset < m_OctreeSectionOffset; offset += 0x10)
            {
                uint length = m_File.Read32(offset);

                ushort pt_id = m_File.Read16(offset + 0x04);
                int pt_x = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id*12)    ));
                int pt_y = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id*12) + 4));
                int pt_z = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id*12) + 8));

                ushort nr_id = m_File.Read16(offset + 0x06);
                short nr_x = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id*6)    ));
                short nr_y = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id*6) + 2));
                short nr_z = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id*6) + 4));

                ushort d1_id = m_File.Read16(offset + 0x08);
                short d1_x = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id*6)    ));
                short d1_y = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id*6) + 2));
                short d1_z = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id*6) + 4));

                ushort d2_id = m_File.Read16(offset + 0x0A);
                short d2_x = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id*6)    ));
                short d2_y = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id*6) + 2));
                short d2_z = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id*6) + 4));

                ushort d3_id = m_File.Read16(offset + 0x0C);
                short d3_x = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id*6)    ));
                short d3_y = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id*6) + 2));
                short d3_z = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id*6) + 4));

                ColFace plane = new ColFace((float)(length / 65536000f),
                    new Vector3((float)pt_x / 64000f, (float)pt_y / 64000f, (float)pt_z / 64000f),
                    new Vector3((float)nr_x / 1024f, (float)nr_y / 1024f, (float)nr_z / 1024f),
                    new Vector3((float)d1_x / 1024f, (float)d1_y / 1024f, (float)d1_z / 1024f),
                    new Vector3((float)d2_x / 1024f, (float)d2_y / 1024f, (float)d2_z / 1024f),
                    new Vector3((float)d3_x / 1024f, (float)d3_y / 1024f, (float)d3_z / 1024f),
                    m_File.Read16(offset + 0x0E));

               /* if (planeid == 31)
                    MessageBox.Show(string.Format("PLANE 32:\n{0}\n{1}\n{2}\n\n{3}\n{4}\n{5}\n\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}",
                        d1_x, d1_y, d1_z,
                        d2_x, d2_y, d2_z,
                        plane.m_Position, plane.m_Normal, plane.m_Dir1, plane.m_Dir2, plane.m_Dir3, plane.m_Length));*/

                planeid++;

               /* if (Math.Abs(plane.m_Dir1.Length - 1f) > 0.0001f || Math.Abs(plane.m_Dir2.Length - 1f) > 0.0001f ||
                    Math.Abs(plane.m_Dir3.Length - 1f) > 0.0001f || Math.Abs(plane.m_Normal.Length - 1f) > 0.0001f ||
                    plane.m_Length < 0f)
                    MessageBox.Show(string.Format("WRONG PLANE | {0} | {1} | {2} | {3} | {4}",
                        plane.m_Dir1.Length, plane.m_Dir2.Length, plane.m_Dir3.Length, plane.m_Normal.Length, plane.m_Length));

                if (plane.m_Dir1.Length < 0.001f || plane.m_Dir2.Length < 0.001f ||
                    plane.m_Dir3.Length < 0.001f || plane.m_Normal.Length < 0.001f ||
                    Math.Abs(plane.m_Length) < 0.001f)
                    MessageBox.Show(string.Format("ZERO PLANE | {0} | {1} | {2} | {3} | {4}",
                        plane.m_Dir1.Length, plane.m_Dir2.Length, plane.m_Dir3.Length, plane.m_Normal.Length, plane.m_Length));

                Vector3 lol1 = Vector3.Cross(plane.m_Dir1, plane.m_Normal);
                float lol1len = plane.m_Length / (float)Math.Cos(Math.Acos(Math.Min(1f,Vector3.Dot(lol1, plane.m_Dir3))));
                Vector3 lol2 = Vector3.Cross(plane.m_Normal, plane.m_Dir2);
                float lol2len = plane.m_Length / (float)Math.Cos(Math.Acos(Math.Min(1f,Vector3.Dot(lol2, plane.m_Dir3))));
                if (Helper.VectorsEqual(plane.m_Position, Vector3.Multiply(lol1, lol1len)) ||
                    Helper.VectorsEqual(plane.m_Position, Vector3.Multiply(lol2, lol2len)))
                    MessageBox.Show(string.Format("WEIRD PLANE {5:X8} | {0} | {1} | {2} | {3} | {4}\n{6} | {7} / cos(acos({8})) = cos({9}) = {10}",
                        plane.m_Dir1, plane.m_Dir2, plane.m_Dir3, plane.m_Normal, plane.m_Length,
                        offset, lol2, plane.m_Length, Vector3.Dot(lol2, plane.m_Dir3), Math.Acos(Vector3.Dot(lol2, plane.m_Dir3)), Math.Cos(Math.Acos(Vector3.Dot(lol2, plane.m_Dir3)))));
                */
                m_Planes.Add(plane);
            }

            OctreeNode.maxkids = 0;
            int shift = (int)m_File.Read32(0x2C);
            Vector3 octreestart = new Vector3((float)(int)m_File.Read32(0x14) / 64000f, (float)(int)m_File.Read32(0x18) / 64000f, (float)(int)m_File.Read32(0x1C) / 64000f);
            float _cubesize = (float)(1 << shift) / 1024f;
            Vector3 cubesize = new Vector3(_cubesize, _cubesize, _cubesize);
            Vector3 octreesize = new Vector3((~m_File.Read32(0x20) >> shift) + 1, (~m_File.Read32(0x24) >> shift) + 1, (~m_File.Read32(0x28) >> shift) + 1);
            OctreeNode.m_List = new List<OctreeNode>();
            uint loloffset = m_OctreeSectionOffset;
            for (int z = 0; z < octreesize.Z; z++)
                for (int y = 0; y < octreesize.Y; y++)
                    for (int x = 0; x < octreesize.X; x++)
                    { new OctreeNode(m_File, m_OctreeSectionOffset, loloffset, octreestart + new Vector3(cubesize.X * x, cubesize.Y * y, cubesize.Z * z), cubesize); loloffset += 4; }

            //MessageBox.Show(OctreeNode.m_List.Count.ToString());
        }
예제 #17
0
        public BMD(NitroFile file)
        {
            m_File     = file;
            m_FileName = file.m_Name;

            /* if (m_File.m_ID == 741)
             *   lolol = true;
             * else*/
            lolol = false;

            // Keep a list of pointers so it's easier to add/remove entries, space etc.
            m_PointerList = new List <PointerReference>();

            m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0));

            // ModelChunk refers to Bone
            m_NumModelChunks    = m_File.Read32(0x04);
            m_ModelChunksOffset = m_File.Read32(0x08);
            AddPointer(0x08);
            for (int i = 0; i < m_NumModelChunks; i++)
            {
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38));
            }

            // PolyChunk refers to Display List
            m_NumPolyChunks    = m_File.Read32(0x0C);
            m_PolyChunksOffset = m_File.Read32(0x10);
            AddPointer(0x10);
            for (int i = 0; i < m_NumPolyChunks; i++)
            {
                // Offset to Display List within Display List entries
                AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4));
                // Offsets within the Display List 16 byte headers
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04);
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C);
            }
            m_NumTexChunks    = m_File.Read32(0x14);
            m_TexChunksOffset = m_File.Read32(0x18);
            m_TextureIDs      = new Dictionary <string, uint>();
            AddPointer(0x18);
            for (int i = 0; i < m_NumTexChunks; i++)
            {
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0));
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4));
                m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i);
            }
            m_NumPalChunks    = m_File.Read32(0x1C);
            m_PalChunksOffset = m_File.Read32(0x20);
            m_PaletteIDs      = new Dictionary <string, uint>();
            AddPointer(0x20);
            for (int i = 0; i < m_NumPalChunks; i++)
            {
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0));
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4));
                m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i);
            }
            m_NumMatChunks    = m_File.Read32(0x24);
            m_MatChunksOffset = m_File.Read32(0x28);
            AddPointer(0x28);
            for (int i = 0; i < m_NumMatChunks; i++)
            {
                AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0));
            }
            m_BoneMapOffset = m_File.Read32(0x2C);
            AddPointer(0x2C);

            m_Textures    = new Dictionary <string, NitroTexture>();
            m_ModelChunks = new ModelChunk[m_NumModelChunks];

            for (uint c = 0; c < m_NumModelChunks; c++)
            {
                ModelChunk mdchunk = new ModelChunk(this);
                m_ModelChunks[c] = mdchunk;

                uint mdchunkoffset = m_ModelChunksOffset + (c * 64);

                mdchunk.m_ID   = m_File.Read32(mdchunkoffset);
                mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0);

                // transforms part
                {
                    int   xscale = (int)m_File.Read32(mdchunkoffset + 0x10);
                    int   yscale = (int)m_File.Read32(mdchunkoffset + 0x14);
                    int   zscale = (int)m_File.Read32(mdchunkoffset + 0x18);
                    short xrot   = (short)m_File.Read16(mdchunkoffset + 0x1C);
                    short yrot   = (short)m_File.Read16(mdchunkoffset + 0x1E);
                    short zrot   = (short)m_File.Read16(mdchunkoffset + 0x20);
                    int   xtrans = (int)m_File.Read32(mdchunkoffset + 0x24);
                    int   ytrans = (int)m_File.Read32(mdchunkoffset + 0x28);
                    int   ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C);

                    mdchunk.m_Scale       = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f);
                    mdchunk.m_Rotation    = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f);
                    mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f);
                    mdchunk.m_Transform   = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation);

                    // Used when exporting bones
                    mdchunk.m_20_12Scale       = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale };
                    mdchunk.m_4_12Rotation     = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot };
                    mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans };

                    // if the chunk has a parent, apply the parent's transform to the chunk's transform.
                    // we don't need to go further than one level because the paren't transform already
                    // went through its parents' transforms.
                    short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8);
                    if (parent_offset < 0)
                    {
                        int parentchunkid = (int)(c + parent_offset);
                        Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform);
                    }
                    mdchunk.m_ParentOffset = parent_offset;
                }
                // If 0x0A is set to 1 the bone has children, if 0 it doesn't
                mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1);

                mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C));

                uint flags = m_File.Read32(mdchunkoffset + 0x3C);
                mdchunk.m_Billboard = ((flags & 0x1) == 0x1);

                uint numpairs = m_File.Read32(mdchunkoffset + 0x30);
                uint matlist  = m_File.Read32(mdchunkoffset + 0x34);
                uint polylist = m_File.Read32(mdchunkoffset + 0x38);

                mdchunk.m_MatGroups = new MaterialGroup[numpairs];

                for (uint i = 0; i < numpairs; i++)
                {
                    MaterialGroup matgroup = new MaterialGroup();
                    mdchunk.m_MatGroups[i] = matgroup;

                    byte matID  = m_File.Read8(matlist + i);
                    byte polyID = m_File.Read8(polylist + i);

                    uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48));

                    matgroup.m_ID   = matID;
                    matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0);
                    uint texid = m_File.Read32(mchunkoffset + 0x04);
                    uint palid = m_File.Read32(mchunkoffset + 0x08);
                    matgroup.m_TexParams    = m_File.Read32(mchunkoffset + 0x20);
                    matgroup.m_PolyAttribs  = m_File.Read32(mchunkoffset + 0x24);
                    matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28);
                    matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C);

                    if ((matgroup.m_PolyAttribs & 0x30) == 0x10)
                    {
                        matgroup.m_TexEnvMode = TextureEnvMode.Decal;
                    }
                    else
                    {
                        matgroup.m_TexEnvMode = TextureEnvMode.Modulate;
                    }

                    switch (matgroup.m_PolyAttribs & 0xC0)
                    {
                    case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break;

                    case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break;

                    case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break;
                    }

                    matgroup.m_DiffuseColor  = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors);
                    matgroup.m_AmbientColor  = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16));
                    matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors);
                    matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16));

                    switch (matgroup.m_TexParams >> 30)
                    {
                    case 0:
                        matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f);
                        matgroup.m_TexCoordRot   = 0.0f;
                        matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f);
                        break;

                    case 1:
                    {
                        int   sscale = (int)m_File.Read32(mchunkoffset + 0x0C);
                        int   tscale = (int)m_File.Read32(mchunkoffset + 0x10);
                        short trot   = (short)m_File.Read16(mchunkoffset + 0x14);
                        int   strans = (int)m_File.Read32(mchunkoffset + 0x18);
                        int   ttrans = (int)m_File.Read32(mchunkoffset + 0x1C);

                        matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f);
                        matgroup.m_TexCoordRot   = ((float)trot * (float)Math.PI) / 2048.0f;
                        matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f);
                    }
                    break;

                    case 2:
                        goto case 1;

                    case 3:
                        goto case 1;

                    default:
                        break;
                        // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30));
                    }

                    if (texid != 0xFFFFFFFF)
                    {
                        matgroup.m_Texture    = ReadTexture(texid, palid);
                        matgroup.m_TexParams |= matgroup.m_Texture.m_DSTexParam;
                    }
                    else
                    {
                        matgroup.m_Texture = null;
                    }

                    uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4));
                    uint dloffset     = m_File.Read32(pchunkoffset + 0x0C);
                    uint dlsize       = m_File.Read32(pchunkoffset + 0x08);
                    uint numbones     = m_File.Read32(pchunkoffset);
                    uint bonesoffset  = m_File.Read32(pchunkoffset + 0x04);

                    matgroup.m_BoneIDs = new ushort[numbones];
                    for (uint b = 0; b < numbones; b++)
                    {
                        byte idx1 = m_File.Read8(bonesoffset + b);
                        matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1)));
                    }

                    matgroup.m_Geometry = new List <VertexList>();

                    m_CurVertex.m_Position = new Vector3(0, 0, 0);
                    m_CurVertex.m_TexCoord = null;
                    m_CurVertex.m_Normal   = null;

                    if ((matgroup.m_PolyAttribs & 0x8000) != 0x8000)
                    {
                        byte alpha = (byte)((matgroup.m_PolyAttribs >> 16) & 0x1F);
                        alpha           |= (byte)(alpha >> 5);
                        matgroup.m_Alpha = alpha;
                    }

                    if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000)
                    {
                        m_CurVertex.m_Color = Color.FromArgb(matgroup.m_Alpha << 3, matgroup.m_DiffuseColor);
                    }
                    else
                    {
                        m_CurVertex.m_Color = Color.Black;
                    }

                    m_CurVertex.m_MatrixID = 0;

                    uint dlend = dloffset + dlsize;
                    for (uint pos = dloffset; pos < dlend;)
                    {
                        byte cmd1 = m_File.Read8(pos++);
                        byte cmd2 = m_File.Read8(pos++);
                        byte cmd3 = m_File.Read8(pos++);
                        byte cmd4 = m_File.Read8(pos++);

                        ProcessGXCommand(matgroup, cmd1, ref pos);
                        ProcessGXCommand(matgroup, cmd2, ref pos);
                        ProcessGXCommand(matgroup, cmd3, ref pos);
                        ProcessGXCommand(matgroup, cmd4, ref pos);
                    }
                }
            }

            foreach (ModelChunk mdchunk in m_ModelChunks)
            {
                foreach (MaterialGroup matgroup in mdchunk.m_MatGroups)
                {
                    matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length];
                    for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++)
                    {
                        matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform;
                    }
                }
            }

            int index = 0;

            foreach (KeyValuePair <string, uint> entry in m_TextureIDs)
            {
                if (!m_Textures.ContainsKey(entry.Key))
                {
                    Console.WriteLine("NOT IN TEXTURES: " + entry.Key);
                    uint palID = Math.Min(m_PaletteIDs.ElementAt(index).Value, (uint)m_PaletteIDs.Count - 1);
                    ReadTexture(entry.Value, palID);
                }
                index++;
            }
        }
예제 #18
0
                public SDATInfoBANK(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID = sdat.Read32(m_Offset + 0x00);
                    m_WaveArc = new ushort[4];
                    for (int i = 0; i < 4; i++)
                    {
                        m_WaveArc[i] = sdat.Read16(m_Offset + 0x04 + (uint)(i * 2));
                    }
                }
예제 #19
0
            char[] m_Type; // 'INFO'

            #endregion Fields

            #region Constructors

            public SDATInfo(NitroFile sdat, uint offset)
            {
                m_Offset = offset;
                m_Type = sdat.ReadString(m_Offset + 0x00, 4).ToCharArray();
                m_Size = sdat.Read32(m_Offset + 0x04);
                m_RecordOffset = new uint[8];
                for (int i = 0; i < 8; i++)
                    m_RecordOffset[i] = sdat.Read32(m_Offset + 0x08 + (uint)(i * 4));
                m_Reserved = sdat.ReadBlock(m_Offset + 0x28, 24);

                m_Records = new SDATInfoRecord[8];
                for (int i = 0; i < 8; i++)
                {
                    m_Records[i] = new SDATInfoRecord(sdat, m_Offset + m_RecordOffset[i]);
                }
                m_Records0SEQ = new SDATInfoSEQ[m_Records[0].m_Count];
                for (int i = 0; i < m_Records[0].m_Count; i++)
                {
                    m_Records0SEQ[i] = new SDATInfoSEQ(sdat, m_Offset + m_Records[0].m_EntryOffset[i]);
                }
                m_Records1SEQARC = new SDATInfoSEQARC[m_Records[1].m_Count];
                for (int i = 0; i < m_Records[1].m_Count; i++)
                {
                    m_Records1SEQARC[i] = new SDATInfoSEQARC(sdat, m_Offset + m_Records[1].m_EntryOffset[i]);
                }
                m_Records2BANK = new SDATInfoBANK[m_Records[2].m_Count];
                for (int i = 0; i < m_Records[2].m_Count; i++)
                {
                    m_Records2BANK[i] = new SDATInfoBANK(sdat, m_Offset + m_Records[2].m_EntryOffset[i]);
                }
                m_Records3WAVEARC = new SDATInfoWAVEARC[m_Records[3].m_Count];
                for (int i = 0; i < m_Records[3].m_Count; i++)
                {
                    m_Records3WAVEARC[i] = new SDATInfoWAVEARC(sdat, m_Offset + m_Records[3].m_EntryOffset[i]);
                }
                m_Records4PLAYER = new SDATInfoPLAYER[m_Records[4].m_Count];
                for (int i = 0; i < m_Records[4].m_Count; i++)
                {
                    m_Records4PLAYER[i] = new SDATInfoPLAYER(sdat, m_Offset + m_Records[4].m_EntryOffset[i]);
                }
                m_Records5GROUP = new SDATInfoGROUP[m_Records[5].m_Count];
                for (int i = 0; i < m_Records[5].m_Count; i++)
                {
                    m_Records5GROUP[i] = new SDATInfoGROUP(sdat, m_Offset + m_Records[5].m_EntryOffset[i]);
                }
                m_Records6PLAYER2 = new SDATInfoPLAYER2[m_Records[6].m_Count];
                for (int i = 0; i < m_Records[6].m_Count; i++)
                {
                    m_Records6PLAYER2[i] = new SDATInfoPLAYER2(sdat, m_Offset + m_Records[6].m_EntryOffset[i]);
                }
                m_Records7STREAM = new SDATInfoSTREAM[m_Records[7].m_Count];
                for (int i = 0; i < m_Records[7].m_Count; i++)
                {
                    m_Records7STREAM[i] = new SDATInfoSTREAM(sdat, m_Offset + m_Records[7].m_EntryOffset[i]);
                }
            }
예제 #20
0
                    /* Value	Type
                     * 0x0700	SEQ
                     * 0x0803	SEQARC
                     * 0x0601	BANK
                     * 0x0402	WAVEARC
                     *
                     * m_Index is the entry number in the relevant Record (SEQ/SEQARC/BANK/WAVEARC).
                     */
                    public GroupEntry(NitroFile sdat, uint offset)
                    {
                        m_Offset = offset;

                        m_Type = sdat.Read8(m_Offset + 0x00);
                        m_LoadFlag = sdat.Read8(m_Offset + 0x01);
                        m_Padding = sdat.Read16(m_Offset + 0x02);
                        m_Index = sdat.Read32(m_Offset + 0x04);
                    }
예제 #21
0
                public SDATInfoGROUP(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_Count = sdat.Read32(m_Offset + 0x00);
                    m_GroupEntries = new GroupEntry[m_Count];
                    for (int i = 0; i < m_Count; i++)
                    {
                        m_GroupEntries[i] = new GroupEntry(sdat, m_Offset + 0x04 + (uint)(i * 8));
                    }
                }
                public SDATInfoSEQARC(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID = sdat.Read32(m_Offset + 0x00);
                }
예제 #23
0
                public SDATInfoPLAYER(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_SequenceMax = sdat.Read8(m_Offset + 0x00);
                    m_Padding = sdat.Read8(m_Offset + 0x01);
                    m_AllocChannelBitFlag = sdat.Read16(m_Offset + 0x02);
                    m_HeapSize = sdat.Read32(m_Offset + 0x04);
                }
예제 #24
0
                public SDATInfoSEQ(NitroFile sdat, uint offset)
                {
                    m_File = sdat;
                    m_Offset = offset;

                    m_FileID = sdat.Read32(m_Offset + 0x00);
                    m_Bank = sdat.Read16(m_Offset + 0x04);
                    m_Volume = sdat.Read8(m_Offset + 0x06);
                    m_ChannelPriority = sdat.Read8(m_Offset + 0x07);
                    m_PlayerPriority = sdat.Read8(m_Offset + 0x08);
                    m_PlayerNumber = sdat.Read8(m_Offset + 0x09);
                    m_Unknown2 = sdat.ReadBlock(m_Offset + 0x0A, 2);
                }
예제 #25
0
 public SDATInfoRecord(NitroFile sdat, uint offset)
 {
     m_Offset = offset;
     m_Count = sdat.Read32(m_Offset);
     m_EntryOffset = new uint[m_Count];
     for (int i = 0; i < m_Count; i++)
         m_EntryOffset[i] = sdat.Read32(m_Offset + 0x04 + (uint)(i * 4));
 }
예제 #26
0
                public SDATInfoSEQARC(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID = sdat.Read32(m_Offset + 0x00);
                }
예제 #27
0
                public SDATInfoSTREAM(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    m_FileID = sdat.Read32(m_Offset + 0x00);
                    m_Volume = sdat.Read8(m_Offset + 0x04);
                    m_PlayerPriority = sdat.Read8(m_Offset + 0x05);
                    m_PlayerNumber = sdat.Read8(m_Offset + 0x06);
                    m_Reserved = new byte[5];
                    for (int i = 0; i < 5; i++)
                        m_Reserved[i] = sdat.Read8(m_Offset + 0x07 + (uint)(i));
                }
예제 #28
0
파일: KCL.cs 프로젝트: RicoPlays/sm64dse
            public OctreeNode(NitroFile file, uint baseoffset, uint offset, Vector3 pos, Vector3 size)
            {
                m_Pos = pos;
                m_Size = size;
                m_LOL = false;
                m_PlaneList = new List<int>();

                uint node = file.Read32(offset);
                if ((node & 0x80000000) != 0)
                {
                    uint lolz = baseoffset + (node & 0x7FFFFFFF) + 2;
                    int n = 0;
                    string lmao = "";
                    for (; ; )
                    {
                        ushort p = file.Read16(lolz);
                        if (p == 0)
                            break;
                        else if (p == 37)
                            m_LOL = true;

                        m_PlaneList.Add(p - 1);
                        lmao += (p - 1).ToString() + " ";
                        lolz += 2;
                        n++;
                    }

                    if (n > maxkids)
                        maxkids = n;

                    //if (m_LOL)
                     //   MessageBox.Show(lmao);

                    m_NumPlanes = n;
                    OctreeNode.m_List.Add(this);
                }
                else
                {
                    uint parentoffset = baseoffset + node;
                    uint child0offset = parentoffset;
                    size /= 2f;
                    for (int z = 0; z < 2; z++)
                        for (int y = 0; y < 2; y++)
                            for (int x = 0; x < 2; x++)
                            { new OctreeNode(file, child0offset, parentoffset, pos + new Vector3(size.X * x, size.Y * y, size.Z * z), size); parentoffset += 4; }
                }
            }
예제 #29
0
        public void ReadStrings(String fileName)
        {
            file = Program.m_ROM.GetFileFromName(fileName);

            inf1size = file.Read32(0x24);
            ushort numentries = file.Read16(0x28);

            m_MsgData = new string[numentries];
            m_StringLengths = new int[numentries];
            m_ShortVersions = new string[numentries];
            m_FileSize = file.Read32(0x08);
            m_StringHeaderAddr = new uint[numentries];
            m_StringHeaderData = new uint[numentries];
            m_DAT1Start = 0x20 + inf1size + 0x08;

            for (int i = 0; i < numentries; i++)
            {
                m_StringHeaderAddr[i] = (uint)(0x20 + 0x10 + (i * 8));
                m_StringHeaderData[i] = file.Read32(m_StringHeaderAddr[i]);
            }

            lbxMsgList.Items.Clear();//Reset list of messages
            lbxMsgList.BeginUpdate();// Only draw when EndUpdate is called, much faster, expecially for Mono

            for (int i = 0; i < m_MsgData.Length; i++)
            {
                uint straddr = file.Read32((uint)(0x30 + i * 8));
                straddr += 0x20 + inf1size + 0x8;

                int length = 0;

                string thetext = "";
                for (; ; )
                {
                    byte cur;
                    try
                    {
                        cur = file.Read8(straddr);
                    }
                    catch
                    {
                        break;
                    }
                    straddr++;
                    length++;
                    char thechar = '\0';

                    /*if ((cur >= 0x00) && (cur <= 0x09))
                        thechar = (char)('0' + cur);
                    else if ((cur >= 0x0A) && (cur <= 0x23))
                        thechar = (char)('A' + cur - 0x0A);
                    else if ((cur >= 0x2D) && (cur <= 0x46))
                        thechar = (char)('a' + cur - 0x2D);
                    else if ((cur >= 0x50) && (cur <= 0xCF))//Extended ASCII Characters
                        thechar = (char)(0x30 + cur);*/
                    // Some characters are two bytes long, can skip the second

                    if (langNames[langIndex] == "jpn")
                    {
                        if (JAP_CHARS.GetFirstToSecond().ContainsKey(cur))
                        {
                            thetext += JAP_CHARS.GetByFirst(cur);
                            straddr += (JAP_SIZES[JAP_CHARS.GetByFirst(cur)] - 1);
                            length += (int)(JAP_SIZES[JAP_CHARS.GetByFirst(cur)] - 1);
                        }
                    }
                    else
                    {
                        if ((cur >= 0x00 && cur <= 0x4F) || (cur >= 0xEE && cur <= 0xFB))
                        {
                            thetext += BASIC_EUR_US_CHARS.GetByFirst(cur);
                            straddr += (BASIC_EUR_US_SIZES[BASIC_EUR_US_CHARS.GetByFirst(cur)] - 1);
                            length += (int)(BASIC_EUR_US_SIZES[BASIC_EUR_US_CHARS.GetByFirst(cur)] - 1);
                        }
                        else if (cur >= 0x50 && cur <= 0xCF)
                        {
                            thetext += EXTENDED_ASCII_CHARS.GetByFirst(cur);
                            straddr += (EXTENDED_ASCII_SIZES[EXTENDED_ASCII_CHARS.GetByFirst(cur)] - 1);
                            length += (int)(EXTENDED_ASCII_SIZES[EXTENDED_ASCII_CHARS.GetByFirst(cur)] - 1);
                        }
                    }

                    if (thechar != '\0')
                        thetext += thechar;
                    else if (cur == 0xFD)
                        thetext += "\r\n";
                    else if (cur == 0xFF)
                        break;
                    else if (cur == 0xFE)// Special Character
                    {
                        int len = file.Read8(straddr);
                        thetext += "[\\r]";
                        thetext += String.Format("{0:X2}", cur);
                        for (int spec = 0; spec < len - 1; spec++)
                        {
                            thetext += String.Format("{0:X2}", file.Read8((uint)(straddr + spec)));
                        }
                        length += (len - 1);// Already increased by 1 at start
                        straddr += (uint)(len - 1);
                    }
                }

                m_MsgData[i] = thetext;
                m_StringLengths[i] = length;
                m_ShortVersions[i] = ShortVersion(m_MsgData[i], i);

                lbxMsgList.Items.Add(m_ShortVersions[i]);

                btnImport.Enabled = true; btnExport.Enabled = true;
            }
            lbxMsgList.EndUpdate();
        }
예제 #30
0
                public SDATInfoWAVEARC(NitroFile sdat, uint offset)
                {
                    m_Offset = offset;

                    uint num = sdat.Read32(m_Offset + 0x00);
                    m_FileID = (num & 16777215u);
                    m_Flag = (byte)(num >> 24);

                    //er.Write((uint)((long)((long)this.flags << 24) | (long)((ulong)(this.fileID & 16777215u))));
                }
예제 #31
0
파일: KCL.cs 프로젝트: RicoPlays/sm64dse
        public KCL(NitroFile file)
        {
            m_File = file;

            m_Planes = new List <ColFace>();

            m_PointsSectionOffset  = m_File.Read32(0x00);
            m_NormalsSectionOffset = m_File.Read32(0x04);
            m_PlanesSectionOffset  = m_File.Read32(0x08);
            m_OctreeSectionOffset  = m_File.Read32(0x0C);

            int planeid = 0;

            for (uint offset = m_PlanesSectionOffset + 0x10; offset < m_OctreeSectionOffset; offset += 0x10)
            {
                uint length = m_File.Read32(offset);

                ushort pt_id = m_File.Read16(offset + 0x04);
                int    pt_x  = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id * 12)));
                int    pt_y  = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id * 12) + 4));
                int    pt_z  = (int)m_File.Read32((uint)(m_PointsSectionOffset + (pt_id * 12) + 8));

                ushort nr_id = m_File.Read16(offset + 0x06);
                short  nr_x  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id * 6)));
                short  nr_y  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id * 6) + 2));
                short  nr_z  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (nr_id * 6) + 4));

                ushort d1_id = m_File.Read16(offset + 0x08);
                short  d1_x  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id * 6)));
                short  d1_y  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id * 6) + 2));
                short  d1_z  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d1_id * 6) + 4));

                ushort d2_id = m_File.Read16(offset + 0x0A);
                short  d2_x  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id * 6)));
                short  d2_y  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id * 6) + 2));
                short  d2_z  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d2_id * 6) + 4));

                ushort d3_id = m_File.Read16(offset + 0x0C);
                short  d3_x  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id * 6)));
                short  d3_y  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id * 6) + 2));
                short  d3_z  = (short)m_File.Read16((uint)(m_NormalsSectionOffset + (d3_id * 6) + 4));

                ColFace plane = new ColFace((float)(length / 65536000f),
                                            new Vector3((float)pt_x / 64000f, (float)pt_y / 64000f, (float)pt_z / 64000f),
                                            new Vector3((float)nr_x / 1024f, (float)nr_y / 1024f, (float)nr_z / 1024f),
                                            new Vector3((float)d1_x / 1024f, (float)d1_y / 1024f, (float)d1_z / 1024f),
                                            new Vector3((float)d2_x / 1024f, (float)d2_y / 1024f, (float)d2_z / 1024f),
                                            new Vector3((float)d3_x / 1024f, (float)d3_y / 1024f, (float)d3_z / 1024f),
                                            m_File.Read16(offset + 0x0E));

                /* if (planeid == 31)
                 *   MessageBox.Show(string.Format("PLANE 32:\n{0}\n{1}\n{2}\n\n{3}\n{4}\n{5}\n\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}",
                 *       d1_x, d1_y, d1_z,
                 *       d2_x, d2_y, d2_z,
                 *       plane.m_Position, plane.m_Normal, plane.m_Dir1, plane.m_Dir2, plane.m_Dir3, plane.m_Length));*/

                planeid++;

                /* if (Math.Abs(plane.m_Dir1.Length - 1f) > 0.0001f || Math.Abs(plane.m_Dir2.Length - 1f) > 0.0001f ||
                 *   Math.Abs(plane.m_Dir3.Length - 1f) > 0.0001f || Math.Abs(plane.m_Normal.Length - 1f) > 0.0001f ||
                 *   plane.m_Length < 0f)
                 *   MessageBox.Show(string.Format("WRONG PLANE | {0} | {1} | {2} | {3} | {4}",
                 *       plane.m_Dir1.Length, plane.m_Dir2.Length, plane.m_Dir3.Length, plane.m_Normal.Length, plane.m_Length));
                 *
                 * if (plane.m_Dir1.Length < 0.001f || plane.m_Dir2.Length < 0.001f ||
                 *   plane.m_Dir3.Length < 0.001f || plane.m_Normal.Length < 0.001f ||
                 *   Math.Abs(plane.m_Length) < 0.001f)
                 *   MessageBox.Show(string.Format("ZERO PLANE | {0} | {1} | {2} | {3} | {4}",
                 *       plane.m_Dir1.Length, plane.m_Dir2.Length, plane.m_Dir3.Length, plane.m_Normal.Length, plane.m_Length));
                 *
                 * Vector3 lol1 = Vector3.Cross(plane.m_Dir1, plane.m_Normal);
                 * float lol1len = plane.m_Length / (float)Math.Cos(Math.Acos(Math.Min(1f,Vector3.Dot(lol1, plane.m_Dir3))));
                 * Vector3 lol2 = Vector3.Cross(plane.m_Normal, plane.m_Dir2);
                 * float lol2len = plane.m_Length / (float)Math.Cos(Math.Acos(Math.Min(1f,Vector3.Dot(lol2, plane.m_Dir3))));
                 * if (Helper.VectorsEqual(plane.m_Position, Vector3.Multiply(lol1, lol1len)) ||
                 *   Helper.VectorsEqual(plane.m_Position, Vector3.Multiply(lol2, lol2len)))
                 *   MessageBox.Show(string.Format("WEIRD PLANE {5:X8} | {0} | {1} | {2} | {3} | {4}\n{6} | {7} / cos(acos({8})) = cos({9}) = {10}",
                 *       plane.m_Dir1, plane.m_Dir2, plane.m_Dir3, plane.m_Normal, plane.m_Length,
                 *       offset, lol2, plane.m_Length, Vector3.Dot(lol2, plane.m_Dir3), Math.Acos(Vector3.Dot(lol2, plane.m_Dir3)), Math.Cos(Math.Acos(Vector3.Dot(lol2, plane.m_Dir3)))));
                 */
                m_Planes.Add(plane);
            }

            OctreeNode.maxkids = 0;
            int     shift       = (int)m_File.Read32(0x2C);
            Vector3 octreestart = new Vector3((float)(int)m_File.Read32(0x14) / 64000f, (float)(int)m_File.Read32(0x18) / 64000f, (float)(int)m_File.Read32(0x1C) / 64000f);
            float   _cubesize   = (float)(1 << shift) / 1024f;
            Vector3 cubesize    = new Vector3(_cubesize, _cubesize, _cubesize);
            Vector3 octreesize  = new Vector3((~m_File.Read32(0x20) >> shift) + 1, (~m_File.Read32(0x24) >> shift) + 1, (~m_File.Read32(0x28) >> shift) + 1);

            OctreeNode.m_List = new List <OctreeNode>();
            uint loloffset = m_OctreeSectionOffset;

            for (int z = 0; z < octreesize.Z; z++)
            {
                for (int y = 0; y < octreesize.Y; y++)
                {
                    for (int x = 0; x < octreesize.X; x++)
                    {
                        new OctreeNode(m_File, m_OctreeSectionOffset, loloffset, octreestart + new Vector3(cubesize.X * x, cubesize.Y * y, cubesize.Z * z), cubesize); loloffset += 4;
                    }
                }
            }

            //MessageBox.Show(OctreeNode.m_List.Count.ToString());
        }
예제 #32
0
파일: BMD.cs 프로젝트: RicoPlays/sm64dse
        public BMD(NitroFile file)
        {
            m_File = file;
            m_FileName = file.m_Name;

            /* if (m_File.m_ID == 741)
                 lolol = true;
             else*/
            lolol = false;

            // Keep a list of pointers so it's easier to add/remove entries, space etc.
            m_PointerList = new List<PointerReference>();

            m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0));

            // ModelChunk refers to Bone
            m_NumModelChunks = m_File.Read32(0x04);
            m_ModelChunksOffset = m_File.Read32(0x08);
            AddPointer(0x08);
            for (int i = 0; i < m_NumModelChunks; i++)
            {
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38));
            }

            // PolyChunk refers to Display List
            m_NumPolyChunks = m_File.Read32(0x0C);
            m_PolyChunksOffset = m_File.Read32(0x10);
            AddPointer(0x10);
            for (int i = 0; i < m_NumPolyChunks; i++)
            {
                // Offset to Display List within Display List entries
                AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4));
                // Offsets within the Display List 16 byte headers
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04);
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C);
            }
            m_NumTexChunks = m_File.Read32(0x14);
            m_TexChunksOffset = m_File.Read32(0x18);
            m_TextureIDs = new Dictionary<string, uint>();
            AddPointer(0x18);
            for (int i = 0; i < m_NumTexChunks; i++)
            {
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0));
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4));
                m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i);
            }
            m_NumPalChunks = m_File.Read32(0x1C);
            m_PalChunksOffset = m_File.Read32(0x20);
            m_PaletteIDs = new Dictionary<string, uint>();
            AddPointer(0x20);
            for (int i = 0; i < m_NumPalChunks; i++)
            {
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0));
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4));
                m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i);
            }
            m_NumMatChunks = m_File.Read32(0x24);
            m_MatChunksOffset = m_File.Read32(0x28);
            AddPointer(0x28);
            for (int i = 0; i < m_NumMatChunks; i++)
            {
                AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0));
            }
            m_BoneMapOffset = m_File.Read32(0x2C);
            AddPointer(0x2C);

            m_Textures = new Dictionary<string, Texture>();
            m_ModelChunks = new ModelChunk[m_NumModelChunks];

            for (uint c = 0; c < m_NumModelChunks; c++)
            {
                ModelChunk mdchunk = new ModelChunk(this);
                m_ModelChunks[c] = mdchunk;

                uint mdchunkoffset = m_ModelChunksOffset + (c * 64);

                mdchunk.m_ID = m_File.Read32(mdchunkoffset);
                mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0);

                // transforms part
                {
                    int xscale = (int)m_File.Read32(mdchunkoffset + 0x10);
                    int yscale = (int)m_File.Read32(mdchunkoffset + 0x14);
                    int zscale = (int)m_File.Read32(mdchunkoffset + 0x18);
                    short xrot = (short)m_File.Read16(mdchunkoffset + 0x1C);
                    short yrot = (short)m_File.Read16(mdchunkoffset + 0x1E);
                    short zrot = (short)m_File.Read16(mdchunkoffset + 0x20);
                    int xtrans = (int)m_File.Read32(mdchunkoffset + 0x24);
                    int ytrans = (int)m_File.Read32(mdchunkoffset + 0x28);
                    int ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C);

                    mdchunk.m_Scale = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f);
                    mdchunk.m_Rotation = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f);
                    mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f);
                    mdchunk.m_Transform = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation);

                    // Used when exporting bones
                    mdchunk.m_20_12Scale = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale };
                    mdchunk.m_4_12Rotation = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot };
                    mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans };

                    // if the chunk has a parent, apply the parent's transform to the chunk's transform.
                    // we don't need to go further than one level because the paren't transform already
                    // went through its parents' transforms.
                    short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8);
                    if (parent_offset < 0)
                    {
                        int parentchunkid = (int)(c + parent_offset);
                        Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform);
                    }
                    mdchunk.m_ParentOffset = parent_offset;
                }
                // If 0x0A is set to 1 the bone has children, if 0 it doesn't
                mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1);

                mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C));

                uint flags = m_File.Read32(mdchunkoffset + 0x3C);
                mdchunk.m_Billboard = ((flags & 0x1) == 0x1);

                uint numpairs = m_File.Read32(mdchunkoffset + 0x30);
                uint matlist = m_File.Read32(mdchunkoffset + 0x34);
                uint polylist = m_File.Read32(mdchunkoffset + 0x38);

                mdchunk.m_MatGroups = new MaterialGroup[numpairs];

                for (uint i = 0; i < numpairs; i++)
                {
                    MaterialGroup matgroup = new MaterialGroup();
                    mdchunk.m_MatGroups[i] = matgroup;

                    byte matID = m_File.Read8(matlist + i);
                    byte polyID = m_File.Read8(polylist + i);

                    uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48));

                    matgroup.m_ID = matID;
                    matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0);
                    uint texid = m_File.Read32(mchunkoffset + 0x04);
                    uint palid = m_File.Read32(mchunkoffset + 0x08);
                    matgroup.m_TexParams = m_File.Read32(mchunkoffset + 0x20);
                    matgroup.m_PolyAttribs = m_File.Read32(mchunkoffset + 0x24);
                    matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28);
                    matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C);

                    if ((matgroup.m_PolyAttribs & 0x30) == 0x10)
                        matgroup.m_TexEnvMode = TextureEnvMode.Decal;
                    else
                        matgroup.m_TexEnvMode = TextureEnvMode.Modulate;

                    switch (matgroup.m_PolyAttribs & 0xC0)
                    {
                        case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break;
                        case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break;
                        case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break;
                    }

                    matgroup.m_DiffuseColor = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors);
                    matgroup.m_AmbientColor = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16));
                    matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors);
                    matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16));

                    switch (matgroup.m_TexParams >> 30)
                    {
                        case 0:
                            matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f);
                            matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f);
                            break;

                        case 1:
                            {
                                int sscale = (int)m_File.Read32(mchunkoffset + 0x0C);
                                int tscale = (int)m_File.Read32(mchunkoffset + 0x10);
                                int strans = (int)m_File.Read32(mchunkoffset + 0x18);
                                int ttrans = (int)m_File.Read32(mchunkoffset + 0x1C);

                                matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f);
                                matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f);
                                //matgroup.m_TexCoordTrans = new Vector2(0.0f, 16.0f);
                                /*System.Windows.Forms.MessageBox.Show(String.Format("textransform: scale:{0} trans:{1} rot:{2:X8}",
                                    matgroup.m_TexCoordScale, matgroup.m_TexCoordTrans,
                                    m_File.Read32(mchunkoffset + 0x1C)));*/
                            }
                            break;

                        case 2:
                            goto case 1;

                        case 3:
                            goto case 1;

                        default:
                            break;
                        // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30));
                    }

                    if (texid != 0xFFFFFFFF)
                    {
                        matgroup.m_Texture = ReadTexture(texid, palid);
                        matgroup.m_TexParams |= matgroup.m_Texture.m_Params;
                    }
                    else
                        matgroup.m_Texture = null;

                    uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4));
                    uint dloffset = m_File.Read32(pchunkoffset + 0x0C);
                    uint dlsize = m_File.Read32(pchunkoffset + 0x08);
                    uint numbones = m_File.Read32(pchunkoffset);
                    uint bonesoffset = m_File.Read32(pchunkoffset + 0x04);

                    matgroup.m_BoneIDs = new ushort[numbones];
                    for (uint b = 0; b < numbones; b++)
                    {
                        byte idx1 = m_File.Read8(bonesoffset + b);
                        matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1)));
                    }

                    matgroup.m_Geometry = new List<VertexList>();

                    m_CurVertex.m_Position = new Vector3(0, 0, 0);
                    m_CurVertex.m_TexCoord = new Vector2(0, 0);
                    if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000)
                    {
                        byte alpha = (byte)((matgroup.m_PolyAttribs >> 13) & 0xF8);
                        alpha |= (byte)(alpha >> 5);
                        matgroup.m_Alpha = alpha;

                        m_CurVertex.m_Color = Color.FromArgb(alpha, matgroup.m_DiffuseColor);
                    }
                    else
                        m_CurVertex.m_Color = Color.Black;

                    m_CurVertex.m_MatrixID = 0;

                    uint dlend = dloffset + dlsize;
                    for (uint pos = dloffset; pos < dlend; )
                    {
                        byte cmd1 = m_File.Read8(pos++);
                        byte cmd2 = m_File.Read8(pos++);
                        byte cmd3 = m_File.Read8(pos++);
                        byte cmd4 = m_File.Read8(pos++);

                        ProcessGXCommand(matgroup, cmd1, ref pos);
                        ProcessGXCommand(matgroup, cmd2, ref pos);
                        ProcessGXCommand(matgroup, cmd3, ref pos);
                        ProcessGXCommand(matgroup, cmd4, ref pos);
                    }
                }
            }

            foreach (ModelChunk mdchunk in m_ModelChunks)
            {
                foreach (MaterialGroup matgroup in mdchunk.m_MatGroups)
                {
                    matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length];
                    for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++)
                        matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform;
                }
            }
        }
예제 #33
0
        public void ReadStrings(String fileName)
        {
            file = Program.m_ROM.GetFileFromName(fileName);

            inf1size = file.Read32(0x24);
            ushort numentries = file.Read16(0x28);

            m_MsgData          = new string[numentries];
            m_StringLengths    = new int[numentries];
            m_ShortVersions    = new string[numentries];
            m_FileSize         = file.Read32(0x08);
            m_StringHeaderAddr = new uint[numentries];
            m_StringHeaderData = new uint[numentries];
            m_DAT1Start        = 0x20 + inf1size + 0x08;

            for (int i = 0; i < numentries; i++)
            {
                m_StringHeaderAddr[i] = (uint)(0x20 + 0x10 + (i * 8));
                m_StringHeaderData[i] = file.Read32(m_StringHeaderAddr[i]);
            }

            lbxMsgList.Items.Clear(); //Reset list of messages
            lbxMsgList.BeginUpdate(); // Only draw when EndUpdate is called, much faster, expecially for Mono

            for (int i = 0; i < m_MsgData.Length; i++)
            {
                uint straddr = file.Read32((uint)(0x30 + i * 8));
                straddr += 0x20 + inf1size + 0x8;

                int length = 0;

                string thetext = "";
                for (; ;)
                {
                    byte cur;
                    try
                    {
                        cur = file.Read8(straddr);
                    }
                    catch
                    {
                        break;
                    }
                    straddr++;
                    length++;
                    char thechar = '\0';

                    /*if ((cur >= 0x00) && (cur <= 0x09))
                     *  thechar = (char)('0' + cur);
                     * else if ((cur >= 0x0A) && (cur <= 0x23))
                     *  thechar = (char)('A' + cur - 0x0A);
                     * else if ((cur >= 0x2D) && (cur <= 0x46))
                     *  thechar = (char)('a' + cur - 0x2D);
                     * else if ((cur >= 0x50) && (cur <= 0xCF))//Extended ASCII Characters
                     *  thechar = (char)(0x30 + cur);*/
                    // Some characters are two bytes long, can skip the second

                    if (langNames[langIndex] == "jpn")
                    {
                        if (JAP_CHARS.GetFirstToSecond().ContainsKey(cur))
                        {
                            thetext += JAP_CHARS.GetByFirst(cur);
                            straddr += (JAP_SIZES[JAP_CHARS.GetByFirst(cur)] - 1);
                            length  += (int)(JAP_SIZES[JAP_CHARS.GetByFirst(cur)] - 1);
                        }
                    }
                    else
                    {
                        if ((cur >= 0x00 && cur <= 0x4F) || (cur >= 0xEE && cur <= 0xFB))
                        {
                            thetext += BASIC_EUR_US_CHARS.GetByFirst(cur);
                            straddr += (BASIC_EUR_US_SIZES[BASIC_EUR_US_CHARS.GetByFirst(cur)] - 1);
                            length  += (int)(BASIC_EUR_US_SIZES[BASIC_EUR_US_CHARS.GetByFirst(cur)] - 1);
                        }
                        else if (cur >= 0x50 && cur <= 0xCF)
                        {
                            thetext += EXTENDED_ASCII_CHARS.GetByFirst(cur);
                            straddr += (EXTENDED_ASCII_SIZES[EXTENDED_ASCII_CHARS.GetByFirst(cur)] - 1);
                            length  += (int)(EXTENDED_ASCII_SIZES[EXTENDED_ASCII_CHARS.GetByFirst(cur)] - 1);
                        }
                    }

                    if (thechar != '\0')
                    {
                        thetext += thechar;
                    }
                    else if (cur == 0xFD)
                    {
                        thetext += "\r\n";
                    }
                    else if (cur == 0xFF)
                    {
                        break;
                    }
                    else if (cur == 0xFE)// Special Character
                    {
                        int len = file.Read8(straddr);
                        thetext += "[\\r]";
                        thetext += String.Format("{0:X2}", cur);
                        for (int spec = 0; spec < len - 1; spec++)
                        {
                            thetext += String.Format("{0:X2}", file.Read8((uint)(straddr + spec)));
                        }
                        length  += (len - 1);// Already increased by 1 at start
                        straddr += (uint)(len - 1);
                    }
                }

                m_MsgData[i]       = thetext;
                m_StringLengths[i] = length;
                m_ShortVersions[i] = ShortVersion(m_MsgData[i], i);

                lbxMsgList.Items.Add(m_ShortVersions[i]);

                btnImport.Enabled = true; btnExport.Enabled = true;
            }
            lbxMsgList.EndUpdate();
        }
예제 #34
0
        private void loadExternalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int texDefID = lbxTexDef.SelectedIndex;

            // this shouldn't happen but you never know
            if (texDefID == -1)
            {
                return;
            }

            m_ROMFileSelect.ReInitialize("Select a SPT file to load", new String[] { ".spt" });
            DialogResult result = m_ROMFileSelect.ShowDialog();

            if (result != DialogResult.OK)
            {
                return;
            }
            else
            {
                try
                {
                    NitroFile SPT = Program.m_ROM.GetFileFromName(m_ROMFileSelect.m_SelectedFile);

                    if (SPT.Read32(0x0) != 0x53505420)
                    {
                        throw new Exception("Invalid SPT header.");
                    }

                    uint flags        = SPT.Read32(0x04);
                    uint texelArrSize = SPT.Read32(0x08);
                    uint palOffset    = SPT.Read32(0x0c);
                    uint palSize      = SPT.Read32(0x10);
                    uint totalSize    = SPT.Read32(0x1c);

                    byte[] texels  = SPT.ReadBlock(0x20, texelArrSize);
                    byte[] palette = SPT.ReadBlock(palOffset, palSize);

                    int  width        = 1 << (((int)flags >> 4 & 0xf) + 3);
                    int  height       = 1 << (((int)flags >> 8 & 0xf) + 3);
                    bool color0Transp = ((flags & 0x8) | (flags & 0x10000)) != 0;
                    int  type         = (int)flags & 0x7;
                    Particle.Texture.RepeatMode repeatX = (flags & 0x4000) != 0 ?
                                                          Particle.Texture.RepeatMode.FLIP : (flags & 0x1000) != 0 ?
                                                          Particle.Texture.RepeatMode.REPEAT :
                                                          Particle.Texture.RepeatMode.CLAMP;
                    Particle.Texture.RepeatMode repeatY = (flags & 0x8000) != 0 ?
                                                          Particle.Texture.RepeatMode.FLIP : (flags & 0x2000) != 0 ?
                                                          Particle.Texture.RepeatMode.REPEAT :
                                                          Particle.Texture.RepeatMode.CLAMP;

                    m_TexDefs[texDefID].Unload();

                    m_TexDefs[texDefID] = new Particle.Texture(texels, palette, width, height,
                                                               (byte)(color0Transp ? 1 : 0), type, repeatX, repeatY, texDefID);

                    m_TexDefs[texDefID].Load();

                    UpdateParticleTextures(texDefID);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Failed to load external SPT. Details:\n" + ex.Message, "Failed to load SPT");
                }

                RefreshImage();
                PopulatePaletteSettings();
            }
        }