Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
 public BinarySegBank(SegmentedBank segBank, RomManager rommgr)
 {
     SegBank = segBank;
     SetRomManager(rommgr);
 }
Example #4
0
        // 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;
        }
Example #5
0
 public BinaryRom(RomManager rommgr, FileAccess romAccess) : base(rommgr.RomFile, FileMode.Open, romAccess)
 {
     SetRomManager(rommgr);
 }
Example #6
0
 public void ToObject3D(Object3D obj, RomManager rommgr, byte?AreaID)
 {
     Conversion.Fast3DParsing.Fast3DParser.Convert(obj, this, rommgr, AreaID);
 }
Example #7
0
 public void FromStream(Geopointer gp, RomManager rommgr, byte?AreaID)
 {
     GeoPointer = gp;
     Script.FromStream(rommgr, gp.SegPointer, AreaID);
 }
Example #8
0
        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();
        }