コード例 #1
0
ファイル: MOPP.cs プロジェクト: num0005/MOPP
        public MOPP(MOPPCode.CodeType type, MOPP old_codes)
        {
            Type = type;

            foreach (var code in old_codes.source_codes)
            {
                var new_code = code.Transform(Type);
                source_codes.Add(new_code);
            }
        }
コード例 #2
0
ファイル: MOPP.cs プロジェクト: num0005/MOPP
        public MOPP(MOPPCode.CodeType type, string file)
        {
            Type = type;
            if (mopp_codes == null)
            {
                mopp_codes = new List <MOPPCode> [(int)MOPPCode.CodeType.NumTypes];
                for (var i = 0; i < (int)MOPPCode.CodeType.NumTypes; i++)
                {
                    mopp_codes[i] = new List <MOPPCode>();
                }
            }
            {
                const int UNKNOWN = 0;
                for (var i = 0; i < 256; i++)
                {
                    mopp_codes[(int)Type].Add(null);                           // Empty array of 256 nulls
                }
                SetMOPPCode(0x00, 0x00);

                /*
                 * Advance pointer by 4 from start
                 */
                //SetMOPPCode(0x01, 0x01, 0x00, 0x00, 0x00);              // unknown test
                {
                    UInt32[] args = { 0x00, 0x00, 0x00 };
                    mopp_codes[(int)Type][(int)0x1] = new MOPPCode_0x01(MOPPCode.CodeType.Halo3, 0x1, -1, args);
                }
                SetMOPPCode(0x02, 0x02, 0x00, 0x00, 0x00);              // unknown test
                SetMOPPCode(0x03, 0x03, 0x00, 0x00, 0x00);              // unknown test
                SetMOPPCode(0x04, 0x04, 0x00, 0x00, 0x00);              // unknown test

                SetMOPPCode(0x05, 0x05, 0x00);                          // jump 8bit  a
                SetMOPPCode(0x06, 0x06, 0x00, 0x00);                    // jump 16bit (a<<8) + b
                SetMOPPCode(0x07, 0x07, 0x00, 0x00, 0x00);              // Jump 24bit (a<<16) + (b<<8) + c

                UnkMOPPCode(0x08, 0x08);

                SetMOPPCode(0x09, 0x07, 0x00);                          // 64bytes to ptr. 8bit a
                SetMOPPCode(0x0A, 0x07, 0x00, 0x00);                    // 64bytes to ptr. 16bit a + b<<8
                SetMOPPCode(0x0B, 0x07, 0x00, 0x00, 0x00, 0x00);        // 64bytes to ptr. 24bit a + b<<8 + c<<16

                SetMOPPCode(0x0C, UNKNOWN, 0x00, 0x00);                 // 64bytes to ptr. 16bit a + b<<8

                SetMOPPCode(0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00);  // 64bytes to ptr. 24bit a + b<<8 + c<<16

                UnkMOPPCode(0x0E, 0x0E);
                UnkMOPPCode(0x0F, 0x0F);

                //if x>a then execute block c bytes further; if x<=a and x>=b then execute next block and block c bytes further; if x<b then only execute next block
                SetMOPPCode(0x10, 0x10, 0x00, 0x00, 0x00);
                SetMOPPCode(0x11, 0x11, 0x00, 0x00, 0x00); //like 0x10 but for y
                SetMOPPCode(0x12, 0x12, 0x00, 0x00, 0x00); //like 0x10 but for z
                SetMOPPCode(0x13, 0x13, 0x00, 0x00, 0x00); //like 0x10 but for y + z
                SetMOPPCode(0x14, 0x14, 0x00, 0x00, 0x00); //like 0x10 but for y - z
                SetMOPPCode(0x15, 0x15, 0x00, 0x00, 0x00); //like 0x10 but for x + z
                SetMOPPCode(0x16, 0x16, 0x00, 0x00, 0x00); //like 0x10 but for x - z
                SetMOPPCode(0x17, 0x17, 0x00, 0x00, 0x00); //like 0x10 but for x + y
                SetMOPPCode(0x18, 0x18, 0x00, 0x00, 0x00); //like 0x10 but for x - y
                SetMOPPCode(0x19, 0x19, 0x00, 0x00, 0x00); //like 0x10 but for x + y + z
                SetMOPPCode(0x1A, 0x1A, 0x00, 0x00, 0x00); //like 0x10 but for x + y - z
                SetMOPPCode(0x1B, 0x1B, 0x00, 0x00, 0x00); //like 0x10 but for x - y + z
                SetMOPPCode(0x1C, 0x1C, 0x00, 0x00, 0x00); //like 0x10 but for x - y - z

                // Something happens here. Offsets become important. Why? Well. I don't f*****g know.

                //execute next block and/or block at b bytes further depending on result of an unknown test involving a
                SetMOPPCode(0x20, UNKNOWN, UNKNOWN, UNKNOWN);
                SetMOPPCode(0x21, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x20
                SetMOPPCode(0x22, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x20

                SetMOPPCode(0x23, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
                SetMOPPCode(0x24, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x20
                SetMOPPCode(0x25, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x20

                // Normally used for AABB collision
                SetMOPPCode(0x26, 0x26, 0x00, 0x00);                // exit if x<a or x>b
                SetMOPPCode(0x27, 0x27, 0x00, 0x00);                // exit if y<a or y>b
                SetMOPPCode(0x28, 0x28, 0x00, 0x00);                // exit if z<a or z>b

                /*
                 * According to http://niftools.sourceforge.net/wiki/Nif_Format/Mopp
                 * These used to be 0x23-25
                 *
                 * */


                //execute block c*256 + d bytes further and/or block e*256 + f bytes further depending on result of an unknown test involving a and b
                SetMOPPCode(0x29, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
                SetMOPPCode(0x2A, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x23
                SetMOPPCode(0x2B, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); //like 0x23

                //Select triangle. offset + i<0x00 - 0x1F>
                for (var i = 0; i <= 0x1F; i++)
                {
                    SetMOPPCode(0x30 + i, UNKNOWN + i);
                }

                SetMOPPCode(0x50, UNKNOWN, 0x00);                   // select triangle a+offset 8bit
                SetMOPPCode(0x51, UNKNOWN, 0x00, 0x00);             // select triangle a+offset 16bit
                SetMOPPCode(0x52, UNKNOWN, 0x00, 0x00, 0x00);       // select triangle a+offset 24bit
                                                                    //SetMOPPCode(0x53, UNKNOWN, 0x00, 0x00, 0x00, 0x00); // select triangle a+offset 32bit

                {
                    UInt32[] args = { 0x00, 0x00, 0x00, 0x00 };
                    mopp_codes[(int)Type][(int)0x53] = new MOPPCode_0x53(MOPPCode.CodeType.Halo3, 0x53, -1, args);
                }



                SetMOPPCode(0x60, UNKNOWN, 0x00);                   // Something 8bit
                SetMOPPCode(0x61, UNKNOWN, 0x00);                   // Something 8bit
                SetMOPPCode(0x62, UNKNOWN, 0x00);                   // Something 8bit
                SetMOPPCode(0x63, UNKNOWN, 0x00);                   // Something 8bit
                SetMOPPCode(0x64, UNKNOWN, 0x00, 0x00);             // Something 16bit
                SetMOPPCode(0x65, UNKNOWN, 0x00, 0x00);             // Something 16bit
                SetMOPPCode(0x66, UNKNOWN, 0x00, 0x00);             // Something 16bit
                SetMOPPCode(0x67, UNKNOWN, 0x00, 0x00);             // Something 16bit
                SetMOPPCode(0x68, UNKNOWN, 0x00, 0x00, 0x00, 0x00); // Something 32bit
                SetMOPPCode(0x69, UNKNOWN, 0x00, 0x00, 0x00, 0x00); // Something 32bit
                SetMOPPCode(0x6A, UNKNOWN, 0x00, 0x00, 0x00, 0x00); // Something 32bit
                SetMOPPCode(0x6B, UNKNOWN, 0x00, 0x00, 0x00, 0x00); // Something 32bit
            }

            Console.Title = $"Converting {file}";

            // Open the text file using a stream reader.
            MemoryStream stream = new MemoryStream();

            using (FileStream fs = File.OpenRead(file))
            {
                fs.CopyTo(stream);
                stream.Position = 0;
                while (stream.Position < stream.Length)
                {
                    var code = GetMOPPCode(stream);
                    if (code == null)
                    {
                        stream.Position--;
                        var pos = stream.Position.ToString("X");
                        var val = stream.ReadByte().ToString("X");
                        var str = $"0x{val}@0x{pos} is unknown/invalid";
                        Console.WriteLine(str);
                        throw new Exception(str);
                    }
                    else
                    {
                        source_codes.Add(code);
                    }
                }
            }
            Console.WriteLine($"Finished {file}");
        }