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); } }
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}"); }