public void Patch(PatchScript script, RomManager rommgr, IWin32Window owner, IReadOnlyDictionary <string, object> @params, string[] additionalAssemblyReferences) { if (script is null) { throw new ArgumentNullException(nameof(script)); } object oromfile = ""; if (@params is null || [email protected]("romfile", out oromfile)) { oromfile = rommgr.RomFile; } string romfile = (string)oromfile; var switchExpr = script.Type; switch (switchExpr) { case ScriptType.TweakScript: { var stream = new FileStream(romfile, FileMode.Open, FileAccess.ReadWrite); var bw = new BinaryWriter(stream); var br = new BinaryReader(stream); var reader = new StringReader(script.Script); while (reader.Peek() > -1) { string line = reader.ReadLine().Trim().ToLower(); int commentStart = line.IndexOf("//"); if (commentStart > -1) { line = line.Substring(0, commentStart); } if (string.IsNullOrEmpty(line.Trim())) { continue; } int nextDP = line.IndexOf(":"); string body = line.Substring(nextDP + 1).Trim(); if (nextDP > -1) { string addr; addr = line.Substring(0, nextDP); stream.Position = Convert.ToInt32(addr, 16); } int nextKlammer = body.IndexOf('['); while (nextKlammer > -1) { int endKl = body.IndexOf(']', nextKlammer + 1); string str = body.Substring(nextKlammer, endKl - nextKlammer + 1); string newVal = ""; switch (true) { case object _ when str.StartsWith("["): var parts = str.Substring(1, str.Length - 2).Split(','); // body.Substring(1, body.Length - 1).Split(",") if (parts.Count() > 0) { var switchExpr1 = parts[0].Trim(); switch (switchExpr1) { case "copy": { if (parts.Count() > 1) { int startAddr = Convert.ToInt32(parts[1].Trim(), 16); int endAddr = parts.Length > 2 ? Convert.ToInt32(parts[2].Trim(), 16) : startAddr + 1; int length = endAddr - startAddr; int lastPos = Conversions.ToInteger(stream.Position); body = ""; stream.Position = startAddr; for (int i = 1, loopTo = length; i <= loopTo; i++) { body += " " + br.ReadByte().ToString("X2"); } stream.Position = lastPos; } break; } case "fill": { if (parts.Count() > 2) { byte value = Convert.ToByte(parts[1].Trim(), 16); string valueString = value.ToString("X2"); int length = Convert.ToInt32(parts[2].Trim(), 16); body = ""; for (int i = 1, loopTo1 = length; i <= loopTo1; i++) { body += " " + valueString; } } break; } default: { var inputType = InputValueType.Byte; var switchExpr2 = parts[0].Trim(); switch (switchExpr2) { case "8": inputType = InputValueType.Byte; break; case "16": inputType = InputValueType.UInt16; break; case "32": inputType = InputValueType.UInt32; break; case "half": inputType = InputValueType.Single; break; case "string": inputType = InputValueType.String; break; case "sequence": inputType = InputValueType.Sequence; break; case "level": inputType = InputValueType.LevelID; break; } var titel = parts.ElementAtOrDefault(1)?.Trim()?.Trim('"', '[', ']'); var processingEventArgs = new PatchScriptManagerProcessingInputValueEventArgs(inputType, titel, rommgr, owner); ProcessingInputValue?.Invoke(this, processingEventArgs); if (processingEventArgs.SettedValue) { if (inputType == InputValueType.String) { byte[] barr = System.Text.Encoding.ASCII.GetBytes((string)processingEventArgs.ReturnValue); foreach (byte b in barr) { newVal += b.ToString("X2"); } } else { string barr = string.Empty; switch (inputType) { case InputValueType.Byte: case InputValueType.Sequence: barr = Conversions.ToByte(processingEventArgs.ReturnValue).ToString("X2"); break; case InputValueType.UInt16: case InputValueType.LevelID: barr = Conversions.ToUShort(processingEventArgs.ReturnValue).ToString("X4"); break; case InputValueType.Single: barr = Data.System.SwapInts.SwapSingle(Convert.ToSingle(processingEventArgs.ReturnValue)).ToString("X4"); break; case InputValueType.UInt32: barr = Conversions.ToUInteger(processingEventArgs.ReturnValue).ToString("X8"); break; } for (int i = 0, loopTo2 = barr.Length - 1; i <= loopTo2; i += 2) { newVal += " " + barr.Substring(i, 2); } } } body = body.Replace(str, newVal); break; } } break; } break; default: continue; } nextKlammer = body.IndexOf('[', nextKlammer + 1); } if (!string.IsNullOrEmpty(body)) { foreach (string str in body.Split(' ')) { if (!string.IsNullOrWhiteSpace(str)) { byte value = Convert.ToByte(str, 16); bw.Write(value); } } } } reader.Close(); stream.Close(); break; } case ScriptType.VisualBasic: case ScriptType.CSharp: { var assembly = GetAssembly(script, additionalAssemblyReferences); if (assembly is object) { ExecuteScript(assembly, @params); } break; } case ScriptType.Armips: { RunArmips(script.Script, romfile, Path.GetDirectoryName(Conversions.ToString(@params["profilepath"]))); break; } } General.PatchClass.UpdateChecksum(romfile); }
/// <summary>Parse a Displaylist to an Object3D.</summary> /// <param name="obj">The Object3D where the model should be parsed to.</param> /// <param name="dl">The Displaylist which should be parsed.</param> /// <param name="rommgr">The RomManager Instance to use.</param> /// <param name="AreaID">The Area ID if avaiable.</param> public static void Convert(Object3D obj, DisplayList dl, RomManager rommgr, byte?AreaID) { if (dl.Script.Count == 0 || dl.GeoPointer is null) { return; } int cmdIndex = 0; DisplayListCommand cmd = null; byte[] cmdarr = null; var knownTextures = new Dictionary <int, Material>(); var knownColors = new Dictionary <int, Color>(); var knownVertices = new Dictionary <int, Vertex>(); var knownNormals = new Dictionary <int, Normal>(); var knownUVs = new Dictionary <int, UV>(); var knownVertexColors = new Dictionary <int, VertexColor>(); var knownShading = new Dictionary <int, Color>(); var dicVertexColorShading = new Dictionary <Color, VertexColor>(); var pointbuffer = new Pilz.S3DFileParser.Point[16]; var scaledVertices = new List <UV>(); Material curTexture = null; Size curTexSize = default; int curTexSegAddr = -1; int curTexWrapT = 10497; int curTexWrapS = 10497; var curTexScale = new System.Numerics.Vector2(1.0F, 1.0F); var curTexPalette = Array.Empty <byte>(); int curTexPaletteSegAddr = -1; N64Graphics.N64Codec?curTexFormat = default; uint curGeometryMode = 0x22205; Mesh curMesh = null; Color?curColor = default; TextureLoadedInfos curTexLoadedInfos = null; bool useUVOffsetFix = true; int dlDepth = 0; // Load Main Segmented Bank var curSeg = GetSegBank(rommgr, dl.GeoPointer.SegPointer, AreaID); if (curSeg is null) { return; } curMesh = new Mesh(); while (cmdIndex < dl.Script.Count /*&& dl.Script[cmdIndex].CommandType != CommandTypes.EndDisplaylist*/) { cmd = dl.Script[cmdIndex]; cmdarr = cmd.ToArray(); var switchExpr = cmd.CommandType; // &H20000 switch (switchExpr) { case CommandTypes.DisplayList: if (cmdarr[1] != 1) { dlDepth += 1; } break; case CommandTypes.EndDisplaylist: if (dlDepth > 0) { dlDepth -= 1; } break; case CommandTypes.ClearGeometryMode: { curGeometryMode = curGeometryMode & ~F3D_CLEARGEOMETRYMODE.GetGeometryMode(cmd); break; } case CommandTypes.SetGeometryMode: { curGeometryMode = curGeometryMode | F3D_CLEARGEOMETRYMODE.GetGeometryMode(cmd); break; } case CommandTypes.Movemem: { int segAddr = F3D_MOVEMEM.GetSegmentedOffset(cmd); byte smode = F3D_MOVEMEM.GetLightValueMode(cmd); if (smode == 0x86) // Load Shading Light (Diffuse) Color { if (knownShading.ContainsKey(segAddr)) { curColor = knownShading[segAddr]; } else { var colordata = new byte[4]; var seg = rommgr.GetSegBank(Conversions.ToByte(segAddr >> 24), AreaID); // Read Color Data seg.Data.Position = segAddr & 0xFFFFFF; seg.Data.Read(colordata, 0, colordata.Length); curColor = Color.FromArgb(0xFF, colordata[0], colordata[1], colordata[2]); if (!dicVertexColorShading.ContainsKey((Color)curColor)) { // Create new Vertex Color var vc = new VertexColor() { R = colordata[0] / 256.0F, G = colordata[1] / 256.0F, B = colordata[2] / 256.0F, A = 1.0F }; dicVertexColorShading.Add((Color)curColor, vc); } // Set as Vertex Color knownShading.Add(segAddr, (Color)curColor); } } break; } case CommandTypes.Loadtlut: { byte paletteTileDescritpr = cmdarr[4]; ushort numColorsToLoadInPalette; curTexPaletteSegAddr = curTexSegAddr; cmd.Position = 5; numColorsToLoadInPalette = (ushort)(cmd.ReadUInt16() >> 6); var seg = rommgr.GetSegBank(Conversions.ToByte(curTexPaletteSegAddr >> 24), AreaID); curTexPalette = new byte[numColorsToLoadInPalette * 2 + 1 + 1]; int offset = curTexPaletteSegAddr & 0xFFFFFF; for (int i = 1, loopTo = numColorsToLoadInPalette + 1; i <= loopTo; i++) { int ii = i * 2 - 2; seg.Data.Position = offset + ii; curTexPalette[ii] = Conversions.ToByte(seg.Data.ReadByte()); curTexPalette[ii + 1] = Conversions.ToByte(seg.Data.ReadByte()); } break; } case CommandTypes.Triangle1: { var f = new Face(); if (curTexFormat is object) { ProcessTexture(obj, rommgr, AreaID, dl, (N64Graphics.N64Codec)curTexFormat, knownTextures, ref curTexture, curTexSegAddr, curTexSize, curTexWrapT, curTexWrapS, curTexScale, curTexPalette, curTexPaletteSegAddr, curColor, ref curTexLoadedInfos); f.Material = curTexture; } for (int i = 1; i <= 3; i++) { byte pindex = F3D_TRI1.GetVertice(cmd, Conversions.ToByte(i)); if (pindex >= pointbuffer.Length) { return; } var p = pointbuffer[pindex]; if (p is object) { f.Points.Add(p); } } // Shading (as Vertex Color) if (curTexture?.Color is object && (curGeometryMode & (long)0x20000) != 0) { var vc = dicVertexColorShading[(Color)curTexture.Color]; foreach (Pilz.S3DFileParser.Point p in f.Points) { if (p.VertexColor is null) { if (dicVertexColorShading.ContainsKey((Color)curTexture.Color)) { p.VertexColor = vc; if (!curMesh.VertexColors.Contains(vc)) { curMesh.VertexColors.Add(vc); } } } } } curMesh.Faces.Add(f); break; } case CommandTypes.Vertex: { byte num = F3D_VTX.GetNumberOfVertices(cmd); byte startindex = F3D_VTX.GetStartIndexInVertexBuffer(cmd); short datalength = F3D_VTX.GetLengthOfVertexData(cmd); int segAddr = F3D_VTX.GetSegmentedAddress(cmd); if (num > 0) { for (int i = 0, loopTo1 = num; i <= loopTo1; i++) { var p = new Pilz.S3DFileParser.Point(); int curSegAddr = segAddr + i * 0x10; var cs = GetSegBank(rommgr, curSegAddr, AreaID); if (cs is null) { continue; } // Vertex if (knownVertices.ContainsKey(curSegAddr)) { p.Vertex = knownVertices[curSegAddr]; } else { var vert = GetVertexFromStream(cs.Data, cs.BankOffsetFromSegAddr(curSegAddr), dl.GeoPointer.ModelOffset, dl.GeoPointer.ModelScale); p.Vertex = vert; curMesh.Vertices.Add(vert); knownVertices.Add(curSegAddr, vert); } // UV if (knownUVs.ContainsKey(curSegAddr)) { p.UV = knownUVs[curSegAddr]; } else { var uv = GetUVFromStream(cs.Data, cs.BankOffsetFromSegAddr(curSegAddr), curTexScale, curTexSize, useUVOffsetFix); p.UV = uv; curMesh.UVs.Add(uv); knownUVs.Add(curSegAddr, uv); } if ((curGeometryMode & (long)0x20000) == 0) { // Vertex Color if (knownVertexColors.ContainsKey(curSegAddr)) { p.VertexColor = knownVertexColors[curSegAddr]; } else { var vc = GetVertexColorFromStream(cs.Data, cs.BankOffsetFromSegAddr(curSegAddr)); p.VertexColor = vc; curMesh.VertexColors.Add(vc); knownVertexColors.Add(curSegAddr, vc); } } // Normal else if (knownNormals.ContainsKey(curSegAddr)) { p.Normal = knownNormals[curSegAddr]; } else { var n = GetNormalFromStream(cs.Data, cs.BankOffsetFromSegAddr(curSegAddr)); p.Normal = n; curMesh.Normals.Add(n); knownNormals.Add(curSegAddr, n); } pointbuffer[startindex + i] = p; } } break; } case CommandTypes.SetImage: { int newAddr = F3D_SETIMG.GetSegmentedAddress(cmd); if ((uint)newAddr != 0xFFFFFFFF) { curTexSegAddr = newAddr; } break; } case CommandTypes.SetTileSize: { curTexSize = F3D_SETTILESIZE.GetSize(cmd); break; } case CommandTypes.SetTile: { cmd.Position = 4; int checkVal = cmd.ReadInt32(); cmd.Position = 0; if (checkVal != 0x7000000) { if (cmdarr[4] == 0) { curTexFormat = F3D_SETTILE.GetTextureFormat(cmd); } curTexWrapT = F3D_SETTILE.GetWrapT(cmd); curTexWrapS = F3D_SETTILE.GetWrapS(cmd); } break; } case CommandTypes.Texture: { if ((curGeometryMode & (long)0x40000) == 0x40000) { curTexSize = F3D_TEXTURE.GetTextureSize(cmd); } else { curTexScale = F3D_TEXTURE.GetTextureScaling(cmd); } break; } case CommandTypes.SetOtherMode_H: { uint bits = F3D_SETOTHERMODE_H.GetModeBits(cmd); bool nearestNeighbor = (bits & (long)0x2000) == 0; useUVOffsetFix = !nearestNeighbor; break; } } cmdIndex += 1; } //if (curMesh.Faces.Any()) obj.Meshes.Add(curMesh); }
public BinarySegBank(SegmentedBank segBank, RomManager rommgr) { SegBank = segBank; SetRomManager(rommgr); }
// M e t h o d s public void SetSegmentedBanks(RomManager rommgr) { var bank0xE = rommgr.SetSegBank(0xE, Conversions.ToInteger(Bank0x0EOffset), (int)(Bank0x0EOffset + Bank0xELength), AreaID); bank0xE.Data = AreaModel.Fast3DBuffer; }
public BinaryRom(RomManager rommgr, FileAccess romAccess) : base(rommgr.RomFile, FileMode.Open, romAccess) { SetRomManager(rommgr); }
public void ToObject3D(Object3D obj, RomManager rommgr, byte?AreaID) { Conversion.Fast3DParsing.Fast3DParser.Convert(obj, this, rommgr, AreaID); }
public void FromStream(Geopointer gp, RomManager rommgr, byte?AreaID) { GeoPointer = gp; Script.FromStream(rommgr, gp.SegPointer, AreaID); }
public InputDialog(InputValueType valType, RomManager rommgr, object defaultValue = null) { InitializeComponent(); ValueType = valType; this.rommgr = rommgr; string infoText = string.Empty; switch (valType) { case InputValueType.Byte: infoText = "Input a 8 Bit value (Byte)"; break; case InputValueType.UInt16: infoText = "Input a 16 Bit value (2 Bytes)"; break; case InputValueType.UInt32: infoText = "Input a 32 Bit value (4 Bytes)"; break; case InputValueType.Single: infoText = "Input a float value"; break; case InputValueType.String: infoText = "Input a string"; break; case InputValueType.Sequence: infoText = "Input a Sequence ID"; break; case InputValueType.LevelID: infoText = "Input a Level ID"; break; } switch (valType) { case InputValueType.Byte: case InputValueType.UInt16: case InputValueType.UInt32: { ComboBoxEx1.Text = defaultValue is null ? "0" : TextValueConverter.TextFromValue(Conversions.ToLong(defaultValue)); break; } case InputValueType.Single: { ComboBoxEx1.Text = $"0{CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator}00"; break; } case InputValueType.String: { ComboBoxEx1.Text = Conversions.ToString(defaultValue is null ? "Text" : defaultValue); break; } case InputValueType.Sequence: { if (rommgr is object) { byte id = 0; foreach (MusicSequence ms in rommgr.MusicList) { ComboBoxEx1.Items.Add($"{id.ToString("X2")} - {ms.Name}"); id += 1; } ComboBoxEx1.DropDownStyle = ComboBoxStyle.DropDownList; ComboBoxEx1.SelectedIndex = 0; } break; } case InputValueType.LevelID: { if (rommgr is object) { foreach (SM64Lib.Levels.LevelInfoDataTabelList.Level lvi in rommgr.LevelInfoData) { ComboBoxEx1.Items.Add($"{lvi.ID.ToString("X2")} - {lvi.Name}"); } ComboBoxEx1.DropDownStyle = ComboBoxStyle.DropDownList; ComboBoxEx1.SelectedIndex = 0; } break; } } if (infoText != null) { LabelX1.Text = infoText; } base.UpdateAmbientColors(); }