public ROMHandler(string fn) { #if !DEBUG try #endif { reload: DMATableAddress = FileNameTableAddress = SceneTableAddress = -1; Filename = fn; /* Initialize segment and rendering systems */ SegmentMapping = new Hashtable(); Renderer = new F3DEX2Interpreter(this); /* Read ROM */ BinaryReader br = new BinaryReader(File.Open(fn, FileMode.Open, FileAccess.Read, FileShare.Read)); if (br.BaseStream.Length < MinROMSize) { throw new ROMHandlerException(string.Format("File size is less than {0}MB; ROM appears to be invalid.", MinROMSize / 0x100000)); } Data = new byte[br.BaseStream.Length]; br.Read(Data, 0, (int)br.BaseStream.Length); br.Close(); /* Detect byte order */ DetectByteOrder(); if (DetectedByteOrder != ByteOrder.BigEndian) { if (MessageBox.Show("The ROM file you have selected uses an incompatible byte order, and needs to be converted to Big Endian format to be used." + Environment.NewLine + Environment.NewLine + "Convert the ROM now? (You will be asked for the target filename; the converted ROM will also be reloaded.)", "Byte Order Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { /* Ask for new filename */ string fnnew = GUIHelpers.ShowSaveFileDialog("Nintendo 64 ROMs (*.z64;*.bin)|*.z64;*.bin|All Files (*.*)|*.*"); if (fnnew != string.Empty) { fn = fnnew; /* Perform byte order conversion */ byte[] datanew = new byte[Data.Length]; byte[] conv = null; for (int i = 0, j = 0; i < Data.Length; i += 4, j += 4) { if (DetectedByteOrder == ByteOrder.MiddleEndian) { conv = new byte[4] { Data[i + 1], Data[i], Data[i + 3], Data[i + 2] } } ; else if (DetectedByteOrder == ByteOrder.LittleEndian) { conv = new byte[4] { Data[i + 3], Data[i + 2], Data[i + 1], Data[i] } } ; Buffer.BlockCopy(conv, 0, datanew, j, conv.Length); } /* Save converted ROM, then reload it */ BinaryWriter bw = new BinaryWriter(File.Create(fn)); bw.Write(datanew); bw.Close(); goto reload; } } else { /* Wrong byte order, no conversion performed */ throw new ByteOrderException(string.Format("Incompatible byte order {0} detected; ROM cannot be used.", DetectedByteOrder)); } } else { /* Read header */ ReadROMHeader(); /* Create XML actor definition reader */ XMLActorDefReader = new XMLActorDefinitionReader(Path.Combine("XML", "ActorDefinitions", GameID.Substring(1, 2))); if (XMLActorDefReader.Definitions.Count > 0) { /* Create remaining XML-related objects */ XMLActorNames = new XMLHashTableReader(Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ActorNames.xml"); XMLObjectNames = new XMLHashTableReader(Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ObjectNames.xml"); XMLSongNames = new XMLHashTableReader(Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "SongNames.xml"); XMLSceneNames = new XMLHashTableReader(Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "SceneNames.xml"); XMLRoomNames = new XMLHashTableReader(Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "RoomNames.xml"); XMLStageDescriptions = new XMLHashTableReader(Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "StageDescriptions.xml"); /* Determine if ROM uses z64tables hack */ HasZ64TablesHack = (Version == 15 && Endian.SwapUInt32(BitConverter.ToUInt32(Data, 0x1238)) != 0x0C00084C); /* Find and read build information, DMA table, etc. */ FindBuildInfo(); FindDMATable(); FindFileNameTable(); ReadDMATable(); ReadFileNameTable(); /* Try to identify files */ foreach (DMATableEntry dte in Files) { dte.Identify(this); } /* Find the code file */ FindCodeFile(); /* Find other Zelda-specific stuff */ FindActorTable(); FindObjectTable(); FindSceneTable(); ReadEntranceTable(); /* Some sanity checking & exception handling*/ if (Scenes == null || Scenes.Count == 0) { throw new ROMHandlerException("No valid scenes could be recognized in the ROM."); } /* Done */ Loaded = true; } } } #if !DEBUG catch (Exception ex) { Loaded = false; if (MessageBox.Show(ex.Message + "\n\n" + "Show detailed information?", "Exception", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { MessageBox.Show(ex.ToString(), "Exception Details", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } #endif }
public ROMHandler(string fn) { #if !DEBUG try #endif { reload: DMATableAddress = FileNameTableAddress = SceneTableAddress = -1; Filename = fn; /* Initialize segment and rendering systems */ SegmentMapping = new Hashtable(); Renderer = new F3DEX2Interpreter(this); /* Read ROM */ System.IO.BinaryReader br = new System.IO.BinaryReader(System.IO.File.Open(fn, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)); if (br.BaseStream.Length < MinROMSize) throw new ROMHandlerException(string.Format("File size is less than {0}MB; ROM appears to be invalid.", (MinROMSize / 0x100000))); Data = new byte[br.BaseStream.Length]; br.Read(Data, 0, (int)br.BaseStream.Length); br.Close(); /* Detect byte order */ DetectByteOrder(); if (DetectedByteOrder != ByteOrder.BigEndian) { if (MessageBox.Show("The ROM file you have selected uses an incompatible byte order, and needs to be converted to Big Endian format to be used." + Environment.NewLine + Environment.NewLine + "Convert the ROM now? (You will be asked for the target filename; the converted ROM will also be reloaded.)", "Byte Order Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { /* Ask for new filename */ string fnnew = GUIHelpers.ShowSaveFileDialog("Nintendo 64 ROMs (*.z64;*.bin)|*.z64;*.bin|All Files (*.*)|*.*"); if (fnnew != string.Empty) { fn = fnnew; /* Perform byte order conversion */ byte[] datanew = new byte[Data.Length]; byte[] conv = null; for (int i = 0, j = 0; i < Data.Length; i += 4, j += 4) { if (DetectedByteOrder == ByteOrder.MiddleEndian) conv = new byte[4] { Data[i + 1], Data[i], Data[i + 3], Data[i + 2] }; else if (DetectedByteOrder == ByteOrder.LittleEndian) conv = new byte[4] { Data[i + 3], Data[i + 2], Data[i + 1], Data[i] }; Buffer.BlockCopy(conv, 0, datanew, j, conv.Length); } /* Save converted ROM, then reload it */ System.IO.BinaryWriter bw = new System.IO.BinaryWriter(System.IO.File.Create(fn)); bw.Write(datanew); bw.Close(); goto reload; } } else { /* Wrong byte order, no conversion performed */ throw new ByteOrderException(string.Format("Incompatible byte order {0} detected; ROM cannot be used.", DetectedByteOrder)); } } else { /* Read header */ ReadROMHeader(); /* Create XML actor definition reader */ XMLActorDefReader = new XMLActorDefinitionReader(System.IO.Path.Combine("XML", "ActorDefinitions", GameID.Substring(1, 2))); if (XMLActorDefReader.Definitions.Count > 0) { /* Create remaining XML-related objects */ XMLActorNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ActorNames.xml"); XMLObjectNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ObjectNames.xml"); XMLSongNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "SongNames.xml"); XMLSceneNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "SceneNames.xml"); XMLRoomNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "RoomNames.xml"); XMLStageDescriptions = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "StageDescriptions.xml"); /* Determine if ROM uses z64tables hack */ HasZ64TablesHack = (Version == 15 && Endian.SwapUInt32(BitConverter.ToUInt32(Data, 0x1238)) != 0x0C00084C); /* Find and read build information, DMA table, etc. */ FindBuildInfo(); FindFileNameTable(); ReadDMATable(); ReadFileNameTable(); /* Try to identify files */ foreach (DMATableEntry dte in Files) dte.Identify(this); /* Find the code file */ FindCodeFile(); /* Find other Zelda-specific stuff */ FindActorTable(); FindObjectTable(); FindSceneTable(); ReadEntranceTable(); /* Some sanity checking & exception handling*/ if (Scenes == null || Scenes.Count == 0) throw new ROMHandlerException("No valid scenes could be recognized in the ROM."); /* Done */ Loaded = true; } } } #if !DEBUG catch (Exception ex) { Loaded = false; if (MessageBox.Show(ex.Message + "\n\n" + "Show detailed information?", "Exception", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { MessageBox.Show(ex.ToString(), "Exception Details", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } #endif }