/// <summary> /// Load an RM/SM file. /// </summary> /// <param name="path">Path to the file to load from.</param> /// <param name="type">Filetype. RM2, SM2, etc.</param> public void LoadFile(string path, FileType type) { if (!File.Exists(path)) { return; } Records = new List <TwinsItem>(); RecordIDs = new Dictionary <uint, int>(); var file = new FileStream(path, FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(file); Type = type; Console = ConsoleType.PS2; if (type == FileType.RMX || type == FileType.SMX) { Console = ConsoleType.XBOX; } if (type == FileType.Frontend) { TwinsSection sec = new TwinsSection { ID = 3, Type = SectionType.SE, }; var sk = reader.BaseStream.Position; sec.Load(reader, (int)file.Length); reader.BaseStream.Position = sk; RecordIDs.Add(3, Records.Count); Records.Add(sec); reader.Close(); return; } if ((Magic = reader.ReadUInt32()) != magic) { throw new Exception("LoadFile: Magic number is wrong."); } FileName = path; int count = 0; bool miniFix = false; if (type == FileType.MonkeyBallRM || type == FileType.MonkeyBallSM) { var sk = reader.BaseStream.Position; count = reader.ReadInt16(); uint test = reader.ReadUInt16(); if (test != 0) // PS2 starts off weird { reader.BaseStream.Position = sk; count = reader.ReadInt16(); reader.ReadByte(); miniFix = true; } else { Console = ConsoleType.PSP; reader.BaseStream.Position = sk; count = reader.ReadInt32(); } } else { count = reader.ReadInt32(); } var sec_size = reader.ReadUInt32(); if (miniFix) { reader.ReadByte(); } uint s_off = 0, s_id = 0; int s_size = 0; for (int i = 0; i < count; i++) { s_off = reader.ReadUInt32(); s_size = reader.ReadInt32(); s_id = reader.ReadUInt32(); switch (type) { case FileType.DemoRM2: case FileType.RMX: case FileType.RM2: { switch (s_id) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 10: case 11: { TwinsSection sec = new TwinsSection() { ID = s_id }; if (s_id <= 7) { if (type == FileType.DemoRM2) { sec.Type = SectionType.InstanceDemo; } else { sec.Type = SectionType.Instance; } } else if (s_id == 10) { if (type == FileType.DemoRM2) { sec.Type = SectionType.CodeDemo; } else if (type == FileType.RMX) { sec.Type = SectionType.CodeX; } else { sec.Type = SectionType.Code; } } else if (s_id == 11) { if (type == FileType.RMX) { sec.Type = SectionType.GraphicsX; } else if (type == FileType.DemoRM2) { sec.Type = SectionType.GraphicsD; } else { sec.Type = SectionType.Graphics; } } var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; sec.Level = 1; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 9: { ColData rec = new ColData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 8: { ParticleData rec = new ParticleData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.DemoSM2: case FileType.SM2: case FileType.SMX: { switch (s_id) { case 6: { SectionType targetType = SectionType.Graphics; if (type == FileType.SMX) { targetType = SectionType.GraphicsX; } if (type == FileType.DemoSM2) { targetType = SectionType.GraphicsD; } TwinsSection sec = new TwinsSection { ID = s_id, Type = targetType, Level = 1 }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 5: { ChunkLinks rec = new ChunkLinks { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 0: { SceneryData rec = new SceneryData { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 4: { DynamicSceneryData rec = new DynamicSceneryData { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.MonkeyBallRM: { switch (s_id) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 11: case 12: { TwinsSection sec = new TwinsSection() { ID = s_id }; if (s_id == 12) { sec.Type = SectionType.GraphicsMB; } else if (s_id == 11) { sec.Type = SectionType.CodeMB; } else { sec.Type = SectionType.InstanceMB; } var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; sec.Level = 1; sec.Load(reader, s_size, miniFix); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 9: { ParticleData rec = new ParticleData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size, true); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 10: { if (!miniFix) { ColData rec = new ColData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); } else { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); } break; } default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.MonkeyBallSM: { switch (s_id) { //5: Dynamic Scenery Data, but different //0: Scenery Data, but different default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 8: { SectionType targetType = SectionType.SceneryMB; TwinsSection sec = new TwinsSection { ID = s_id, Type = targetType, Level = 1 }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 5: { DynamicSceneryDataMB rec = new DynamicSceneryDataMB { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 7: { // usually all empty SectionType targetType = SectionType.GraphicsMB; TwinsSection sec = new TwinsSection { ID = s_id, Type = targetType, Level = 1 }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 6: { if (!miniFix) { ChunkLinks rec = new ChunkLinks { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } else { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } } break; } } reader.Close(); }
/// <summary> /// Load an RM/SM file. /// </summary> /// <param name="path">Path to the file to load from.</param> /// <param name="type">Filetype. RM2, SM2, etc.</param> public void LoadFile(string path, FileType type) { if (!File.Exists(path)) { return; } Records = new List <TwinsItem>(); RecordIDs = new Dictionary <uint, int>(); BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)); Type = type; if ((Magic = reader.ReadUInt32()) != magic) { throw new Exception("LoadFile: Magic number is wrong."); } FileName = path; var count = reader.ReadInt32(); var sec_size = reader.ReadUInt32(); uint s_off = 0, s_id = 0; int s_size = 0; for (int i = 0; i < count; i++) { s_off = reader.ReadUInt32(); s_size = reader.ReadInt32(); s_id = reader.ReadUInt32(); switch (type) { case FileType.DemoRM2: case FileType.RMX: case FileType.RM2: { switch (s_id) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 10: case 11: { TwinsSection sec = new TwinsSection() { ID = s_id }; if (s_id <= 7) { if (type == FileType.DemoRM2) { sec.Type = SectionType.InstanceDemo; } else { sec.Type = SectionType.Instance; } } else if (s_id == 10) { if (type == FileType.DemoRM2) { sec.Type = SectionType.CodeDemo; } else if (type == FileType.RMX) { sec.Type = SectionType.CodeX; } else { sec.Type = SectionType.Code; } } else if (s_id == 11) { if (type == FileType.RMX) { sec.Type = SectionType.GraphicsX; } else if (type == FileType.DemoRM2) { sec.Type = SectionType.GraphicsD; } else { sec.Type = SectionType.Graphics; } } var sk = reader.BaseStream.Position; reader.BaseStream.Position = sec.Offset = s_off; sec.Level = 1; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 9: { ColData rec = new ColData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 8: { ParticleData rec = new ParticleData() { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.DemoSM2: case FileType.SM2: case FileType.SMX: { switch (s_id) { case 6: { SectionType targetType = SectionType.Graphics; if (type == FileType.SMX) { targetType = SectionType.GraphicsX; } if (type == FileType.DemoSM2) { targetType = SectionType.GraphicsD; } TwinsSection sec = new TwinsSection { ID = s_id, Type = targetType, Level = 1 }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = sec.Offset = s_off; sec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(sec); break; } case 5: { ChunkLinks rec = new ChunkLinks { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 0: { SceneryData rec = new SceneryData { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } case 4: { DynamicSceneryData rec = new DynamicSceneryData { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.BIN: { switch (s_id) { default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; case FileType.DIR: { switch (s_id) { default: { TwinsItem rec = new TwinsItem { ID = s_id }; var sk = reader.BaseStream.Position; reader.BaseStream.Position = rec.Offset = s_off; rec.Load(reader, s_size); reader.BaseStream.Position = sk; RecordIDs.Add(s_id, Records.Count); Records.Add(rec); break; } } } break; } } reader.Close(); }