private void CompareFrameDumps(IExperimentFace face, List <string> file) { long pos; int f0h, f0l, f1h, f1l; StringBuilder sb = new StringBuilder(); using (BinaryReader f0 = new BinaryReader(new FileStream(file[0], FileMode.Open, FileAccess.Read))) { using (BinaryReader f1 = new BinaryReader(new FileStream(file[1], FileMode.Open, FileAccess.Read))) { while (f0.BaseStream.Position < f0.BaseStream.Length) { pos = f0.BaseStream.Position; f0h = f0.ReadBigInt32(); f0l = f0.ReadBigInt32(); f1h = f1.ReadBigInt32(); f1l = f1.ReadBigInt32(); if (f0h != f1h || f0l != f1l) { sb.AppendFormat("{0:X6}: {1:X8} {2:X8} | {3:X8} {4:X8}", pos, f0h, f0l, f1h, f1l); sb.AppendLine(); } } } } face.OutputText(sb.ToString()); }
public static void MQJsonImportAndPatch(IExperimentFace face, List <string> filePath) { Rom n0 = new ORom(filePath[0], ORom.Build.N0); Rom mq = new ORom(filePath[1], ORom.Build.MQU); List <Scene_MQJson> scenes = Load_Scene_MQJson(); foreach (var scene in scenes) { if (!MQRandoScenes.Contains(scene.Id)) { continue; } var n0_scene = SceneRoomReader.InitializeScene(n0, scene.Id); var mq_scene = SceneRoomReader.InitializeScene(mq, scene.Id); CollisionMesh n0_mesh = ((CollisionCommand)n0_scene.Header[HeaderCommands.Collision]).Mesh; CollisionMesh mq_mesh = ((CollisionCommand)mq_scene.Header[HeaderCommands.Collision]).Mesh; var delta = new Col_MQJson(n0_mesh, mq_mesh); scene.ColDelta = delta; } MemoryStream s = SerializeScenes(scenes); StreamReader sr = new StreamReader(s); face.OutputText(sr.ReadToEnd()); }
public static void TestYazDecompress(IExperimentFace face, List <string> filePath) { StringBuilder sb = new StringBuilder(); ORom compRom = new ORom(filePath[0], ORom.Build.N0); ORom decompRom = new ORom(@"C:\Users\mzxrules\Documents\Roms\N64\Games\Ocarina\Ocarina (U10)\Ocarina (U10) (d).z64", ORom.Build.N0); RomFile compFile = compRom.Files.GetFile(ORom.FileList.code); RomFile decompFile = decompRom.Files.GetFile(ORom.FileList.code); BinaryReader compReader = new BinaryReader(compFile); BinaryReader decompReader = new BinaryReader(decompFile); byte[] compText = compReader.ReadBytes(compFile.Record.VRom.Size); byte[] decompText = decompReader.ReadBytes(decompFile.Record.VRom.Size); for (int i = 0; i < compFile.Record.VRom.Size; i++) { byte a = decompText[i]; byte b = compText[i]; if (a == b) { continue; } sb.AppendLine($"DECOMPRESS MISMATCH {i:X6}: {a:X2} {b:X2}"); break; } sb.AppendLine("Test Complete"); face.OutputText(sb.ToString()); }
public static void MM3DGetItemTable(IExperimentFace face, List <string> file) { const int Get_Item_Table = 0x68F220; const int readStartIndex = -255; const int baseIndex = 1; List <MM3d.GetItemRecord> GetItems = new List <MM3d.GetItemRecord>(); using (BinaryReader br = new BinaryReader(new FileStream(file[0], FileMode.Open, FileAccess.Read))) { br.BaseStream.Position = MM3d.RAM.GetFileRelAddr(Get_Item_Table) + (8 * (readStartIndex - baseIndex)); for (int i = readStartIndex; i < 255; i++) { GetItems.Add(new MM3d.GetItemRecord((short)i, br)); } } StringBuilder sb = new StringBuilder(); foreach (MM3d.GetItemRecord record in GetItems) { sb.AppendLine(record.ToString()); } face.OutputText(sb.ToString()); }
public static void ImportMapData(IExperimentFace face, List <string> files) { Rom n0 = new ORom(files[0], ORom.Build.N0); Rom mq = new ORom(files[1], ORom.Build.MQU); var scenes = Load_Scene_MQJson(); const int dung_mark_vrom_mq = 0xBE78D8; N64Ptr dung_mark_vram_mq = 0x8085CFF8; var Minimaps = GetDungeonMinimaps(mq, dung_mark_vrom_mq, dung_mark_vram_mq); //const int floor_index_n0 = 0xB6C934; //const int floor_data_n0 = 0xBC7E00; const int floor_index_mq = 0xB6AFC4; const int floor_data_mq = 0xBB49E0; var FloorMap = GetDungeonFloorData(mq, floor_index_mq, floor_data_mq); for (int i = 0; i < 10; i++) { scenes[i].FloorMaps = FloorMap[i]; scenes[i].Minimaps = Minimaps[i]; } var ms = SerializeScenes(scenes); StreamReader sr = new StreamReader(ms); face.OutputText(sr.ReadToEnd()); }
private void RipRomsFromIso(IExperimentFace face, List <string> file) { byte[] buffer = new byte[0x1000]; using (var fs = new FileStream(file[0], FileMode.Open, FileAccess.Read)) { using (var rom1 = new FileStream("Mask (GCJ).z64", FileMode.Create, FileAccess.Write)) { //fs.Position = 0x52FBC1E0; //fs.Position = 0xC4E1FC0; fs.Position = 0x54FC1FC0; for (int i = 0; i < 0x2000000; i++) { rom1.WriteByte((byte)fs.ReadByte()); } } } //using (var fs = new FileStream(file[0], FileMode.Open, FileAccess.Read)) //{ // using (var rom2 = new FileStream("Ocarina (GCJ) (c).z64", FileMode.Create, FileAccess.Write)) // { // //fs.Position = 0x550569D8; // //fs.Position = 0x3B9D1FC0; // fs.Position = 0x27BD8000; // for (int i = 0; i < 0x2000000; i++) // { // rom2.WriteByte((byte)fs.ReadByte()); // } // } //} }
public static void DmaMap(IExperimentFace face, List <string> filePath) { Rom sourceRom = new MRom(filePath[0], MRom.Build.J0); Rom targetRom = new MRom(filePath[1], MRom.Build.U0); VFileTable source; //rom containing the complete file list VFileTable target; //rom we're using to link to file names Dictionary <long, FileRecord> unmatched = new Dictionary <long, FileRecord>(); //address pool Dictionary <long, FOut> fOut = new Dictionary <long, FOut>(); source = sourceRom.Files; target = targetRom.Files; //Load file table data foreach (FileRecord t in target) { if (t.VRom.End != 0) { fOut.Add(t.VRom.Start, new FOut(t)); } } foreach (FileRecord s in source) { if (s.VRom.End != 0) { unmatched.Add(s.VRom.Start, s); } } //match scene files MatchGeneric(TableInfo.Type.Scenes, source, target, fOut, unmatched); //match room files MatchRooms(source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.GameOvls, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.TitleCards, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.Actors, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.Objects, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.HyruleSkybox, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.Particles, source, target, fOut, unmatched); MatchGeneric(TableInfo.Type.Transitions, source, target, fOut, unmatched); StringBuilder sw = new StringBuilder(); { foreach (FOut item in fOut.Values) { FileAddress vS = item.Source; FileAddress vT = item.Target; sw.AppendLine($"{item.SourceIndex}\t{vS.Start}\t{vS.End}\t{item.TargetIndex}\t{vT.Start}\t{vT.End}"); } } face.OutputText(sw.ToString()); }
private void CompareFiles(IExperimentFace face, List <string> file) { using (FileStream f0 = new FileStream(file[0], FileMode.Open, FileAccess.Read)) { using (FileStream f1 = new FileStream(file[1], FileMode.Open, FileAccess.Read)) { face.OutputText(f0.IsDifferentTo(f1) ? "different" : "same"); } } }
public static void OutputMQJson(IExperimentFace face, List <string> filePath) { Rom n0 = new ORom(filePath[0], ORom.Build.N0); Rom mq = new ORom(filePath[1], ORom.Build.MQU); var rom_scenes = new List <List <Scene_MQJson> >(); List <Scene_MQJson> scenes; foreach (Rom rom in new Rom[] { n0, mq }) { scenes = new List <Scene_MQJson>(); foreach (int sceneId in MQRandoScenes) { if (sceneId == 12) { continue; } var sceneFile = rom.Files.GetSceneFile(sceneId); using (BinaryReader br = new BinaryReader(sceneFile)) { var va = sceneFile.Record.VRom; var scene = new Scene_MQJson(br, sceneId, va.Start, va.End); br.BaseStream.Position = scene.RoomsAddress.Offset; for (int roomId = 0; roomId < scene.RoomsCount; roomId++) { int start = br.ReadBigInt32(); int end = br.ReadBigInt32(); var roomFile = rom.Files.GetFile(start); var room = new Room_MQJson(new BinaryReader(roomFile), sceneId, roomId, start, end); scene.Rooms.Add(room); } scenes.Add(scene); } } rom_scenes.Add(scenes); } var n0_scenes = rom_scenes[0]; scenes = rom_scenes[1]; SetN0Addresses(scenes, n0_scenes); MemoryStream ms = SerializeScenes(scenes); StreamReader sr = new StreamReader(ms); string json = sr.ReadToEnd(); face.OutputText(json); }
public static void TestYazCompression(IExperimentFace face, List <string> filePath) { ORom rom = new ORom(filePath[0], ORom.Build.N0); StringBuilder sb = new StringBuilder(); foreach (var file in rom.Files) { if (!file.IsCompressed) { continue; } try { Stream vanillaFile = rom.Files.GetPhysicalFile(file.VRom); var decompressedFile = Yaz.Decode(vanillaFile, file.Rom.Size); MemoryStream ms = new MemoryStream(file.Rom.Size); sb.AppendLine($"{ Yaz.Encode(decompressedFile, decompressedFile.Length, ms):X8}"); while (ms.Length < ms.Capacity) { ms.WriteByte(0); } vanillaFile.Position = 0; ms.Position = 0; BinaryReader original = new BinaryReader(vanillaFile); BinaryReader test = new BinaryReader(ms); sb.AppendLine($"{file.VRom} - original: {original.BaseStream.Length:X8} test: {test.BaseStream.Length:X8}"); for (int i = 0; i < file.Rom.Size; i += 4) { int left = original.ReadBigInt32(); int right = test.ReadBigInt32(); if (left != right) { sb.AppendLine($"{file.VRom} - {i:X8} does not match, comparison stopped"); } } } catch (Exception e) { sb.AppendLine($"{file.VRom} - Exception {e.Message} {e.InnerException}"); } } face.OutputText(sb.ToString()); }
public static void Generate(IExperimentFace face, List <string> file) { byte[] buffer; MemoryStream ms; const int RecordLength = 0x1EC; const int RecordCount = 0x4158 / 0x1EC; ORom rom = new ORom(file[0], ORom.Build.MQU); var addr = rom.Files.GetPlayPauseAddress(0); var kaleido_scope = rom.Files.GetFile(addr); var kalBr = new BinaryReader(kaleido_scope); BinaryWriter newBw; using (FileStream fs = new FileStream(file[1], FileMode.Open)) { buffer = new byte[fs.Length]; ms = new MemoryStream(buffer); fs.CopyTo(ms); } newBw = new BinaryWriter(ms); ms.Position = 0x016C20; kaleido_scope.Stream.Position = kaleido_scope.Record.GetRelativeAddress(0xBB49E0); for (int i = 0; i < RecordCount; i++) { for (int j = 0; j < RecordLength; j += 4) { var word = kalBr.ReadBigInt32(); if (j == 0x8) { newBw.BaseStream.Position += 4; continue; } else { newBw.WriteBig(word); } } } using (FileStream fs = new FileStream("new_ovl_kaleido_scope", FileMode.Create)) { newBw.Seek(0, SeekOrigin.Begin); newBw.BaseStream.CopyTo(fs); } }
public static void RandomDrops(IExperimentFace face, List <string> file) { ORom rom = new ORom(file[0], ORom.Build.N0); StringBuilder sb = new StringBuilder(); var codeFile = rom.Files.GetFile(new RomFileToken(ORom.FileList.code)); long dropTableAddr = codeFile.Record.GetRelativeAddress(0xB5D764); BinaryReader br = new BinaryReader(codeFile); br.BaseStream.Position = dropTableAddr; for (int i = 0; i < 15; i++) { sb.AppendLine(new RandomDropTable(br).ToString()); } face.OutputText(sb.ToString()); }
public static void Test(IExperimentFace Face, List <String> Files) { ClassHelper debug = new ClassHelper(new ORom(Files[0], ORom.Build.DBGMQ)); ClassHelper ntsc10 = new ClassHelper(new ORom(Files[1], ORom.Build.N0)); TextureData sourceData; sourceData = GetTextureData("TextureExplorer/SourceTextureList.xml"); AdjustOffsets(sourceData); ntsc10.Data = new TextureData(); debug.Data = TrimSearchData(sourceData, ntsc10.Data); Dictionary <string, int> FileAddressPair = GetFileDatabase(); sb = new StringBuilder(); DoThings(debug, ntsc10, FileAddressPair); WriteTextureData(ntsc10.Data); Face.OutputText(sb.ToString()); }
public static void CutsceneSerializationTest(IExperimentFace face, List <string> file) { Cutscene cutscene; cutscene = SaveCutscene(file, KokiriEmeraldCs, "cs/kokiriemerald.z64"); cutscene = SaveCutscene(file, GoronRubyCs, "cs/goronruby.z64"); cutscene = SaveCutscene(file, ZoraSapphireCs, "cs/zorasapphire.z64"); cutscene = SaveCutscene(file, LightMedallionCs, "cs/lightmedallion.z64"); face.OutputText(cutscene.PrintByOccurrence()); cutscene = SaveCutscene(file, FireMedallionCs, "cs/firemedallion.z64"); cutscene = SaveCutscene(file, WaterMedallionCs, "cs/watermedallion.z64"); cutscene = SaveCutscene(file, SpiritMedallionCs, "cs/spiritmedallion.z64"); cutscene = SaveCutscene(file, ShadowMedallionCs, "cs/shadowmedallion.z64"); //cutscene = SaveCutscene(file, Ganonlol, "Ganonlol.z64"); cutscene = SaveCutscene(file, LightArrowCs, "cs/lightarrow.z64"); cutscene = SaveCutscene(file, TheEnd, "cs/theend.z64"); cutscene = SaveCutscene(file, MeetSheikTempleTimeCs, "cs/sheiktime.z64"); cutscene = SaveCutscene(file, ForestMedallionCs, "cs/forestmedallion.z64"); }
private void DmaDataCompare(IExperimentFace face, List <string> file) { ORom rom1 = new ORom(file[0], ORom.Build.GCU); ORom rom2 = new ORom(file[1], ORom.Build.GCU); //ORom ntsc = new ORom(file[3], ORom.Build.N0); StringBuilder sb = new StringBuilder(); var f1 = rom1.Files.ToList(); var f2 = rom2.Files.ToList(); for (int i = 0; i < f1.Count; i++) { var f1a = f1[i].VRom; var f2a = f2[i].VRom; if (f1a.Size != f2a.Size) { sb.AppendFormat("DMA Diff: {0:X8} {1:X8}\n", f1a.Start, f2a.Start); } var s1 = rom1.Files.GetFile(f1[i].VRom); var s2 = rom2.Files.GetFile(f2[i].VRom); if (s1.Stream.IsDifferentTo(s2)) { sb.AppendFormat("File Read Diff: {0:X8} {1:X8}\n", f1a.Start, f2a.Start); foreach (var item in s1.Stream.GetDelta(s2)) { if (item[1] + 0x10 != item[2]) { sb.AppendFormat("{0:X8}: {1:X8} {2:X8}\n", item[0], item[1], item[2]); } } } } face.OutputText(sb.ToString()); }
public static void GetCutsceneExitAsm(IExperimentFace face, List <string> file) { List <InCutsceneData> cutsceneData; Dictionary <int, _Scene> sceneInfo; StringBuilder sb = new(); ORom rom; string romLoc = file[0]; rom = new ORom(romLoc, ORom.Build.N0); //get list of cutscene bank offsets cutsceneData = GetCutsceneOffsetData(); //get stats on the scenes within the input list sceneInfo = GetSceneInfo(rom); InCutsceneData.GetSceneDelegate = sceneInfo.TryGetValue; foreach (InCutsceneData item in cutsceneData) { Cutscene cs; ExitCommand exit; RomFile sceneFile; sceneFile = rom.Files.GetSceneFile(item.scene); sceneFile.Stream.Position += item.offset & 0xFFFFFF; cs = new Cutscene(sceneFile); exit = cs.Commands.OfType <ExitCommand>().SingleOrDefault(); if (exit != null) { sb.AppendFormat("{0:D3}\t{1:D2}\t{2:X2}", item.scene, item.setup, exit.Asm); sb.AppendLine(); } } face.OutputText(sb.ToString()); }
public static void MM3DEntranceTable(IExperimentFace face, List <string> file) { const int Entrance_Index_Table = 0x69FB44; const int SceneCount = 0x70; List <MM3d.EntranceIndexRecord> eiRecord = new List <MM3d.EntranceIndexRecord>(); using (FileStream fs = new FileStream(file[0], FileMode.Open, FileAccess.Read)) { BinaryReader br = new BinaryReader(fs); br.BaseStream.Position = MM3d.RAM.GetFileRelAddr(Entrance_Index_Table); for (int scene = 0; scene < SceneCount; scene++) { eiRecord.Add(new MM3d.EntranceIndexRecord(scene, br)); } StringBuilder sb = new StringBuilder(); List <MM3d.EntranceRecord> entRecord = new List <MM3d.EntranceRecord>(); //For every external scene foreach (MM3d.EntranceIndexRecord record in eiRecord) { //if there are no entrances, don't bother going deeper if (record.Entrances == 0) { entRecord.Add(new MM3d.EntranceRecord(MM3d.EntranceIndex(record.scene, 0, 0))); continue; } int listPtr = MM3d.RAM.GetFileRelAddr(record.TablePointer); for (int ent = 0; ent < record.Entrances; ent++) { br.BaseStream.Position = listPtr + (ent * 4); int innerPtr = MM3d.RAM.GetFileRelAddr(br.ReadInt32()); for (int setup = 0; setup < 0x10; setup++) { var EntranceIndex = MM3d.EntranceIndex(record.scene, ent, setup); try { br.BaseStream.Position = innerPtr + (setup * 4); var temp = new MM3d.EntranceRecord(EntranceIndex, br); entRecord.Add(temp); } catch { entRecord.Add(new MM3d.EntranceRecord(EntranceIndex)); } } } } foreach (MM3d.EntranceRecord record in entRecord) { sb.AppendLine(record.ToString()); } face.OutputText(sb.ToString()); } }
public static void TestYazSimple(IExperimentFace face, List <string> filePath) { StringBuilder sb = new StringBuilder(); ORom rom = new ORom(filePath[0], ORom.Build.N0); RomFile rfile = rom.Files.GetFile(ORom.FileList.code); var dmarec_code = rfile.Record; BinaryReader compressed = new BinaryReader((MemoryStream)rom.Files.GetPhysicalFile(dmarec_code.VRom)); BinaryReader decompressed = new BinaryReader(rfile); byte[] decompressedbuffer = decompressed.ReadBytes(rfile.Record.VRom.Size); //var buffer = new MemoryStream(0x20_0000); var buffer = new byte[0]; Stopwatch stopwatch = Stopwatch.StartNew(); //int compressedSize = Yaz.Encode(decompressedbuffer, rfile.Record.VirtualAddress.Size, buffer); int compressedSize = Yaz.Encode(decompressedbuffer, rfile.Record.VRom.Size, out buffer); Yaz.GetEncodingData(buffer, compressedSize, out int metaSize); stopwatch.Stop(); sb.AppendLine($"Compression time: {stopwatch.Elapsed.Seconds}.{stopwatch.Elapsed.Milliseconds:D3}"); sb.AppendLine($"Compressed Size: {compressedSize:X6}, Meta Size {metaSize:X6}"); decompressed.Seek(0); //buffer.Position = 0; //compare compressed output if (compressedSize != dmarec_code.Rom.Size) { sb.AppendLine($"Compression size mismatch: Original {dmarec_code.Rom.Size:X6} || New {compressedSize:X6}"); } int mismatchMax = 8; for (int i = 0; i < dmarec_code.Rom.Size; i++) { byte a = compressed.ReadByte(); //byte b = (byte)buffer.ReadByte(); byte b = buffer[i]; if (a == b) { continue; } mismatchMax--; sb.AppendLine($"COMPRESS MISMATCH {i:X6}: {a:X2} {b:X2}"); if (mismatchMax <= 0) { break; } } compressed.Seek(0); //buffer.Position = 0; byte[] dbuffer = Yaz.Decode(new MemoryStream(buffer), compressedSize); decompressed.BaseStream.Position = 0; for (int i = 0; i < dbuffer.Length; i++) { if (dbuffer[i] != decompressed.ReadByte()) { sb.AppendLine($"File Size: {dbuffer.Length:X}, Compressed: {compressedSize:X}, Failed Match: {i:X}"); break; } } sb.AppendLine("Test Complete"); face.OutputText(sb.ToString()); }
private void GetBaseIndex(IExperimentFace face) { face.OutputText("not implemented;"); }
private void GetWWResult(IExperimentFace face) { face.OutputText("not implemented;"); }
public static void Generate(IExperimentFace face, List <string> file) { ZeldasBirthday zb = new ZeldasBirthday(); zb.Script(file[0]); }
public static void MQRandoCompareHeaders(IExperimentFace face, List <string> filePath) { Rom n0 = new ORom(filePath[0], ORom.Build.N0); Rom mq = new ORom(filePath[1], ORom.Build.MQU); StringWriter sw = new StringWriter(); foreach (Rom rom in new Rom[] { n0, mq }) { for (int i = 0; i < 16; i++) { var scn = rom.Files.GetSceneFile(i); BinaryReader br = new BinaryReader(scn); SceneWord cmd; SceneWord roomCmd = new SceneWord(); bool hasRoom = false; do { cmd = new SceneWord(); br.Read(cmd, 0, 8); //sw.WriteLine($"{i} -1 {cmd}"); if ((HeaderCommands)cmd.Code == HeaderCommands.RoomList) { hasRoom = true; roomCmd = cmd; } }while ((HeaderCommands)cmd.Code != HeaderCommands.End); if (hasRoom) { var seekback = br.BaseStream.Position; br.BaseStream.Position = ((SegmentAddress)roomCmd.Data2).Offset; for (int j = 0; j < roomCmd.Data1; j++) { var roomAddr = br.ReadBigInt32(); br.ReadBigInt32(); var roomFile = rom.Files.GetFile(roomAddr); BinaryReader brRoom = new BinaryReader(roomFile); do { cmd = new SceneWord(); brRoom.Read(cmd, 0, 8); //sw.WriteLine($"{i} {j} {cmd}"); if ((HeaderCommands)cmd.Code == HeaderCommands.ActorList) { var va = roomFile.Record.VRom; sw.WriteLine($"{i} {j} {va.Start:X8} {va.End:X8} {(cmd.Data1 * 0x10):X8}"); } }while ((HeaderCommands)cmd.Code != HeaderCommands.End); } br.BaseStream.Position = seekback; } } } face.OutputText(sw.ToString()); }
public static void CompareCollision(IExperimentFace face, List <string> filePath) { Rom n0 = new ORom(filePath[0], ORom.Build.N0); Rom mq = new ORom(filePath[1], ORom.Build.MQU); StringBuilder sb_n0 = new StringBuilder(); StringBuilder sb_mq = new StringBuilder(); foreach (int id in MQRandoScenes) { var n0_scene = SceneRoomReader.InitializeScene(n0, id); var mq_scene = SceneRoomReader.InitializeScene(mq, id); CollisionMesh n0_mesh = ((CollisionCommand)n0_scene.Header[HeaderCommands.Collision]).Mesh; CollisionMesh mq_mesh = ((CollisionCommand)mq_scene.Header[HeaderCommands.Collision]).Mesh; sb_n0.AppendLine($"Scene {id}"); sb_mq.AppendLine($"Scene {id}"); sb_n0.AppendLine(n0_mesh.Print()); sb_n0.AppendLine(); sb_n0.AppendLine(mq_mesh.Print()); sb_n0.AppendLine(); //PrintList(sb_n0, n0_mesh.CameraDataList); //PrintList(sb_n0, mq_mesh.CameraDataList); //PrintList(sb_n0, n0_mesh.WaterBoxList); //PrintList(sb_n0, mq_mesh.WaterBoxList); //for (int i = 0; i < n0_mesh.VertexList.Count; i++) //{ // var vertN0 = n0_mesh.VertexList[i]; // var vertMQ = mq_mesh.VertexList[i]; // if (vertN0 != vertMQ) // { // sb_n0.AppendLine($"{i:X4}: {vertN0}"); // sb_mq.AppendLine($"{i:X4}: {vertMQ}"); // } //} //for (int i = 0; i < n0_mesh.Polys; i++) //{ // var n0poly = n0_mesh.PolyList[i]; // var mqpoly = mq_mesh.PolyList[i]; // if (!n0poly.Equals(mqpoly)) // { // if (n0poly.VertexFlagsC != mqpoly.VertexFlagsC // || n0poly.VertexFlagsB != mqpoly.VertexFlagsB) // { // sb_n0.AppendLine($"{i:X4}: {n0poly}"); // sb_mq.AppendLine($"{i:X4}: {mqpoly}"); // } // } //} //sb_mq.AppendLine(); } string result = sb_n0.ToString() + $"{Environment.NewLine}~SPLIT{Environment.NewLine}" + sb_mq.ToString(); face.OutputText(result); }
public static void ImportMapData(IExperimentFace face, List <string> filePath) => MQJson.ImportMapData(face, filePath);
public static void AssSkulls(IExperimentFace face, List <string> filePath) { ORom r = new ORom(filePath[0], ORom.Build.N0); List <(FileAddress addr, int scene, int room, Room info)> lookup = new List <(FileAddress addr, int scene, int room, Room info)>(); for (int sceneId = 0; sceneId < r.Scenes; sceneId++) { var sceneFile = r.Files.GetSceneFile(sceneId); Scene scene = SceneRoomReader.InitializeScene(sceneFile, sceneId); scene.Header.InitializeAssets(new BinaryReader(sceneFile.Stream)); int roomId = -1; foreach (var roomAddr in scene.Header.GetRoomAddresses()) { roomId++; var roomFile = r.Files.GetFile(roomAddr); Room room = SceneRoomReader.InitializeRoom(roomFile); lookup.Add((roomAddr, sceneId, roomId, room)); } } //now for some ass StringBuilder sb = new StringBuilder(); for (int i = ass.GetLowerBound(0); i <= ass.GetUpperBound(0); i++) { for (int j = ass.GetLowerBound(1); j <= ass.GetUpperBound(1); j++) { foreach (var item in ass[i, j]) { if (item is ACTOR actor) { var(addr, scene, room, info) = lookup.Where(x => x.addr.Start <= actor.addr && x.addr.End > actor.addr).Single(); int setup = 0; if (info.Header.HasAlternateHeaders()) { for (int hId = 0; hId < info.Header.Alternate.Headers.Count; hId++) { var alt = info.Header.Alternate.Headers[hId]; if (alt == null) { continue; } var actorList = alt[HeaderCommands.ActorList]; if (actorList == null) { continue; } int actors = actorList.Command.Data1; SegmentAddress loc = actorList.Command.Data2; int actorsStart = addr.Start + loc.Offset; int actorsEnd = addr.End + loc.Offset + (0x10 * actors); if (actor.addr >= actorsStart && actor.addr < actorsEnd) { setup = hId + 1; break; } } } sb.AppendLine($"{i}\t{j}\t{scene}\t{room}\t{setup}\t{item.ToString()}"); } } } } face.OutputText(sb.ToString()); }
public static StringBuilder Calculate(IExperimentFace face, List <string> files) { StringBuilder result = new StringBuilder(); int N0_SceneEndAddr = 0x384980; int N0_CodeAddr = 0x110A0; SegmentAddress[] SegmentTable = new SegmentAddress[16]; Dictionary <short, EntranceTableRecord> EntranceTableSimplified = new Dictionary <short, EntranceTableRecord>(); Rom N0 = new ORom(files[0], ORom.Build.N0); Addresser.TryGetRom(ORom.FileList.code, N0.Version, AddressToken.EntranceIndexTable_Start, out int entranceTableAddress); Addresser.TryGetRom(ORom.FileList.code, N0.Version, AddressToken.ActorTable_Start, out int actorTableRomAddress); var code_File = N0.Files.GetFile(ORom.FileList.code); var codeStr = new BinaryReader(code_File); codeStr.BaseStream.Position = code_File.Record.GetRelativeAddress(entranceTableAddress); //remove redundant entrance table records for (int i = 0; i < 0x614; i++) { var record = new EntranceTableRecord(codeStr); short key = (short)((record.Scene << 8) + record.Spawn); if (!EntranceTableSimplified.ContainsKey(key)) { EntranceTableSimplified.Add(key, record); } } int lastScene = -1; RomFile scene_File = null; BinaryReader sceneStr = null; foreach (EntranceTableRecord record in EntranceTableSimplified.Values.OrderBy(x => x.Scene)) { if (sceneStr != null) { sceneStr.BaseStream.Position = 0; } if (record.Scene != lastScene) { if (record.Scene >= 101) { WriteResult(result, record, -1, ResultType.Crash, "No Scene"); continue; } scene_File = N0.Files.GetSceneFile(record.Scene); sceneStr = new BinaryReader(scene_File.Stream); SegmentTable[2] = N0_SceneEndAddr - scene_File.Record.VRom.Size; } //First, 0x18 command byte cmdId = sceneStr.ReadByte(); sceneStr.BaseStream.Position--; List <AlternateSetup> setups = new List <AlternateSetup>(); if (cmdId == 0x18) { sceneStr.BaseStream.Position += 4; int headerListOffset = sceneStr.ReadBigInt32() & 0xFFFFFF; sceneStr.BaseStream.Position = headerListOffset + 0xC; for (int i = 0; i < 0xD; i++) { int data = sceneStr.ReadBigInt32(); setups.Add(new AlternateSetup(i, data)); } } else { setups.Add(new AlternateSetup(-1, 0x02000000)); } //parse headers foreach (var setup in setups) { SceneHeader sceneHeader = new SceneHeader(); FaroresTest ft = FaroresTest.NA; //resolve header start if (setup.SegmentAddress.Segment != 2 || !(setup.SegmentAddress.Offset < scene_File.Record.VRom.Size)) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash_Likely, UnresolvedAddress("Scene Setup", setup.SegmentAddress)); continue; } //set header start sceneStr.BaseStream.Position = setup.SegmentAddress.Offset; int loop = 32; while (loop > 0) { loop--; cmdId = sceneStr.ReadByte(); sceneStr.BaseStream.Position--; switch (cmdId) { case 0x14: if (sceneHeader.Cutscene == 0) { WriteResult(result, record, setup.SceneSetup, ResultType.Cutscene_Pointer, "No Known Issues", ft); } else { WriteResult(result, record, setup.SceneSetup, ResultType.Cutscene, "No Known Issues", ft); } loop = -1; break; case 0x04: //room definitions { sceneStr.BaseStream.Position += 1; sceneHeader.Rooms = sceneStr.ReadByte(); sceneStr.BaseStream.Position += 2; sceneHeader.RoomsAddress = sceneStr.ReadBigInt32(); break; } case 0x06: //entrance index definitions { sceneStr.BaseStream.Position += 4; sceneHeader.EntranceIndexDefinitionsAddress = sceneStr.ReadBigInt32(); break; } case 0x00: //Link spawns definitions { long seekBack; sceneStr.BaseStream.Position += 1; sceneHeader.LinkSpawns = sceneStr.ReadByte(); sceneStr.BaseStream.Position += 2; sceneHeader.LinkSpawnsAddress = sceneStr.ReadBigInt32(); //start resolving things here I guess SegmentAddress selectEntDefAddr = sceneHeader.EntranceIndexDefinitionsAddress + (record.Spawn << 1); if (selectEntDefAddr.Segment != 2 && selectEntDefAddr.Offset > scene_File.Record.VRom.Size) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash_Likely, UnresolvedAddress("Entrance Definitions", selectEntDefAddr)); loop = -1; break; } seekBack = sceneStr.BaseStream.Position; sceneStr.BaseStream.Position = selectEntDefAddr.Offset; int spawnId = sceneStr.ReadByte(); int mapId = sceneStr.ReadByte(); //test if Link Spawn is invalid (phase 1) SegmentAddress selectSpawnAddr = sceneHeader.LinkSpawnsAddress + (spawnId << 4); if (selectSpawnAddr.Segment != 2 && selectSpawnAddr.Offset > scene_File.Record.VRom.Size) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash_Likely, UnresolvedAddress("Link Spawn", selectSpawnAddr), ft); loop = -1; break; } //test if Map Id is invalid, making FW mandatory if (!(mapId < sceneHeader.Rooms)) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash, string.Format("Invalid Room Id ({0})", mapId), FaroresTest.Without); ft = FaroresTest.With; //Don't break because we can continue parsing for FW purposes } //Check if Link spawn is valid (phase 2) sceneStr.BaseStream.Position = selectSpawnAddr.Offset; var actorId = sceneStr.ReadBigInt16(); int linkActorVarsRomAddr = actorId * 0x20 + 0x14; linkActorVarsRomAddr += actorTableRomAddress; var linkActorVarsRelOff = code_File.Record.GetRelativeAddress(linkActorVarsRomAddr); //pointer to Link's Actor vars can't be resolved if (linkActorVarsRelOff < 0 || !(linkActorVarsRelOff < code_File.Record.VRom.Size)) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash_Likely, UnresolvedAddress("Link Actor Var Pointer", (int)(linkActorVarsRelOff + N0_CodeAddr)), ft); loop = -1; break; } codeStr.BaseStream.Position = linkActorVarsRelOff; int linkActorVarsWriteAddr = codeStr.ReadBigInt32(); int linkActorVarsWriteOff = (linkActorVarsWriteAddr - N0_CodeAddr + 8) & 0xFFFFFF; //pointer to where to update Link's object number can't be resolved if (linkActorVarsWriteOff < 0 || !(linkActorVarsWriteOff < code_File.Record.VRom.Size)) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash_Likely, UnresolvedAddress("Link Object Dependency Write", linkActorVarsWriteAddr + 8), ft); loop = -1; break; } //check if pointer is going to do an unaligned write if (linkActorVarsWriteAddr % 2 == 1) { WriteResult(result, record, setup.SceneSetup, ResultType.Crash, string.Format("N64: Unaligned SH write to address {0:X8}", linkActorVarsWriteAddr + 8), ft); } sceneStr.BaseStream.Position = seekBack; break; } case 0x17: { sceneStr.BaseStream.Position += 4; sceneHeader.Cutscene = sceneStr.ReadBigInt32(); break; } default: sceneStr.BaseStream.Position += 8; break; } if (loop == 0) { WriteResult(result, record, setup.SceneSetup, ResultType.Error, "Header Parse Error"); } } } } face.OutputText(result.ToString()); return(result); }
private void GetWWResultFromData(IExperimentFace face, List <string> files) { UltimaWrongWarp.Calculate(face, files); }
private void ActorTaggingTest(IExperimentFace face) { face.OutputText("not implemented;"); }
public static void MMEntranceTable(IExperimentFace face, List <string> file) { MRom rom = new(file[0], MRom.Build.U0); //scenes (7 bits, 0x6E max) //entrance sets (5 bits, 32 max) //entrance setups(32 max) StringBuilder sb = new(); RomFile code = rom.Files.GetFile(MRom.FileList.code); BinaryReader br = new(code); int sceneBase; //Sets of entrance records per scene int entranceSetsPointerAddr; uint entranceSetsPointer; int entranceSetsAddr; //Single set of entrance records (single entrance) int eNumPointerAddr; uint eNumPointer; int eNumAddr; //get rom address of sceneTableBase sceneBase = Addresser.GetRom(MRom.FileList.code, rom.Version, AddressToken.EntranceIndexTable_Start); //for every scene for (int scene = 0; scene < 0x6E; scene++) { //get offset of pointer to the entrance sets entranceSetsPointerAddr = sceneBase + (sizeof(int) * 3) * scene + 4; //move the stream to the entrance sets pointer br.BaseStream.Position = code.Record.GetRelativeAddress(entranceSetsPointerAddr); //read the entranceSetsPointer (scene) entranceSetsPointer = br.ReadBigUInt32(); //if invalid if (!IsPointer(entranceSetsPointer) || !Addresser.TryGetRom (MRom.FileList.code, rom.Version, entranceSetsPointer, out entranceSetsAddr) || code.Record.GetRelativeAddress(entranceSetsAddr) >= code.Record.VRom.End) { //entrance index base, offset, sptr, eptr, entb1,2,3,4 sb.AppendFormat("{0:X4},{1},{2:X8},{3:X8},{4:X2},{5:X2},{6:X2},{7:X2}", GetEntranceIndex(scene, 0), 0, entranceSetsPointer, 0, 255, 0, 0, 0); sb.AppendLine(); continue; } //entranceSetsAddr now contains the rom address to the first entrance set pointer //for every theoretical entrance set for (int entranceSet = 0; entranceSet < 32; entranceSet++) { eNumPointerAddr = entranceSetsAddr + (sizeof(UInt32) * entranceSet); //move the stream to the entrance set pointer br.BaseStream.Position = code.Record.GetRelativeAddress(eNumPointerAddr); //read the entranceSetPointer (entrance set) eNumPointer = br.ReadBigUInt32(); //if invalid if (!IsPointer(eNumPointer) || !Addresser.TryGetRom (MRom.FileList.code, rom.Version, eNumPointer, out eNumAddr) || code.Record.GetRelativeAddress(eNumAddr) >= code.Record.VRom.End) { //entrance index base, offset, sptr, eptr, entb1,2,3,4 sb.AppendFormat("{0:X4},{1},{2:X8},{3:X8},{4:X2},{5:X2},{6:X2},{7:X2}", GetEntranceIndex(scene, entranceSet), 0, entranceSetsPointer, eNumPointer, 255, 0, 0, 0); sb.AppendLine(); continue; } //eNumAddr is valid br.BaseStream.Position = code.Record.GetRelativeAddress(eNumAddr); for (int entrance = 0; entrance < 32; entrance++) { //entrance index base, offset, sptr, eptr, entb1,2,3,4 sb.AppendFormat("{0:X4},{1},{2:X8},{3:X8},{4:X2},{5:X2},{6:X2},{7:X2}", GetEntranceIndex(scene, entranceSet), entrance, entranceSetsPointer, eNumPointer, br.ReadByte(), br.ReadByte(), br.ReadByte(), br.ReadByte()); sb.AppendLine(); } } } face.OutputText(sb.ToString()); }
public static void GetActors(IExperimentFace face, List <string> files) { }