private void InitPaths(BinaryReader br) { int loop = 0; do { sbyte nodes = br.ReadSByte(); br.BaseStream.Position += 3; SegmentAddress address = br.ReadBigInt32(); if (nodes > 0 && loop < 20 && (address.Offset < 0x2F_FFFF) && //assuming an address range of 0200 0000 to 022F FFFF, quite larger than expected address.Segment == 0x02) { var seekback = br.BaseStream.Position; Path_MQJson path = new Path_MQJson(); br.BaseStream.Position = address.Offset; for (int i = 0; i < nodes; i++) { var point = new short[] { br.ReadBigInt16(), br.ReadBigInt16(), br.ReadBigInt16() }; path.Points.Add(point); } Paths.Add(path); br.BaseStream.Position = seekback; loop++; } else { break; } }while (true); }
public CollisionCameraData(BinaryReader br) { CameraS = br.ReadBigInt16(); NumCameras = br.ReadBigInt16(); PositionAddress = br.ReadBigInt32(); if (PositionAddress != 0) { var seekback = br.Seek(PositionAddress.Offset); byte[] data; PositionList = new List <CollisionCameraPosition>(); for (int i = 0; i < NumCameras; i += 3) { data = br.ReadBytes(CollisionCameraPosition.SIZE); var pos = new CollisionCameraPosition(data); PositionList.Add(pos); } br.Seek(seekback); } else { PositionList = null; } }
public Record(BinaryReader br) { Cutscene = br.ReadBigInt32(); EntranceIndex = br.ReadBigInt16(); Spawn = br.ReadByte(); EventFlag = br.ReadByte(); }
public override void SetCommand(SceneWord command) { base.SetCommand(command); SegmentAddress = Command.Data2; if (SegmentAddress.Segment != (byte)ORom.Bank.scene) { throw new Exception(); } }
protected Header(BinaryReader br) { /* 0x00 */ Type = (Type)br.ReadByte(); Data = br.ReadByte(); br.BaseStream.Position += 2; /* 0x04 */ Start = br.ReadBigInt32(); }
public T0Header(BinaryReader br) : base(br) { /* 0x08 */ End = br.ReadBigInt32(); br.BaseStream.Position = Start.Offset; for (int i = 0; i < Entries; i++) { DisplayLists.Add(new DisplayEntry(br)); } }
public DataCenterElementRaw(ushort nameKey, ushort unknown, ushort argsCount, ushort subCount, SegmentAddress argsAddress, SegmentAddress subAddress) : this() { NameKey = nameKey; Unknown = unknown; ArgsCount = argsCount; SubCount = subCount; ArgsAddress = argsAddress; SubAddress = subAddress; }
public ActorList(Game game, SegmentAddress addr, int actors) { Address = addr; this.actors = actors; if (game == Game.OcarinaOfTime) { NewActor = ActorFactory.OcarinaActors; } else if (game == Game.MajorasMask) { NewActor = ActorFactory.MaskActors; } }
public Scene_MQJson(BinaryReader br, int id, int start, int end) { File = new File_MQJson() { Name = $"Scene {id}", Start = start.ToString("X8"), End = end.ToString("X8"), }; Id = id; SceneWord cmd = new SceneWord(); do { br.Read(cmd, 0, 8); var seekback = br.BaseStream.Position; HeaderCommands code = (HeaderCommands)cmd.Code; if (code == HeaderCommands.PathList) { SegmentAddress offset = cmd.Data2; br.BaseStream.Position = offset.Offset; InitPaths(br); } else if (code == HeaderCommands.TransitionActorList) { SegmentAddress actorOff = cmd.Data2; br.BaseStream.Position = actorOff.Offset; for (int i = 0; i < cmd.Data1; i++) { TActors.Add(Actor_MQJson.Read(br)); } } if (code == HeaderCommands.RoomList) { RoomsCount = (int)cmd.Data1; RoomsAddress = cmd.Data2; } br.BaseStream.Position = seekback; }while ((HeaderCommands)cmd.Code != HeaderCommands.End); }
public Room_MQJson(BinaryReader br, int sceneId, int roomId, int start, int end) { File = new File_MQJson() { Name = $"Scene {sceneId}, Room {roomId}", Start = start.ToString("X8"), End = end.ToString("X8"), }; Id = roomId; SceneWord cmd = new SceneWord(); do { br.Read(cmd, 0, 8); var seekback = br.BaseStream.Position; if ((HeaderCommands)cmd.Code == HeaderCommands.ObjectList) { SegmentAddress offset = cmd.Data2; br.BaseStream.Position = offset.Offset; for (int i = 0; i < cmd.Data1; i++) { Objects.Add(br.ReadBigInt16().ToString("X4")); } } else if ((HeaderCommands)cmd.Code == HeaderCommands.ActorList) { SegmentAddress actorOff = cmd.Data2; br.BaseStream.Position = actorOff.Offset; for (int i = 0; i < cmd.Data1; i++) { Actors.Add(Actor_MQJson.Read(br)); } } br.BaseStream.Position = seekback; }while ((HeaderCommands)cmd.Code != HeaderCommands.End); }
private void InitializeHeader(byte[] data) { Endian.Convert(out BoundsMin, data, 0x00); Endian.Convert(out BoundsMax, data, 0x06); Endian.Convert(out Vertices, data, 0x0C); Endian.Convert(out int temp, data, 0x10); VertexArray = new SegmentAddress(temp); Endian.Convert(out Polys, data, 0x14); Endian.Convert(out temp, data, 0x18); PolyArray = new SegmentAddress(temp); Endian.Convert(out temp, data, 0x1C); PolyTypeArray = new SegmentAddress(temp); Endian.Convert(out temp, data, 0x20); CameraDataArray = new SegmentAddress(temp); Endian.Convert(out WaterBoxes, data, 0x24); Endian.Convert(out temp, data, 0x28); WaterBoxesArray = new SegmentAddress(temp); }
public T1Header(BinaryReader br) : base(br) { /* 0x08 */ if (Format == 1) { Backgrounds.Add(new StaticBackground(br)); } else if (Format == 2) { byte count = br.ReadByte(); br.BaseStream.Position += 3; bgAddr = br.ReadBigInt32(); for (int i = 0; i < count; i++) { Backgrounds.Add(new StaticBackground(br, true)); br.BaseStream.Position += 2; } } br.BaseStream.Position = Start.Offset; DisplayLists.Add(new DisplayEntry(br)); }
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); }
internal DataCenterElementRaw GetElement(SegmentAddress address) { return(_elements[address]); }
internal DataCenterValueRaw GetValue(SegmentAddress address) { return(_values[address]); }
internal string GetString(SegmentAddress address) { return(_strings[address]); }
public DcObjectRaw(SegmentAddress argsAddress, int argsCount, SegmentAddress subAddress, int subCount) : this() { }
internal Segment(IApplicationLayerSniffer protocol) { myProtocol = protocol; myTelNum = new SegmentAddress("0"); }
public AlternateSetup(int setup, int segment) { SceneSetup = setup; SegmentAddress = segment; }
public override void SetCommand(SceneWord command) { base.SetCommand(command); Entries = Command.Data1; SegmentAddress = command.Data2; }
public SegmentAddress(SegmentAddress seg, int offset) : this(seg.Segment, offset) { }
} //Probably XLU public DisplayEntry(BinaryReader br) { DisplayList1 = br.ReadBigInt32(); DisplayList2 = br.ReadBigInt32(); }
public CollisionMesh(SegmentAddress headerOffset) { HeaderOffset = headerOffset; }
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()); }
private static string UnresolvedAddress(string v, SegmentAddress address) { return($"Unresolved {v} Address: {address}"); }
public void Initialize(BinaryReader br) { long seekBack; byte[] data; //initialize header data = new byte[HEADER_SIZE]; seekBack = br.Seek(HeaderOffset.Offset); br.Read(data, 0, HEADER_SIZE); InitializeHeader(data); //initialize polygon list data = new byte[CollisionPolygon.SIZE]; br.Seek(PolyArray.Offset); for (int i = 0; i < Polys; i++) { br.Read(data, 0, CollisionPolygon.SIZE); PolyList.Add(new CollisionPolygon(data)); } //initialize polygon types data = new byte[CollisionPolyType.SIZE]; br.Seek(PolyTypeArray.Offset); PolyTypes = GetPolygonTypeListLength(); for (int i = 0; i < PolyTypes; i++) { br.Read(data, 0, CollisionPolyType.SIZE); int hi = Endian.ConvertInt32(data, 0); int low = Endian.ConvertInt32(data, 4); PolyTypeList.Add(new CollisionPolyType(hi, low)); } //initialize vertex list br.Seek(VertexArray.Offset); for (int i = 0; i < Vertices; i++) { VertexList.Add(new Vector3 <short>(br.ReadBigInt16(), br.ReadBigInt16(), br.ReadBigInt16())); } //initialize camera data if (CameraDataArray != 0) { br.Seek(CameraDataArray.Offset); CameraDatas = GetCameraDataListLength(); for (int i = 0; i < CameraDatas; i++) { var camData = new CollisionCameraData(br); CameraDataList.Add(camData); if (CameraDataMin == 0 || (camData.PositionAddress != 0 && camData.PositionAddress.Offset < CameraDataMin.Offset)) { CameraDataMin = camData.PositionAddress; } } } //initialize water box data if (WaterBoxes > 0) { br.Seek(WaterBoxesArray.Offset); for (int i = 0; i < WaterBoxes; i++) { data = br.ReadBytes(CollisionWaterBox.SIZE); WaterBoxList.Add(new CollisionWaterBox(data)); } } br.Seek(seekBack); }