예제 #1
0
        public static IList <AsmPatch> GetPatches(XmlNode rootNode, string xmlFilename, ASMEncodingUtility asmUtility)
        {
            bool         rootHideInDefault = false;
            XmlAttribute attrHideInDefault = rootNode.Attributes["hideInDefault"];

            if (attrHideInDefault != null)
            {
                rootHideInDefault = (attrHideInDefault.InnerText.ToLower().Trim() == "true");
            }

            bool         rootIsHidden = false;
            XmlAttribute attrIsHidden = rootNode.Attributes["hidden"];

            if (attrIsHidden != null)
            {
                rootIsHidden = (attrIsHidden.InnerText.ToLower().Trim() == "true");
            }

            string shortXmlFilename = xmlFilename.Substring(xmlFilename.LastIndexOf("\\") + 1);

            XmlNodeList     patchNodes = rootNode.SelectNodes("Patch");
            List <AsmPatch> result     = new List <AsmPatch>(patchNodes.Count);

            Context context       = (asmUtility.EncodingMode == ASMEncodingMode.PSP) ? Context.US_PSP : Context.US_PSX;
            Type    sectorType    = ISOHelper.GetSectorType(context);
            Enum    defaultSector = ISOHelper.GetSector(0, context);

            foreach (XmlNode node in patchNodes)
            {
                XmlAttribute ignoreNode = node.Attributes["ignore"];
                if (ignoreNode != null && Boolean.Parse(ignoreNode.InnerText))
                {
                    continue;
                }

                bool hasDefaultSector = false;

                //PsxIso.Sectors defaultSector = (PsxIso.Sectors)0;
                //Enum defaultSector = (Enum)Enum.ToObject(sectorType, 0);
                XmlAttribute attrDefaultFile   = node.Attributes["file"];
                XmlAttribute attrDefaultSector = node.Attributes["sector"];

                if (attrDefaultFile != null)
                {
                    //defaultSector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), attrDefaultFile.InnerText);
                    //defaultSector = (Enum)Enum.Parse(sectorType, attrDefaultFile.InnerText);
                    defaultSector    = ISOHelper.GetSector(attrDefaultFile.InnerText, context);
                    hasDefaultSector = true;
                }
                else if (attrDefaultSector != null)
                {
                    //defaultSector = (PsxIso.Sectors)Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber);
                    //defaultSector = (Enum)Enum.ToObject(sectorType, Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber));
                    defaultSector    = ISOHelper.GetSectorHex(attrDefaultSector.InnerText, context);
                    hasDefaultSector = true;
                }

                StringBuilder sbPatchErrorText = new StringBuilder();

                List <VariableType>     variables      = new List <VariableType>();
                List <PatchedByteArray> includePatches = new List <PatchedByteArray>();

                XmlNodeList includeNodes = node.SelectNodes("Include");
                foreach (XmlNode includeNode in includeNodes)
                {
                    XmlAttribute attrPatch = includeNode.Attributes["patch"];
                    if (attrPatch != null)
                    {
                        string patchName       = attrPatch.InnerText.ToLower().Trim();
                        int    foundPatchCount = 0;

                        foreach (AsmPatch currentAsmPatch in result)
                        {
                            if (currentAsmPatch.Name.ToLower().Trim().Equals(patchName))
                            {
                                foreach (VariableType variable in currentAsmPatch.Variables)
                                {
                                    variables.Add(variable.Copy());
                                }
                                for (int index = 0; index < currentAsmPatch.NonVariableCount; index++)
                                {
                                    includePatches.Add(currentAsmPatch[index].Copy());
                                }
                                foundPatchCount++;
                            }
                        }

                        if (foundPatchCount == 0)
                        {
                            sbPatchErrorText.AppendLine("Error in patch XML: Missing dependent patch \"" + attrPatch.InnerText + "\"!");
                        }
                    }
                }

                foreach (XmlNode varNode in node.SelectNodes("Variable"))
                {
                    XmlAttribute numBytesAttr = varNode.Attributes["bytes"];
                    string       strNumBytes  = (numBytesAttr == null) ? "1" : numBytesAttr.InnerText;
                    byte         numBytes     = (byte)(UInt32.Parse(strNumBytes) & 0xff);

                    string varName = varNode.Attributes["name"].InnerText;

                    XmlAttribute fileAttribute   = varNode.Attributes["file"];
                    XmlAttribute sectorAttribute = varNode.Attributes["sector"];
                    XmlAttribute attrSpecific    = varNode.Attributes["specific"];
                    XmlAttribute attrAlign       = varNode.Attributes["align"];

                    //PsxIso.Sectors varSec = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), varNode.Attributes["file"].InnerText );
                    //UInt32 varOffset = UInt32.Parse( varNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber );
                    //string strOffsetAttr = varNode.Attributes["offset"].InnerText;
                    XmlAttribute offsetAttribute  = varNode.Attributes["offset"];
                    string       strOffsetAttr    = (offsetAttribute != null) ? offsetAttribute.InnerText : "";
                    string[]     strOffsets       = strOffsetAttr.Replace(" ", "").Split(',');
                    bool         ignoreOffsetMode = false;
                    bool         isSpecific       = false;

                    List <SpecificLocation> specifics = FillSpecificAttributeData(attrSpecific, defaultSector);

                    int align = 0;
                    if (attrAlign != null)
                    {
                        Int32.TryParse(sectorAttribute.InnerText, out align);

                        if (align < 0)
                        {
                            align = 0;
                        }
                    }

                    XmlAttribute symbolAttribute = varNode.Attributes["symbol"];
                    bool         isSymbol        = (symbolAttribute != null) && PatcherLib.Utilities.Utilities.ParseBool(symbolAttribute.InnerText);

                    if (isSymbol)
                    {
                        strOffsets = new string[0];
                    }
                    else if (specifics.Count > 0)
                    {
                        isSpecific = true;
                        List <string> newStrOffsets = new List <string>(specifics.Count);
                        foreach (SpecificLocation specific in specifics)
                        {
                            newStrOffsets.Add(specific.OffsetString);
                        }
                        strOffsets = newStrOffsets.ToArray();
                    }
                    else if ((string.IsNullOrEmpty(strOffsetAttr)) && (variables.Count > 0) && (variables[variables.Count - 1].Content.Count > 0))
                    {
                        // No offset defined -- offset is (last patch offset) + (last patch size)
                        int lastIndex = variables[variables.Count - 1].Content.Count - 1;
                        PatchedByteArray lastPatchedByteArray = variables[variables.Count - 1].Content[lastIndex];
                        long             offset    = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length;
                        string           strOffset = offset.ToString("X");
                        strOffsets = new string[1] {
                            strOffset
                        };
                        ignoreOffsetMode = true;

                        // Advance offset to match up with alignment, if necessary
                        if (align > 0)
                        {
                            int offsetAlign = (int)(offset % align);
                            if (offsetAlign > 0)
                            {
                                offset += (align - offsetAlign);
                            }
                        }
                    }

                    //PsxIso.Sectors sector = (PsxIso.Sectors)0;
                    Enum sector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0);
                    if (isSpecific)
                    {
                        sector = specifics[0].Sector;
                    }
                    else if (fileAttribute != null)
                    {
                        //sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText);
                        //sector = (Enum)Enum.Parse(sectorType, fileAttribute.InnerText);
                        sector = ISOHelper.GetSector(fileAttribute.InnerText, context);
                    }
                    else if (sectorAttribute != null)
                    {
                        //sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber);
                        //sector = (Enum)Enum.ToObject(sectorType, Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber));
                        sector = ISOHelper.GetSectorHex(sectorAttribute.InnerText, context);
                    }
                    else if (hasDefaultSector)
                    {
                        sector = defaultSector;
                    }
                    else if ((variables.Count > 0) && (variables[variables.Count - 1].Content.Count > 0))
                    {
                        int lastIndex = variables[variables.Count - 1].Content.Count - 1;
                        //sector = (PsxIso.Sectors)(variables[variables.Count - 1].Content[lastIndex].Sector);
                        //sector = (Enum)Enum.ToObject(sectorType, variables[variables.Count - 1].Content[lastIndex].Sector);
                        sector = variables[variables.Count - 1].Content[lastIndex].SectorEnum;
                    }
                    else if (!isSymbol)
                    {
                        sbPatchErrorText.AppendLine("Error in patch XML: Invalid file/sector!");
                    }

                    XmlAttribute offsetModeAttribute = varNode.Attributes["offsetMode"];
                    bool         isRamOffset         = false;
                    if ((!ignoreOffsetMode) && (offsetModeAttribute != null))
                    {
                        if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram")
                        {
                            isRamOffset = true;
                        }
                    }

                    int ftrOffset = ISOHelper.GetFileToRamOffset(sector, context);

                    XmlAttribute defaultAttr = varNode.Attributes["default"];
                    Byte[]       byteArray   = new Byte[numBytes];
                    UInt32       def         = 0;
                    if (defaultAttr != null)
                    {
                        def = UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber);
                        for (int i = 0; i < numBytes; i++)
                        {
                            byteArray[i] = (Byte)((def >> (i * 8)) & 0xff);
                        }
                    }

                    List <PatchedByteArray> patchedByteArrayList = new List <PatchedByteArray>();
                    int offsetIndex = 0;

                    foreach (string strOffset in strOffsets)
                    {
                        UInt32 offset = UInt32.Parse(strOffset, System.Globalization.NumberStyles.HexNumber);
                        //UInt32 ramOffset = offset;
                        UInt32 fileOffset = offset;

                        if (ftrOffset >= 0)
                        {
                            try
                            {
                                if (isRamOffset)
                                {
                                    fileOffset -= (UInt32)ftrOffset;
                                }
                                //else
                                //    ramOffset += (UInt32)ftrOffset;
                            }
                            catch (Exception) { }
                        }

                        //ramOffset = ramOffset | PsxIso.KSeg0Mask;     // KSEG0

                        patchedByteArrayList.Add(new PatchedByteArray(sector, fileOffset, byteArray));

                        offsetIndex++;
                        if (offsetIndex < strOffsets.Length)
                        {
                            if (isSpecific)
                            {
                                sector    = specifics[offsetIndex].Sector;
                                ftrOffset = ISOHelper.GetFileToRamOffset(sector, context);
                            }
                        }
                    }

                    bool   isReference             = false;
                    string referenceName           = "";
                    string referenceOperatorSymbol = "";
                    uint   referenceOperand        = 0;

                    XmlAttribute attrReference = varNode.Attributes["reference"];
                    XmlAttribute attrOperator  = varNode.Attributes["operator"];
                    XmlAttribute attrOperand   = varNode.Attributes["operand"];

                    if (attrReference != null)
                    {
                        isReference             = true;
                        referenceName           = attrReference.InnerText;
                        referenceOperatorSymbol = (attrOperator != null) ? attrOperator.InnerText : "";
                        if (attrOperand != null)
                        {
                            //UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber);
                            uint.TryParse(attrOperand.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out referenceOperand);
                        }
                    }

                    List <VariableType.VariablePreset> presetValueList = new List <VariableType.VariablePreset>();
                    XmlNodeList presetNodeList = varNode.SelectNodes("Preset");

                    string       presetKey  = null;
                    XmlAttribute attrPreset = varNode.Attributes["preset"];
                    if (attrPreset != null)
                    {
                        presetKey = attrPreset.InnerText;
                        if (!string.IsNullOrEmpty(presetKey))
                        {
                            presetValueList = VariableType.VariablePreset.TypeMap[presetKey];
                        }
                    }
                    else if (presetNodeList != null)
                    {
                        foreach (XmlNode presetNode in presetNodeList)
                        {
                            XmlAttribute attrName   = presetNode.Attributes["name"];
                            XmlAttribute attrValue  = presetNode.Attributes["value"];
                            XmlAttribute attrModify = presetNode.Attributes["modify"];
                            UInt32       value      = 0;

                            byte[] valueBytes = new Byte[numBytes];
                            if (attrValue != null)
                            {
                                UInt32.TryParse(attrValue.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out value);
                                for (int i = 0; i < numBytes; i++)
                                {
                                    valueBytes[i] = (byte)((value >> (i * 8)) & 0xff);
                                }
                            }

                            bool isModifiable = false;
                            if (attrModify != null)
                            {
                                bool.TryParse(attrModify.InnerText, out isModifiable);
                            }

                            presetValueList.Add(new VariableType.VariablePreset(attrName.InnerText, value, valueBytes, isModifiable));
                        }
                    }

                    VariableType vType = new VariableType();
                    vType.NumBytes                 = numBytes;
                    vType.ByteArray                = byteArray;
                    vType.Name                     = varName;
                    vType.Content                  = patchedByteArrayList;
                    vType.IsReference              = isReference;
                    vType.Reference                = new VariableReference();
                    vType.Reference.Name           = referenceName;
                    vType.Reference.OperatorSymbol = referenceOperatorSymbol;
                    vType.Reference.Operand        = referenceOperand;
                    vType.PresetValues             = presetValueList;

                    variables.Add(vType);
                }

                GetPatchResult getPatchResult = GetPatch(node, xmlFilename, asmUtility, variables);

                List <PatchedByteArray> patches = new List <PatchedByteArray>(includePatches.Count + getPatchResult.StaticPatches.Count);
                patches.AddRange(includePatches);
                patches.AddRange(getPatchResult.StaticPatches);

                AsmPatch asmPatch = new AsmPatch(getPatchResult.Name, shortXmlFilename, getPatchResult.Description, patches,
                                                 (getPatchResult.HideInDefault | rootHideInDefault), (getPatchResult.IsHidden | rootIsHidden), variables);

                asmPatch.ErrorText = sbPatchErrorText.ToString() + getPatchResult.ErrorText;
                //asmPatch.Update(asmUtility);

                result.Add(asmPatch);
            }

            patchNodes = rootNode.SelectNodes("ImportFilePatch");
            foreach (XmlNode node in patchNodes)
            {
                KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node);

                string name        = nameDesc.Key;
                string description = nameDesc.Value;

                XmlNodeList fileNodes = node.SelectNodes("ImportFile");
                if (fileNodes.Count != 1)
                {
                    continue;
                }

                XmlNode theRealNode = fileNodes[0];

                //PsxIso.Sectors sector = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), theRealNode.Attributes["file"].InnerText );
                Enum   sector         = (Enum)Enum.Parse(sectorType, theRealNode.Attributes["file"].InnerText);
                UInt32 offset         = UInt32.Parse(theRealNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber);
                UInt32 expectedLength = UInt32.Parse(theRealNode.Attributes["expectedLength"].InnerText, System.Globalization.NumberStyles.HexNumber);

                result.Add(new FileAsmPatch(name, shortXmlFilename, description, new InputFilePatch(sector, offset, expectedLength)));
            }

            return(result.AsReadOnly());
        }
예제 #2
0
 private void UpdateVariable(VariableType variable, UInt32 newValue)
 {
     AsmPatch.UpdateVariable(variable, newValue);
 }
예제 #3
0
        public static IList <AsmPatch> GetPatches(XmlNode rootNode, string xmlFilename, ASMEncodingUtility asmUtility)
        {
            XmlNodeList     patchNodes = rootNode.SelectNodes("Patch");
            List <AsmPatch> result     = new List <AsmPatch>(patchNodes.Count);

            foreach (XmlNode node in patchNodes)
            {
                XmlAttribute ignoreNode = node.Attributes["ignore"];
                if (ignoreNode != null && Boolean.Parse(ignoreNode.InnerText))
                {
                    continue;
                }

                string name;
                string description;
                IList <PatchedByteArray> staticPatches;
                List <bool> isDataSectionList;

                GetPatch(node, xmlFilename, asmUtility, out name, out description, out staticPatches, out isDataSectionList);
                List <VariableType> variables = new List <VariableType>();
                foreach (XmlNode varNode in node.SelectNodes("Variable"))
                {
                    XmlAttribute xmlAttr  = varNode.Attributes["bytes"];
                    string       strBytes = (xmlAttr == null) ? "1" : xmlAttr.InnerText;
                    char         bytes    = (char)(UInt32.Parse(strBytes) & 0xff);

                    string varName = varNode.Attributes["name"].InnerText;

                    XmlAttribute fileAttribute   = varNode.Attributes["file"];
                    XmlAttribute sectorAttribute = varNode.Attributes["sector"];

                    PsxIso.Sectors varSec = (PsxIso.Sectors) 0;
                    if (fileAttribute != null)
                    {
                        varSec = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText);
                    }
                    else if (sectorAttribute != null)
                    {
                        varSec = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber);
                    }
                    else
                    {
                        throw new Exception();
                    }

                    //PsxIso.Sectors varSec = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), varNode.Attributes["file"].InnerText );

                    UInt32       varOffset   = UInt32.Parse(varNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber);
                    XmlAttribute defaultAttr = varNode.Attributes["default"];

                    Byte[] byteArray = new Byte[bytes];
                    UInt32 def       = 0;
                    if (defaultAttr != null)
                    {
                        def = UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber);
                        for (int i = 0; i < bytes; i++)
                        {
                            byteArray[i] = (Byte)((def >> (i * 8)) & 0xff);
                        }
                    }

                    KeyValuePair <string, PatchedByteArray> kvp = new KeyValuePair <string, PatchedByteArray>(varName, new PatchedByteArray(varSec, varOffset, byteArray));
                    VariableType vType = new VariableType();
                    vType.content = kvp;
                    vType.bytes   = bytes;

                    variables.Add(vType);
                }
                result.Add(new AsmPatch(name, description, staticPatches, isDataSectionList, variables));
            }

            patchNodes = rootNode.SelectNodes("ImportFilePatch");
            foreach (XmlNode node in patchNodes)
            {
                string name;
                string description;

                GetPatchNameAndDescription(node, out name, out description);

                XmlNodeList fileNodes = node.SelectNodes("ImportFile");
                if (fileNodes.Count != 1)
                {
                    continue;
                }

                XmlNode theRealNode = fileNodes[0];

                PsxIso.Sectors sector         = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), theRealNode.Attributes["file"].InnerText);
                UInt32         offset         = UInt32.Parse(theRealNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber);
                UInt32         expectedLength = UInt32.Parse(theRealNode.Attributes["expectedLength"].InnerText, System.Globalization.NumberStyles.HexNumber);

                result.Add(new FileAsmPatch(name, description, new InputFilePatch(sector, offset, expectedLength)));
            }

            return(result.AsReadOnly());
        }
예제 #4
0
        private void clb_Patches_SelectedIndexChanged(object sender, EventArgs e)
        {
            AsmPatch p = clb_Patches.SelectedItem as AsmPatch;

            if (p != null)
            {
                string description = "";
                if (!string.IsNullOrEmpty(p.Description))
                {
                    StringBuilder sb    = new StringBuilder();
                    string[]      lines = p.Description.Split('\n');

                    for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
                    {
                        string line    = lines[lineIndex];
                        string newLine = line.Trim().Replace("\r", "");
                        if (((lineIndex != 0) && (lineIndex < (lines.Length - 1))) || (!string.IsNullOrEmpty(newLine)))
                        {
                            sb.AppendLine(newLine);
                        }
                    }
                    description = sb.ToString();
                    description = description.Substring(0, description.LastIndexOf(Environment.NewLine));
                }

                textBox1.Text = description;

                int index = clb_Patches.SelectedIndex;
                txt_Messages.Text = p.ErrorText;

                //if (p.Variables.Count > 0)
                if (p.CountNonReferenceVariables() > 0)
                {
                    ignoreChanges = true;
                    variableComboBox.Items.Clear();

                    bool         foundFirst = false;
                    VariableType firstNonReferenceVariable = p.Variables[0];
                    foreach (VariableType variable in p.Variables)
                    {
                        if (!variable.IsReference)
                        {
                            variableComboBox.Items.Add(variable.Name);
                            if (!foundFirst)
                            {
                                firstNonReferenceVariable = variable;
                                foundFirst = true;
                            }
                        }
                    }
                    variableComboBox.SelectedIndex = 0;

                    byte[] byteArray = firstNonReferenceVariable.ByteArray;
                    variableSpinner.Maximum = (decimal)Math.Pow(256, firstNonReferenceVariable.NumBytes) - 1;
                    variableSpinner.Value   = Utilities.GetUnsignedByteArrayValue_LittleEndian(byteArray);

                    variableSpinner.Visible  = true;
                    ignoreChanges            = false;
                    variableComboBox.Visible = true;

                    HandleVariablePresets(firstNonReferenceVariable);
                }
                else
                {
                    variableSpinner.Visible     = false;
                    ignoreChanges               = true;
                    variableComboBox.Visible    = false;
                    cmb_Variable_Preset.Visible = false;
                }
            }
        }