public ObjectTableEntry(ROMHandler rom, int ofs, bool isrel, ushort number = 0) { ROM = rom; Offset = ofs; IsOffsetRelative = isrel; StartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs)); EndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 4)); IsValid = ((StartAddress > rom.Code.VStart) && (StartAddress < rom.Size) && (EndAddress < rom.Size) && ((StartAddress & 0xF) == 0) && ((EndAddress & 0xF) == 0) && (EndAddress > StartAddress)); IsEmpty = (StartAddress == 0 && EndAddress == 0); Name = "N/A"; if (IsValid == true && IsEmpty == false) { if ((Name = (ROM.XMLObjectNames.Names[number] as string)) == null) { DMA = rom.Files.Find(x => x.PStart == StartAddress); if (DMA != null) { Name = DMA.Name; } else { Name = string.Format("S{0:X}_E{1:X}", StartAddress, EndAddress); } } } }
public DMATableEntry(ROMHandler rom, int idx) { int readofs = (rom.DMATableAddress + (idx * 0x10)); VStart = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs)); VEnd = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 4)); PStart = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 8)); PEnd = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 12)); if (PStart == 0xFFFFFFFF || PEnd == 0xFFFFFFFF) { IsValid = false; } else { IsValid = true; if (PEnd != 0 && Encoding.ASCII.GetString(rom.Data, (int)PStart, 4) == "Yaz0") { IsCompressed = true; } else { IsCompressed = false; } } Name = string.Format("File #{0}", idx); FileType = FileTypes.Undefined; AssumedSegment = 0x00; }
public RoomInfoClass(ROMHandler.ROMHandler rom, IHeaderParent parent, int num, uint s = 0, uint e = 0) { ROM = rom; Start = s; End = e; Parent = parent; Number = (ulong)num; if (Start != 0 && End != 0 && Start < rom.Data.Length && End < rom.Data.Length) { ROMHandler.DMATableEntry dma = ROM.Files.Find(x => x.PStart == Start); if (dma != null) DMAFilename = dma.Name; Data = new byte[End - Start]; Array.Copy(ROM.Data, Start, Data, 0, End - Start); if ((Description = (ROM.XMLRoomNames.Names[Start] as string)) == null) { ROMHandler.ISceneTableEntry parentste = (parent as ROMHandler.ISceneTableEntry); if (parentste.IsNameExternal()) { Description = string.Format("Room {0}", (Number + 1)); } else { if (dma != null) Description = DMAFilename; else Description = string.Format("S{0:X}-E{1:X}", Start, End); } } Load(); } }
public F3DEX2Interpreter(ROMHandler.ROMHandler rom) { ROM = rom; ActiveGLDL = new Stack<OpenGLHelpers.DisplayListEx>(); InitializeParser(); InitializeMacros(); LastTriList = new List<SimpleTriangle>(); VertexBuffer = new Vertex[32]; rdphalf1 = GeometryMode = OtherModeH = LastComb0 = LastComb1 = 0; OtherModeL = SimpleF3DEX2.OtherModeL.Empty; mtxstack = new Stack<Matrix4d>(); mtxstack.Push(Matrix4d.Identity); Textures = new Texture[2]; Textures[0] = new Texture(); Textures[1] = new Texture(); palette = new Color4[256]; texcache = new List<TextureCache>(); activetex = 0; multitex = false; ScaleS = new float[2]; ScaleT = new float[2]; InitCombiner(); }
public Generic(ROMHandler.ROMHandler rom, IHeaderParent parent, HeaderLoader.CommandTypeIDs cmdid) { ROM = rom; InROM = false; Command = cmdid; Offset = -1; Data = ulong.MaxValue; Parent = parent; }
public TableEditorForm(ROMHandler.ROMHandler rom) { InitializeComponent(); ROM = rom; InitializeDataGridViews(); dgvEntranceTable.Select(); }
public TableEditorForm(ROMHandler.ROMHandler rom) { InitializeComponent(); ROM = rom; InitializeDataGridViews(); dgvEntranceTable.Select(); }
public EntranceTableEntry(ROMHandler rom, int ofs, bool isrel) { ROM = rom; Offset = ofs; IsOffsetRelative = isrel; SceneNumber = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs]; EntranceNumber = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 1]; Variable = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 2]; Fade = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 3]; }
public EntranceTableEntry(ROMHandler rom, int ofs, bool isrel) { ROM = rom; Offset = ofs; IsOffsetRelative = isrel; SceneNumber = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs]; EntranceNumber = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 1]; Variable = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 2]; Fade = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 3]; }
public TitleCardForm(ROMHandler.ROMHandler rom, ROMHandler.SceneTableEntryOcarina ste) { InitializeComponent(); ROM = rom; Scene = ste; ofdImage.SetCommonImageFilter("png"); sfdImage.SetCommonImageFilter("png"); ReadImageFromROM(); }
public TitleCardForm(ROMHandler.ROMHandler rom, ROMHandler.SceneTableEntryOcarina ste) { InitializeComponent(); ROM = rom; Scene = ste; ofdImage.SetCommonImageFilter("png"); sfdImage.SetCommonImageFilter("png"); ReadImageFromROM(); }
public SceneTableEntryOcarina(ROMHandler rom, int ofs, bool isrel) { ROM = rom; inROM = true; Offset = ofs; IsOffsetRelative = isrel; sceneStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs)); sceneEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 4)); LabelStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 8)); LabelEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 12)); Unknown1 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 16]; ConfigurationNo = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 17]; Unknown3 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 18]; Unknown4 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 19]; if (IsValid() && !IsAllZero()) { DMATableEntry dma = rom.Files.Find(x => x.PStart == sceneStartAddress); if (dma != null) { dmaFilename = dma.Name; } if ((Name = ROM.XMLSceneNames.Names[sceneStartAddress] as string) == null) { isNameExternal = false; if (dma != null) { Name = dmaFilename; } else { Name = string.Format("S{0:X}_L{1:X}", sceneStartAddress, LabelStartAddress); } } else { isNameExternal = true; } data = new byte[sceneEndAddress - sceneStartAddress]; Array.Copy(ROM.Data, sceneStartAddress, data, 0, sceneEndAddress - sceneStartAddress); } }
public Entry(ROMHandler.ROMHandler rom, uint adr, int no, bool isspawn, bool istrans) { ROM = rom; Address = adr; NumberInList = no; IsSpawnPoint = isspawn; IsTransitionActor = istrans; /* Load raw data */ RawData = new byte[16]; byte[] segdata = (byte[])ROM.SegmentMapping[(byte)(adr >> 24)]; if (segdata == null) return; Buffer.BlockCopy(segdata, (int)(adr & 0xFFFFFF), RawData, 0, RawData.Length); /* Find definition, internal name */ RefreshVariables(); }
public HeaderLoader(ROMHandler rom, IHeaderParent parent, byte seg, int ofs, int number) { Parent = parent; Offset = ofs; Segment = seg; Number = number; Commands = new List<Generic>(); Generic cmd = null; while ((cmd = new Generic(rom, parent, seg, ref ofs)).Command != CommandTypeIDs.EndOfHeader) { Type cmdtype = (Type)CommandTypes[cmd.Command]; object inst = Activator.CreateInstance((cmdtype == null ? typeof(Generic) : cmdtype), new object[] { cmd }); Commands.Add((Generic)inst); } }
public HeaderLoader(ROMHandler rom, IHeaderParent parent, byte seg, int ofs, int number) { Parent = parent; Offset = ofs; Segment = seg; Number = number; Commands = new List <Generic>(); Generic cmd = null; while ((cmd = new Generic(rom, parent, seg, ref ofs)).Command != CommandTypeIDs.EndOfHeader) { Type cmdtype = (Type)CommandTypes[cmd.Command]; object inst = Activator.CreateInstance((cmdtype == null ? typeof(Generic) : cmdtype), new object[] { cmd }); Commands.Add((Generic)inst); } }
public SceneTableEntryMajora(ROMHandler rom, string fn) { ROM = rom; inROM = false; Offset = -1; IsOffsetRelative = false; sceneStartAddress = sceneEndAddress = 0; Unknown1 = Unknown2 = Unknown3 = Unknown4 = 0; System.IO.FileStream fs = new System.IO.FileStream(fn, System.IO.FileMode.Open); data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length); fs.Close(); Name = System.IO.Path.GetFileNameWithoutExtension(fn); }
public Generic(ROMHandler.ROMHandler rom, IHeaderParent parent, byte seg, ref int ofs) { ROM = rom; Command = (HeaderLoader.CommandTypeIDs)((byte[])rom.SegmentMapping[seg])[ofs]; Offset = ofs; Data = Endian.SwapUInt64(BitConverter.ToUInt64(((byte[])rom.SegmentMapping[seg]), ofs)); Parent = parent; ofs += 8; if (parent is HeaderCommands.Rooms.RoomInfoClass && (parent as HeaderCommands.Rooms.RoomInfoClass).Parent is SceneTableEntryOcarina) { ISceneTableEntry ste = ((parent as HeaderCommands.Rooms.RoomInfoClass).Parent as ISceneTableEntry); InROM = ste.IsInROM(); } else if (parent is ISceneTableEntry) { InROM = (parent as ISceneTableEntry).IsInROM(); } }
public SceneTableEntryMajora(ROMHandler rom, string fn) { ROM = rom; inROM = false; Offset = -1; IsOffsetRelative = false; sceneStartAddress = sceneEndAddress = 0; Unknown1 = Unknown2 = Unknown3 = Unknown4 = 0; System.IO.FileStream fs = new System.IO.FileStream(fn, System.IO.FileMode.Open); data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length); fs.Close(); Name = System.IO.Path.GetFileNameWithoutExtension(fn); }
public PathHeader(ROMHandler.ROMHandler rom, uint adr, int number) { ROM = rom; Address = adr; PathNumber = number; byte[] segdata = (byte[])ROM.SegmentMapping[(byte)(adr >> 24)]; if (segdata == null) return; WaypointCount = BitConverter.ToUInt32(segdata, (int)(adr & 0xFFFFFF)); WaypointAddress = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)(adr & 0xFFFFFF) + 4)); byte[] psegdata = (byte[])ROM.SegmentMapping[(byte)(WaypointAddress >> 24)]; if (WaypointCount == 0 || WaypointCount > 0xFF || psegdata == null || (WaypointAddress & 0xFFFFFF) >= psegdata.Length) return; Points = new List<Waypoint>(); for (int i = 0; i < WaypointCount; i++) { Points.Add(new Waypoint(ROM, (uint)(WaypointAddress + (i * 6)))); } }
public SceneTableEntryOcarina(ROMHandler rom, int ofs, bool isrel) { ROM = rom; inROM = true; Offset = ofs; IsOffsetRelative = isrel; sceneStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs)); sceneEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 4)); LabelStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 8)); LabelEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 12)); Unknown1 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 16]; ConfigurationNo = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 17]; Unknown3 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 18]; Unknown4 = (IsOffsetRelative ? rom.CodeData : rom.Data)[ofs + 19]; if (IsValid() && !IsAllZero()) { DMATableEntry dma = rom.Files.Find(x => x.PStart == sceneStartAddress); if (dma != null) dmaFilename = dma.Name; if ((Name = (ROM.XMLSceneNames.Names[sceneStartAddress] as string)) == null) { isNameExternal = false; if (dma != null) Name = dmaFilename; else Name = string.Format("S{0:X}_L{1:X}", sceneStartAddress, LabelStartAddress); } else isNameExternal = true; data = new byte[sceneEndAddress - sceneStartAddress]; Array.Copy(ROM.Data, sceneStartAddress, data, 0, sceneEndAddress - sceneStartAddress); } }
public DMATableEntry(ROMHandler rom, int idx) { int readofs = (rom.DMATableAddress + (idx * 0x10)); VStart = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs)); VEnd = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 4)); PStart = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 8)); PEnd = Endian.SwapUInt32(BitConverter.ToUInt32(rom.Data, readofs + 12)); if (PStart == 0xFFFFFFFF || PEnd == 0xFFFFFFFF) IsValid = false; else { IsValid = true; if (PEnd != 0 && Encoding.ASCII.GetString(rom.Data, (int)PStart, 4) == "Yaz0") IsCompressed = true; else IsCompressed = false; } Name = string.Format("File #{0}", idx); FileType = FileTypes.Undefined; AssumedSegment = 0x00; }
public void Identify(ROMHandler rom) { FileTypes fnassumed = FileTypes.General; if (rom.FileNameTableAddress != -1) { if (Name.EndsWith("_scene") == true) fnassumed = FileTypes.Scene; else if (Name.Contains("_room_") == true) fnassumed = FileTypes.Room; else if (Name.StartsWith("ovl_") == true) fnassumed = FileTypes.Overlay; else if (Name.StartsWith("object_") == true) fnassumed = FileTypes.Object; } /* Invalid file? */ if (!IsValid || VEnd - VStart == 0) { FileType = FileTypes.Invalid; return; } if (!IsCompressed) { byte[] data = new byte[VEnd - VStart]; Buffer.BlockCopy(rom.Data, (int)PStart, data, 0, data.Length); /* Room file? */ if (BitConverter.ToUInt32(data, (int)0) == 0x16 || ((BitConverter.ToUInt32(data, (int)0) == 0x18) && data[4] == 0x03 && BitConverter.ToUInt32(data, (int)8) == 0x16)) { for (int i = 8; i < HeaderScanThreshold; i += 8) if (BitConverter.ToUInt32(data, i) == 0x14 && (fnassumed == FileTypes.General || fnassumed == FileTypes.Room)) { AssumedSegment = 0x03; FileType = FileTypes.Room; return; } } /* Scene file? */ if ((BitConverter.ToUInt32(data, (int)0) & 0xFFFF00FF) == 0x15 || ((BitConverter.ToUInt32(data, (int)0) == 0x18) && data[4] == 0x02 && (BitConverter.ToUInt32(data, (int)8) & 0xFFFF00FF) == 0x15)) { for (int i = 8; i < HeaderScanThreshold; i += 8) if (BitConverter.ToUInt32(data, i) == 0x14 && (fnassumed == FileTypes.General || fnassumed == FileTypes.Scene)) { AssumedSegment = 0x02; FileType = FileTypes.Scene; return; } } /* Overlay file? */ uint ovlheader = ((uint)data.Length - Endian.SwapUInt32(BitConverter.ToUInt32(data, (data.Length - 4)))); if ((ovlheader + 16) < data.Length) { uint btext = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader)); uint bdata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 4)); uint brodata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 8)); uint bssdata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 12)); if ((btext + bdata + brodata == data.Length || btext + bdata + brodata == ovlheader) && (fnassumed == FileTypes.General || fnassumed == FileTypes.Overlay)) { FileType = FileTypes.Overlay; return; } } /* Object file? */ bool indl, hassync, hasvtx, hasdlend; int[] segcount = new int[16]; indl = hassync = hasvtx = hasdlend = false; for (int i = 0; i < data.Length; i += 8) { if (BitConverter.ToUInt32(data, i) == 0xE7 && BitConverter.ToUInt32(data, i + 4) == 0x0) { hassync = true; indl = true; } else if (indl && data[i] == 0x01 && data[i + 4] <= 0x0F) { hasvtx = true; segcount[data[i + 4]]++; } else if (BitConverter.ToUInt32(data, i) == 0xDF && BitConverter.ToUInt32(data, i + 4) == 0x0) { hasdlend = true; indl = false; } } if (hassync && hasvtx && hasdlend && (fnassumed == FileTypes.General || fnassumed == FileTypes.Object)) { AssumedSegment = (byte)segcount.ToList().IndexOf(segcount.Max()); FileType = FileTypes.Object; return; } /* Empty file? */ if (data.Length < 0x100) { int isempty = data.Count(x => x != 0); if (isempty == 0) { FileType = FileTypes.Empty; return; } } } /* Use assumption */ FileType = fnassumed; }
public GameActor(ROMHandler.ROMHandler rom, ActorTableEntry ate) { ROM = rom; ATEntry = ate; /* General stuff */ HierarchyAddresses = new List<AddressClass>(); AnimationAddresses = new List<AddressClass>(); Hierarchies = new List<LimbClass[]>(); HierarchyMatrices = new List<byte[]>(); GlobalTranslation = Vector3d.Zero; /* Object list */ ObjectsUsed = new List<ObjectTableEntry>(); ObjectsUsed.Add(ROM.Objects[1]); ObjectsUsed.Add(ROM.Objects[2]); ObjectsUsed.Add(ROM.Objects[3]); ObjectsUsed.Add(ROM.Objects[ATEntry.ObjectNumber]); /* Display list list */ DisplayLists = new List<DisplayListEx>(); /* Numbers */ TotalFrames = CurrentHierarchy = CurrentAnimation = CurrentFrame = 0; /* Temp DL address list */ List<uint> dladrs = new List<uint>(); /* MIPS evaluation of overlay */ if (ATEntry.StartAddress != 0) { DMATableEntry ovldma = ROM.Files.Find(x => x.VStart == ATEntry.StartAddress); if (ovldma != null) { try { /* Create evaluator and begin */ //LogWriter = System.IO.File.CreateText("E:\\temp\\sorata\\log.txt"); MIPS = new MIPSEvaluator(rom, ovldma, ATEntry.RAMStartAddress, new MIPSEvaluator.RegisterHookDelegate(RegisterChecker), 0); MIPS.BeginEvaluation(); //LogWriter.Close(); /* Parse results for DL addresses & additional objects */ foreach (MIPSEvaluator.Result res in MIPS.Results) { if (res.TargetAddress == (FunctionDisplayList1 & 0xFFFFFF) && res.Arguments[1] != 0) dladrs.Add(res.Arguments[1]); else if (res.TargetAddress == (FunctionDisplayList2 & 0xFFFFFF) && res.Arguments[3] != 0) dladrs.Add(res.Arguments[3]); else if (res.TargetAddress == (FunctionDisplayList3 & 0xFFFFFF) && res.Arguments[0] != 0) dladrs.Add(res.Arguments[0]); if (res.TargetAddress == (FunctionObjectNumber & 0xFFFFFF) && res.Arguments[1] != 0 && (ushort)res.Arguments[1] < ROM.ObjectCount) ObjectsUsed.Add(ROM.Objects[(ushort)res.Arguments[1]]); } /* Log results with address arguments in segments 0x04, 0x05 or 0x06 */ //LogSuspiciousResults(); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Exception in MIPS evaluator!\n\n" + ex.ToString() + "\n\nPlease notify the developers of this error!", "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); } } } /* If no hierarchy/animation addresses found, use addresses from MIPS evaluation if any */ if (MIPS != null && (HierarchyAddresses.Count == 0 || AnimationAddresses.Count == 0)) { foreach (MIPSEvaluator.Result res in MIPS.Results) { if (res.TargetAddress == (FunctionHierarchyAnim1 & 0xFFFFFF) || res.TargetAddress == (FunctionHierarchyAnim2 & 0xFFFFFF)) { HierarchyAddresses.Add(new AddressClass(res.Arguments[2])); AnimationAddresses.Add(new AddressClass(res.Arguments[3])); } } } /* Remove garbage zeroes from address results */ HierarchyAddresses.RemoveAll(x => x.Address == 0); AnimationAddresses.RemoveAll(x => x.Address == 0); /* Parse objects & scan for hierarchies and animations if needed */ for (int i = 0; i < ObjectsUsed.Count; i++) { if (ObjectsUsed[i].DMA != null) { byte seg = (byte)(ObjectsUsed[i].DMA.AssumedSegment == 0 ? 0x06 : ObjectsUsed[i].DMA.AssumedSegment); byte[] loadsegdata = new byte[ObjectsUsed[i].DMA.PEnd - ObjectsUsed[i].DMA.PStart]; Buffer.BlockCopy(rom.Data, (int)ObjectsUsed[i].DMA.PStart, loadsegdata, 0, loadsegdata.Length); ROM.SegmentMapping.Remove((byte)0x06); ROM.SegmentMapping.Add((byte)0x06, loadsegdata); if (seg == 0x06/* && HierarchyAddresses.Count == 0*/) ScanForHierarchies(seg); if (seg == 0x06/* && AnimationAddresses.Count == 0*/) ScanForAnimations(seg); } } /* Hackish RAM segment generation for facial textures */ ProcessFacialTextureHack(); /* Ensure display list address validity */ dladrs = dladrs.Where(x => ROM.IsAddressSupported(x) == true).ToList(); /* If still no hierarchy/animation and display list addresses found, search for display lists in segment 0x06 */ if (HierarchyAddresses.Count == 0 && AnimationAddresses.Count == 0 && dladrs.Count == 0) dladrs = ScanForDisplayLists(0x06); /* Execute display lists */ if (dladrs != null) { foreach (uint dla in dladrs) { DisplayListEx dlex = new DisplayListEx(ListMode.Compile); ROM.Renderer.Render(dla); dlex.End(); DisplayLists.Add(dlex); } } /* Clean up address results */ if (HierarchyAddresses.Count != 0 && AnimationAddresses.Count != 0) { HierarchyAddresses = HierarchyAddresses.Where(x => ROM.IsAddressSupported(x.Address) == true).GroupBy(x => x.Address).Select(x => x.First()).ToList(); AnimationAddresses = AnimationAddresses.Where(x => ROM.IsAddressSupported(x.Address) == true).GroupBy(x => x.Address).Select(x => x.First()).ToList(); } /* Initial data read */ ReadHierarchies(); ReadAnimation(CurrentHierarchy, CurrentAnimation, CurrentFrame); }
public ActorTableEntry(ROMHandler rom, int ofs, bool isrel) { ROM = rom; Offset = ofs; IsOffsetRelative = isrel; StartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs)); EndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 4)); RAMStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 8)); RAMEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 12)); Unknown1 = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 16)); ActorInfoRAMAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 20)); ActorNameRAMAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 24)); Unknown2 = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 28)); IsValid = (ActorInfoRAMAddress >> 24 == 0x80) && (((ActorNameRAMAddress >> 24 == 0x80) && (ActorNameRAMAddress - ROMHandler.CodeRAMAddress) < rom.CodeData.Length) || (ActorNameRAMAddress == 0)); IsIncomplete = (StartAddress == 0 && EndAddress == 0 && RAMStartAddress == 0 && RAMEndAddress == 0); IsComplete = (StartAddress > rom.Code.VStart && StartAddress < rom.Size) && (EndAddress > StartAddress && EndAddress > rom.Code.VStart && EndAddress < rom.Size) && (RAMStartAddress >> 24 == 0x80) && (RAMEndAddress > RAMStartAddress && RAMEndAddress >> 24 == 0x80) && (ActorInfoRAMAddress >> 24 == 0x80) && (((ActorNameRAMAddress >> 24 == 0x80) && (ActorNameRAMAddress - ROMHandler.CodeRAMAddress) < rom.CodeData.Length) || (ActorNameRAMAddress == 0)); IsEmpty = (StartAddress == 0 && EndAddress == 0 && RAMStartAddress == 0 && RAMEndAddress == 0 && Unknown1 == 0 && ActorInfoRAMAddress == 0 && ActorNameRAMAddress == 0 && Unknown2 == 0); Name = Filename = "N/A"; if (IsValid == true && IsEmpty == false) { if (ActorNameRAMAddress != 0) { string tmp = string.Empty; ROMHandler.GetTerminatedString(rom.CodeData, (int)(ActorNameRAMAddress - ROMHandler.CodeRAMAddress), out tmp); Name = tmp; } else { Name = string.Format("RAM Start 0x{0:X}", RAMStartAddress); } if (RAMStartAddress != 0 && RAMEndAddress != 0) { DMATableEntry dma = rom.Files.Find(x => x.PStart == StartAddress); if (dma != null) { Filename = dma.Name; byte[] tmp = new byte[dma.VEnd - dma.VStart]; Array.Copy(rom.Data, dma.PStart, tmp, 0, dma.VEnd - dma.VStart); uint infoadr = (ActorInfoRAMAddress - RAMStartAddress); if (infoadr >= tmp.Length) { return; } ActorNumber = Endian.SwapUInt16(BitConverter.ToUInt16(tmp, (int)infoadr)); ActorType = tmp[infoadr + 2]; ObjectNumber = Endian.SwapUInt16(BitConverter.ToUInt16(tmp, (int)infoadr + 8)); } else { Filename = Name; } } } }
private void openROMToolStripMenuItem_Click(object sender, EventArgs e) { /* Get last ROM */ if (Configuration.LastROM != string.Empty) { ofdOpenROM.InitialDirectory = Path.GetDirectoryName(Configuration.LastROM); ofdOpenROM.FileName = Path.GetFileName(Configuration.LastROM); } if (ofdOpenROM.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Program.Status.Message = "Loading; please wait..."; Cursor.Current = Cursors.WaitCursor; individualFileMode = false; displayListsDirty = collisionDirty = waterboxesDirty = true; Configuration.LastROM = ofdOpenROM.FileName; rom = new ROMHandler.ROMHandler(ofdOpenROM.FileName); if (rom.Loaded) { ResetCurrentData(); PopulateMiscControls(); CreateSceneTree(); SetFormTitle(); #if BLAHBLUB //header dumper System.IO.TextWriter tw = System.IO.File.CreateText("D:\\roms\\n64\\headers.txt"); tw.WriteLine("ROM: {0} ({1}, v1.{2}; {3})", ROM.Title, ROM.GameID, ROM.Version, ROM.BuildDateString); foreach (SceneTableEntry ste in ROM.Scenes) { HeaderCommands.Rooms rooms = null; tw.WriteLine(" SCENE: " + ste.Name); foreach (HeaderLoader hl in ste.SceneHeaders) { tw.WriteLine(" HEADER: " + hl.Description); foreach (HeaderCommands.Generic cmd in hl.Commands/*.OrderBy(x => (x.Data >> 56))*/) { if (cmd is HeaderCommands.Rooms) rooms = (cmd as HeaderCommands.Rooms); //if (!((cmd.Data >> 56) == (byte)HeaderLoader.CommandTypeIDs.SubHeaders) && !(cmd is HeaderCommands.Actors) && !(cmd is HeaderCommands.Collision) && // !(cmd is HeaderCommands.MeshHeader) && !(cmd is HeaderCommands.Objects) && !(cmd is HeaderCommands.Rooms) && !(cmd is HeaderCommands.SpecialObjects) && // !(cmd is HeaderCommands.Waypoints)) tw.WriteLine(" COMMAND: " + cmd.ByteString + "; " + cmd.Description); } } if (rooms != null) { foreach (HeaderCommands.Rooms.RoomInfoClass ric in rooms.RoomInformation) { tw.WriteLine(" ROOM: " + ric.Description); foreach (HeaderLoader hl in ric.Headers) { tw.WriteLine(" HEADER: " + hl.Description); foreach (HeaderCommands.Generic cmd in hl.Commands/*.OrderBy(x => (x.Data >> 56))*/) { //if (!((cmd.Data >> 56) == (byte)HeaderLoader.CommandTypeIDs.SubHeaders) && !(cmd is HeaderCommands.Actors) && !(cmd is HeaderCommands.Collision) && // !(cmd is HeaderCommands.MeshHeader) && !(cmd is HeaderCommands.Objects) && !(cmd is HeaderCommands.Rooms) && !(cmd is HeaderCommands.SpecialObjects) && // !(cmd is HeaderCommands.Waypoints)) tw.WriteLine(" COMMAND: " + cmd.ByteString + "; " + cmd.Description); } } } } tw.WriteLine(); } tw.Close(); #endif } else { Program.Status.Message = "Error loading ROM"; } Cursor.Current = DefaultCursor; editDataTablesToolStripMenuItem.Enabled = saveToolStripMenuItem.Enabled = openSceneToolStripMenuItem.Enabled = rOMInformationToolStripMenuItem.Enabled = customGLControl.Enabled = rom.Loaded; } }
public ActorTableEntry(ROMHandler rom, int ofs, bool isrel) { ROM = rom; Offset = ofs; IsOffsetRelative = isrel; StartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs)); EndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 4)); RAMStartAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 8)); RAMEndAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 12)); Unknown1 = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 16)); ActorInfoRAMAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 20)); ActorNameRAMAddress = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 24)); Unknown2 = Endian.SwapUInt32(BitConverter.ToUInt32(IsOffsetRelative ? rom.CodeData : rom.Data, ofs + 28)); IsValid = (ActorInfoRAMAddress >> 24 == 0x80) && (((ActorNameRAMAddress >> 24 == 0x80) && (ActorNameRAMAddress - ROMHandler.CodeRAMAddress) < rom.CodeData.Length) || (ActorNameRAMAddress == 0)); IsIncomplete = (StartAddress == 0 && EndAddress == 0 && RAMStartAddress == 0 && RAMEndAddress == 0); IsComplete = (StartAddress > rom.Code.VStart && StartAddress < rom.Size) && (EndAddress > StartAddress && EndAddress > rom.Code.VStart && EndAddress < rom.Size) && (RAMStartAddress >> 24 == 0x80) && (RAMEndAddress > RAMStartAddress && RAMEndAddress >> 24 == 0x80) && (ActorInfoRAMAddress >> 24 == 0x80) && (((ActorNameRAMAddress >> 24 == 0x80) && (ActorNameRAMAddress - ROMHandler.CodeRAMAddress) < rom.CodeData.Length) || (ActorNameRAMAddress == 0)); IsEmpty = (StartAddress == 0 && EndAddress == 0 && RAMStartAddress == 0 && RAMEndAddress == 0 && Unknown1 == 0 && ActorInfoRAMAddress == 0 && ActorNameRAMAddress == 0 && Unknown2 == 0); Name = Filename = "N/A"; if (IsValid == true && IsEmpty == false) { if (ActorNameRAMAddress != 0) { string tmp = string.Empty; ROMHandler.GetTerminatedString(rom.CodeData, (int)(ActorNameRAMAddress - ROMHandler.CodeRAMAddress), out tmp); Name = tmp; } else Name = string.Format("RAM Start 0x{0:X}", RAMStartAddress); if (RAMStartAddress != 0 && RAMEndAddress != 0) { DMATableEntry dma = rom.Files.Find(x => x.PStart == StartAddress); if (dma != null) { Filename = dma.Name; byte[] tmp = new byte[dma.VEnd - dma.VStart]; Array.Copy(rom.Data, dma.PStart, tmp, 0, dma.VEnd - dma.VStart); uint infoadr = (ActorInfoRAMAddress - RAMStartAddress); if (infoadr >= tmp.Length) return; ActorNumber = Endian.SwapUInt16(BitConverter.ToUInt16(tmp, (int)infoadr)); ActorType = tmp[infoadr + 2]; ObjectNumber = Endian.SwapUInt16(BitConverter.ToUInt16(tmp, (int)infoadr + 8)); } else Filename = Name; } } }
public Rooms(ROMHandler.ROMHandler rom, IHeaderParent parent, string fn) : base(rom, parent, HeaderLoader.CommandTypeIDs.Rooms) { RoomInformation = new List<RoomInfoClass>(); RoomInformation.Add(new RoomInfoClass(rom, parent, fn)); }
public RoomInfoClass(ROMHandler.ROMHandler rom, IHeaderParent parent, string fn) { ROM = rom; Parent = parent; System.IO.FileStream fs = new System.IO.FileStream(fn, System.IO.FileMode.Open); Data = new byte[fs.Length]; fs.Read(Data, 0, (int)fs.Length); fs.Close(); Description = System.IO.Path.GetFileNameWithoutExtension(fn); Load(); }
public void Identify(ROMHandler rom) { FileTypes fnassumed = FileTypes.General; if (rom.FileNameTableAddress != -1) { if (Name.EndsWith("_scene") == true) { fnassumed = FileTypes.Scene; } else if (Name.Contains("_room_") == true) { fnassumed = FileTypes.Room; } else if (Name.StartsWith("ovl_") == true) { fnassumed = FileTypes.Overlay; } else if (Name.StartsWith("object_") == true) { fnassumed = FileTypes.Object; } } /* Invalid file? */ if (!IsValid || VEnd - VStart == 0) { FileType = FileTypes.Invalid; return; } if (!IsCompressed) { byte[] data = new byte[VEnd - VStart]; Buffer.BlockCopy(rom.Data, (int)PStart, data, 0, data.Length); /* Room file? */ if (BitConverter.ToUInt32(data, (int)0) == 0x16 || ((BitConverter.ToUInt32(data, (int)0) == 0x18) && data[4] == 0x03 && BitConverter.ToUInt32(data, (int)8) == 0x16)) { for (int i = 8; i < HeaderScanThreshold; i += 8) { if (BitConverter.ToUInt32(data, i) == 0x14 && (fnassumed == FileTypes.General || fnassumed == FileTypes.Room)) { AssumedSegment = 0x03; FileType = FileTypes.Room; return; } } } /* Scene file? */ if ((BitConverter.ToUInt32(data, (int)0) & 0xFFFF00FF) == 0x15 || ((BitConverter.ToUInt32(data, (int)0) == 0x18) && data[4] == 0x02 && (BitConverter.ToUInt32(data, (int)8) & 0xFFFF00FF) == 0x15)) { for (int i = 8; i < HeaderScanThreshold; i += 8) { if (BitConverter.ToUInt32(data, i) == 0x14 && (fnassumed == FileTypes.General || fnassumed == FileTypes.Scene)) { AssumedSegment = 0x02; FileType = FileTypes.Scene; return; } } } /* Overlay file? */ uint ovlheader = ((uint)data.Length - Endian.SwapUInt32(BitConverter.ToUInt32(data, (data.Length - 4)))); if ((ovlheader + 16) < data.Length) { uint btext = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader)); uint bdata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 4)); uint brodata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 8)); uint bssdata = Endian.SwapUInt32(BitConverter.ToUInt32(data, (int)ovlheader + 12)); if ((btext + bdata + brodata == data.Length || btext + bdata + brodata == ovlheader) && (fnassumed == FileTypes.General || fnassumed == FileTypes.Overlay)) { FileType = FileTypes.Overlay; return; } } /* Object file? */ bool indl, hassync, hasvtx, hasdlend; int[] segcount = new int[16]; indl = hassync = hasvtx = hasdlend = false; for (int i = 0; i < data.Length; i += 8) { if (BitConverter.ToUInt32(data, i) == 0xE7 && BitConverter.ToUInt32(data, i + 4) == 0x0) { hassync = true; indl = true; } else if (indl && data[i] == 0x01 && data[i + 4] <= 0x0F) { hasvtx = true; segcount[data[i + 4]]++; } else if (BitConverter.ToUInt32(data, i) == 0xDF && BitConverter.ToUInt32(data, i + 4) == 0x0) { hasdlend = true; indl = false; } } if (hassync && hasvtx && hasdlend && (fnassumed == FileTypes.General || fnassumed == FileTypes.Object)) { AssumedSegment = (byte)segcount.ToList().IndexOf(segcount.Max()); FileType = FileTypes.Object; return; } /* Empty file? */ if (data.Length < 0x100) { int isempty = data.Count(x => x != 0); if (isempty == 0) { FileType = FileTypes.Empty; return; } } } /* Use assumption */ FileType = fnassumed; }
public Waypoint(ROMHandler.ROMHandler rom, uint adr) { ROM = rom; Address = adr; byte[] segdata = (byte[])ROM.SegmentMapping[(byte)(adr >> 24)]; if (segdata == null) return; X = (double)Endian.SwapInt16(BitConverter.ToInt16(segdata, (int)(adr & 0xFFFFFF))); Y = (double)Endian.SwapInt16(BitConverter.ToInt16(segdata, (int)(adr & 0xFFFFFF) + 2)); Z = (double)Endian.SwapInt16(BitConverter.ToInt16(segdata, (int)(adr & 0xFFFFFF) + 4)); }