Example #1
0
        void Btn_EncodeClick(object sender, EventArgs e)
        {
            txt_Hex.Text      = "";
            txt_Messages.Text = "";

            ASMEncoderResult encodeResult = _asmUtility.EncodeASM(txt_ASM.Text, txt_StartPC.Text, GetSpacePadding(), chk_IncludeAddress.Checked, chk_littleEndian.Checked);

            txt_Hex.Text = encodeResult.EncodedASMText;
            txt_ASM.Text = encodeResult.ModifiedText;

            txt_Messages.ForeColor = Color.Red;
            txt_Messages.Text      = encodeResult.ErrorText;

            if (string.IsNullOrEmpty(encodeResult.ErrorText))
            {
                uint           pc          = ASMEncodingUtility.ProcessStartPC(txt_ASM.Text, txt_StartPC.Text);
                ASMCheckResult checkResult = _asmUtility.CheckASMFromHex(encodeResult.EncodedASMText, pc, chk_littleEndian.Checked, chk_NameRegs.Checked);
                txt_Messages.Text = checkResult.ErrorText;
            }
        }
Example #2
0
        private static GetPatchResult GetPatch(XmlNode node, string xmlFileName, ASMEncodingUtility asmUtility, List <VariableType> variables)
        {
            KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node);

            bool         hideInDefault     = false;
            XmlAttribute attrHideInDefault = node.Attributes["hideInDefault"];

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

            bool         isHidden     = false;
            XmlAttribute attrIsHidden = node.Attributes["hidden"];

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

            bool hasDefaultSector = false;
            //PsxIso.Sectors defaultSector = (PsxIso.Sectors)0;
            Context context    = (asmUtility.EncodingMode == ASMEncodingMode.PSP) ? Context.US_PSP : Context.US_PSX;
            Type    sectorType = ISOHelper.GetSectorType(context);

            Enum         defaultSector     = ISOHelper.GetSector(0, context); // (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    = ISOHelper.GetSectorHex(attrDefaultSector.InnerText, context);
                hasDefaultSector = true;
            }

            XmlNodeList             currentLocs      = node.SelectNodes("Location");
            List <PatchedByteArray> patches          = new List <PatchedByteArray>(currentLocs.Count);
            StringBuilder           sbOuterErrorText = new StringBuilder();

            Dictionary <PatchedByteArray, string> replaceLabelsContentMap = new Dictionary <PatchedByteArray, string>();

            foreach (XmlNode location in currentLocs)
            {
                //UInt32 offset = UInt32.Parse( location.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber );
                XmlAttribute offsetAttribute        = location.Attributes["offset"];
                XmlAttribute fileAttribute          = location.Attributes["file"];
                XmlAttribute sectorAttribute        = location.Attributes["sector"];
                XmlAttribute modeAttribute          = location.Attributes["mode"];
                XmlAttribute offsetModeAttribute    = location.Attributes["offsetMode"];
                XmlAttribute inputFileAttribute     = location.Attributes["inputFile"];
                XmlAttribute replaceLabelsAttribute = location.Attributes["replaceLabels"];
                XmlAttribute attrLabel    = location.Attributes["label"];
                XmlAttribute attrSpecific = location.Attributes["specific"];
                XmlAttribute attrMovable  = location.Attributes["movable"];
                XmlAttribute attrAlign    = location.Attributes["align"];
                XmlAttribute attrStatic   = location.Attributes["static"];

                string   strOffsetAttr      = (offsetAttribute != null) ? offsetAttribute.InnerText : "";
                string[] strOffsets         = strOffsetAttr.Replace(" ", "").Split(',');
                bool     ignoreOffsetMode   = false;
                bool     isSpecific         = false;
                bool     isSequentialOffset = false;

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

                bool isAsmMode    = false;
                bool markedAsData = false;
                if (modeAttribute != null)
                {
                    string modeAttributeText = modeAttribute.InnerText.ToLower().Trim();
                    if (modeAttributeText == "asm")
                    {
                        isAsmMode = true;
                    }
                    else if (modeAttributeText == "data")
                    {
                        markedAsData = true;
                    }
                }

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

                    if (align < 0)
                    {
                        align = 0;
                    }
                }
                else if (isAsmMode)
                {
                    align = 4;
                }

                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)) && (patches.Count > 0))
                {
                    // No offset defined -- offset is (last patch offset) + (last patch size)
                    PatchedByteArray lastPatchedByteArray = patches[patches.Count - 1];
                    long             offset = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length;
                    ignoreOffsetMode   = true;
                    isSequentialOffset = true;

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

                    string strOffset = offset.ToString("X");
                    strOffsets = new string[1] {
                        strOffset
                    };
                }

                //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 (patches.Count > 0)
                {
                    //sector = (PsxIso.Sectors)(patches[patches.Count - 1].Sector);
                    //sector = (Enum)Enum.ToObject(sectorType, patches[patches.Count - 1].Sector);
                    sector = patches[patches.Count - 1].SectorEnum;
                }
                else
                {
                    sbOuterErrorText.AppendLine("Error in patch XML: Invalid file/sector!");
                }

                bool isRamOffset = false;
                if ((!ignoreOffsetMode) && (offsetModeAttribute != null))
                {
                    if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram")
                    {
                        isRamOffset = true;
                    }
                }

                string content = location.InnerText;
                if (inputFileAttribute != null)
                {
                    try
                    {
                        string   strMode  = Enum.GetName(typeof(ASMEncodingMode), asmUtility.EncodingMode);
                        string   readPath = Path.Combine("Include", inputFileAttribute.InnerText);
                        FileInfo fileInfo = new FileInfo(xmlFileName);
                        readPath = Path.Combine(fileInfo.DirectoryName, readPath);
                        using (StreamReader streamReader = new StreamReader(readPath, Encoding.UTF8))
                        {
                            content = streamReader.ReadToEnd();
                        }
                    }
                    catch (Exception)
                    {
                        string readPath = inputFileAttribute.InnerText;
                        using (StreamReader streamReader = new StreamReader(readPath, Encoding.UTF8))
                        {
                            content = streamReader.ReadToEnd();
                        }
                    }
                }

                bool replaceLabels = false;
                if (replaceLabelsAttribute != null)
                {
                    if (replaceLabelsAttribute.InnerText.ToLower().Trim() == "true")
                    {
                        replaceLabels = true;
                    }
                }
                if (replaceLabels)
                {
                    StringBuilder sbLabels = new StringBuilder();
                    foreach (PatchedByteArray currentPatchedByteArray in patches)
                    {
                        if (!string.IsNullOrEmpty(currentPatchedByteArray.Label))
                        {
                            sbLabels.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine));
                        }
                    }
                    asmUtility.EncodeASM(sbLabels.ToString(), 0);
                    content = asmUtility.ReplaceLabelsInHex(content, true, true);
                }

                string label = "";
                if (attrLabel != null)
                {
                    label = attrLabel.InnerText.Replace(" ", "");
                }

                bool isMoveSimple = isAsmMode;
                if (attrMovable != null)
                {
                    bool.TryParse(attrMovable.InnerText, out isMoveSimple);
                }

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

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

                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) { }
                    }

                    if (context == Context.US_PSX)
                    {
                        ramOffset = ramOffset | PsxIso.KSeg0Mask;
                    }

                    byte[] bytes;
                    string errorText = "";
                    if (isAsmMode)
                    {
                        string encodeContent = content;

                        StringBuilder sbPrefix = new StringBuilder();
                        foreach (PatchedByteArray currentPatchedByteArray in patches)
                        {
                            if (!string.IsNullOrEmpty(currentPatchedByteArray.Label))
                            {
                                sbPrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine));
                            }
                        }
                        foreach (VariableType variable in variables)
                        {
                            sbPrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.Name).Replace(",", ""),
                                                          PatcherLib.Utilities.Utilities.GetUnsignedByteArrayValue_LittleEndian(variable.ByteArray), Environment.NewLine));
                        }

                        encodeContent = sbPrefix.ToString() + content;

                        ASMEncoderResult result = asmUtility.EncodeASM(encodeContent, ramOffset, true);
                        bytes     = result.EncodedBytes;
                        errorText = result.ErrorText;
                    }
                    else
                    {
                        AsmPatch.GetBytesResult result = AsmPatch.GetBytes(content, ramOffset, variables);
                        bytes     = result.Bytes;
                        errorText = result.ErrorMessage;
                    }

                    /*
                     * bool isCheckedAsm = false;
                     * if (!markedAsData)
                     * {
                     *  ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(bytes, ramOffset, true, false, new HashSet<ASMCheckCondition>() {
                     *      ASMCheckCondition.LoadDelay,
                     *      ASMCheckCondition.UnalignedOffset,
                     *      ASMCheckCondition.MultCountdown,
                     *      ASMCheckCondition.StackPointerOffset4,
                     *      ASMCheckCondition.BranchInBranchDelaySlot
                     *  });
                     *
                     *  if (checkResult.IsASM)
                     *  {
                     *      isCheckedAsm = true;
                     *      if (!string.IsNullOrEmpty(checkResult.ErrorText))
                     *      {
                     *          errorText += checkResult.ErrorText;
                     *      }
                     *  }
                     * }
                     */

                    //if (!string.IsNullOrEmpty(errorText))
                    //    sbOuterErrorText.Append(errorText);

                    PatchedByteArray patchedByteArray = new PatchedByteArray(sector, fileOffset, bytes);
                    patchedByteArray.IsAsm              = isAsmMode;
                    patchedByteArray.MarkedAsData       = markedAsData;
                    patchedByteArray.IsCheckedAsm       = false; // isCheckedAsm;
                    patchedByteArray.IsSequentialOffset = isSequentialOffset;
                    patchedByteArray.IsMoveSimple       = isMoveSimple;
                    //patchedByteArray.AsmText = isAsmMode ? content : "";
                    patchedByteArray.Text      = content;
                    patchedByteArray.RamOffset = ramOffset;
                    patchedByteArray.ErrorText = errorText;
                    patchedByteArray.Label     = label;
                    patchedByteArray.IsStatic  = isStatic;

                    if (replaceLabels)
                    {
                        replaceLabelsContentMap.Add(patchedByteArray, content);
                    }

                    patches.Add(patchedByteArray);

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

            StringBuilder sbEncodePrefix = new StringBuilder();

            foreach (PatchedByteArray currentPatchedByteArray in patches)
            {
                if (!string.IsNullOrEmpty(currentPatchedByteArray.Label))
                {
                    sbEncodePrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine));
                }
            }
            foreach (VariableType variable in variables)
            {
                sbEncodePrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.Name).Replace(",", ""),
                                                    PatcherLib.Utilities.Utilities.GetUnsignedByteArrayValue_LittleEndian(variable.ByteArray), Environment.NewLine));
            }
            string strEncodePrefix = sbEncodePrefix.ToString();

            asmUtility.EncodeASM(strEncodePrefix, 0);

            foreach (PatchedByteArray patchedByteArray in patches)
            {
                string errorText = string.Empty;

                string replaceLabelsContent;
                if (replaceLabelsContentMap.TryGetValue(patchedByteArray, out replaceLabelsContent))
                {
                    if (!string.IsNullOrEmpty(replaceLabelsContent))
                    {
                        AsmPatch.GetBytesResult result = AsmPatch.GetBytes(asmUtility.ReplaceLabelsInHex(replaceLabelsContent, true, false), (uint)patchedByteArray.RamOffset, variables);
                        patchedByteArray.SetBytes(result.Bytes);
                        errorText += result.ErrorMessage;
                    }
                }

                if (patchedByteArray.IsAsm)
                {
                    string           encodeContent = strEncodePrefix + patchedByteArray.Text;
                    ASMEncoderResult result        = asmUtility.EncodeASM(encodeContent, (uint)patchedByteArray.RamOffset);
                    patchedByteArray.SetBytes(result.EncodedBytes);
                    errorText += result.ErrorText;
                }

                if (!patchedByteArray.MarkedAsData)
                {
                    HashSet <ASMCheckCondition> checkConditions = new HashSet <ASMCheckCondition>()
                    {
                        ASMCheckCondition.LoadDelay,
                        ASMCheckCondition.UnalignedOffset,
                        ASMCheckCondition.MultCountdown,
                        ASMCheckCondition.StackPointerOffset4,
                        ASMCheckCondition.BranchInBranchDelaySlot
                    };

                    if (asmUtility.EncodingMode == ASMEncodingMode.PSP)
                    {
                        checkConditions.Remove(ASMCheckCondition.LoadDelay);
                    }

                    ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(patchedByteArray.GetBytes(), (uint)patchedByteArray.RamOffset, true, false, checkConditions);

                    if (checkResult.IsASM)
                    {
                        patchedByteArray.IsCheckedAsm = true;
                        if (!string.IsNullOrEmpty(checkResult.ErrorText))
                        {
                            errorText += checkResult.ErrorText;
                        }
                    }
                }

                if (!string.IsNullOrEmpty(errorText))
                {
                    sbOuterErrorText.Append(errorText);
                }
            }

            currentLocs = node.SelectNodes("STRLocation");
            foreach (XmlNode location in currentLocs)
            {
                XmlAttribute fileAttribute   = location.Attributes["file"];
                XmlAttribute sectorAttribute = location.Attributes["sector"];

                //PsxIso.Sectors sector = (PsxIso.Sectors)0;
                Enum sector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0);

                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
                {
                    throw new Exception();
                }

                string filename = location.Attributes["input"].InnerText;
                filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(xmlFileName), filename);

                patches.Add(new STRPatchedByteArray(sector, filename));
            }

            return(new GetPatchResult(nameDesc.Key, nameDesc.Value, patches.AsReadOnly(), hideInDefault, isHidden, sbOuterErrorText.ToString()));
        }
        private static GetPatchResult GetPatch(XmlNode node, string xmlFileName, ASMEncodingUtility asmUtility, List <VariableType> variables)
        {
            KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node);

            bool         hideInDefault     = false;
            XmlAttribute attrHideInDefault = node.Attributes["hideInDefault"];

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

            bool hasDefaultSector = false;

            PsxIso.Sectors defaultSector     = (PsxIso.Sectors) 0;
            XmlAttribute   attrDefaultFile   = node.Attributes["file"];
            XmlAttribute   attrDefaultSector = node.Attributes["sector"];

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

            XmlNodeList             currentLocs      = node.SelectNodes("Location");
            List <PatchedByteArray> patches          = new List <PatchedByteArray>(currentLocs.Count);
            StringBuilder           sbOuterErrorText = new StringBuilder();

            foreach (XmlNode location in currentLocs)
            {
                //UInt32 offset = UInt32.Parse( location.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber );
                XmlAttribute offsetAttribute        = location.Attributes["offset"];
                XmlAttribute fileAttribute          = location.Attributes["file"];
                XmlAttribute sectorAttribute        = location.Attributes["sector"];
                XmlAttribute modeAttribute          = location.Attributes["mode"];
                XmlAttribute offsetModeAttribute    = location.Attributes["offsetMode"];
                XmlAttribute inputFileAttribute     = location.Attributes["inputFile"];
                XmlAttribute replaceLabelsAttribute = location.Attributes["replaceLabels"];
                XmlAttribute attrLabel    = location.Attributes["label"];
                XmlAttribute attrSpecific = location.Attributes["specific"];
                XmlAttribute attrMovable  = location.Attributes["movable"];

                string   strOffsetAttr      = (offsetAttribute != null) ? offsetAttribute.InnerText : "";
                string[] strOffsets         = strOffsetAttr.Replace(" ", "").Split(',');
                bool     ignoreOffsetMode   = false;
                bool     isSpecific         = false;
                bool     isSequentialOffset = false;

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

                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)) && (patches.Count > 0))
                {
                    // No offset defined -- offset is (last patch offset) + (last patch size)
                    PatchedByteArray lastPatchedByteArray = patches[patches.Count - 1];
                    long             offset    = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length;
                    string           strOffset = offset.ToString("X");
                    strOffsets = new string[1] {
                        strOffset
                    };
                    ignoreOffsetMode   = true;
                    isSequentialOffset = true;
                }

                PsxIso.Sectors sector = (PsxIso.Sectors) 0;
                if (isSpecific)
                {
                    sector = specifics[0].Sector;
                }
                else if (fileAttribute != null)
                {
                    sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText);
                }
                else if (sectorAttribute != null)
                {
                    sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber);
                }
                else if (hasDefaultSector)
                {
                    sector = defaultSector;
                }
                else if (patches.Count > 0)
                {
                    sector = (PsxIso.Sectors)(patches[patches.Count - 1].Sector);
                }
                else
                {
                    throw new Exception("Error in patch XML: Invalid file/sector!");
                }

                bool asmMode      = false;
                bool markedAsData = false;
                if (modeAttribute != null)
                {
                    string modeAttributeText = modeAttribute.InnerText.ToLower().Trim();
                    if (modeAttributeText == "asm")
                    {
                        asmMode = true;
                    }
                    else if (modeAttributeText == "data")
                    {
                        markedAsData = true;
                    }
                }

                bool isRamOffset = false;
                if ((!ignoreOffsetMode) && (offsetModeAttribute != null))
                {
                    if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram")
                    {
                        isRamOffset = true;
                    }
                }

                string content = location.InnerText;
                if (inputFileAttribute != null)
                {
                    using (StreamReader streamReader = new StreamReader(inputFileAttribute.InnerText, Encoding.UTF8))
                    {
                        content = streamReader.ReadToEnd();
                    }
                }

                bool replaceLabels = false;
                if (replaceLabelsAttribute != null)
                {
                    if (replaceLabelsAttribute.InnerText.ToLower().Trim() == "true")
                    {
                        replaceLabels = true;
                    }
                }
                if (replaceLabels)
                {
                    foreach (PatchedByteArray currentPatchedByteArray in patches)
                    {
                        StringBuilder sbLabels = new StringBuilder();
                        if (!string.IsNullOrEmpty(currentPatchedByteArray.Label))
                        {
                            sbLabels.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine));
                        }
                        asmUtility.EncodeASM(sbLabels.ToString(), 0);
                    }
                    content = asmUtility.ReplaceLabelsInHex(content, true);
                }

                string label = "";
                if (attrLabel != null)
                {
                    label = attrLabel.InnerText.Replace(" ", "");
                }

                bool isMoveSimple = asmMode;
                if (attrMovable != null)
                {
                    bool.TryParse(attrMovable.InnerText, out isMoveSimple);
                }

                Nullable <PsxIso.FileToRamOffsets> ftrOffset = null;
                try
                {
                    ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector));
                }
                catch (Exception)
                {
                    ftrOffset = null;
                }

                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.HasValue)
                    {
                        try
                        {
                            if (isRamOffset)
                            {
                                fileOffset -= (UInt32)ftrOffset;
                            }
                            else
                            {
                                ramOffset += (UInt32)ftrOffset;
                            }
                        }
                        catch (Exception) { }
                    }

                    ramOffset = ramOffset | 0x80000000;     // KSEG0

                    byte[] bytes;
                    string errorText = "";
                    if (asmMode)
                    {
                        string encodeContent = content;

                        StringBuilder sbPrefix = new StringBuilder();
                        foreach (PatchedByteArray currentPatchedByteArray in patches)
                        {
                            if (!string.IsNullOrEmpty(currentPatchedByteArray.Label))
                            {
                                sbPrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine));
                            }
                        }
                        foreach (VariableType variable in variables)
                        {
                            sbPrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.name).Replace(",", ""),
                                                          AsmPatch.GetUnsignedByteArrayValue_LittleEndian(variable.byteArray), Environment.NewLine));
                        }

                        encodeContent = sbPrefix.ToString() + content;

                        ASMEncoderResult result = asmUtility.EncodeASM(encodeContent, ramOffset);
                        bytes     = result.EncodedBytes;
                        errorText = result.ErrorText;
                    }
                    else
                    {
                        bytes = GetBytes(content);
                    }

                    bool isCheckedAsm = false;
                    if (!markedAsData)
                    {
                        ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(bytes, ramOffset, true, false, new HashSet <ASMCheckCondition>()
                        {
                            ASMCheckCondition.LoadDelay,
                            ASMCheckCondition.UnalignedOffset,
                            ASMCheckCondition.MultCountdown,
                            ASMCheckCondition.StackPointerOffset4,
                            ASMCheckCondition.BranchInBranchDelaySlot
                        });

                        if (checkResult.IsASM)
                        {
                            isCheckedAsm = true;
                            if (!string.IsNullOrEmpty(checkResult.ErrorText))
                            {
                                errorText += checkResult.ErrorText;
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(errorText))
                    {
                        sbOuterErrorText.Append(errorText);
                    }

                    PatchedByteArray patchedByteArray = new PatchedByteArray(sector, fileOffset, bytes);
                    patchedByteArray.IsAsm              = asmMode;
                    patchedByteArray.MarkedAsData       = markedAsData;
                    patchedByteArray.IsCheckedAsm       = isCheckedAsm;
                    patchedByteArray.IsSequentialOffset = isSequentialOffset;
                    patchedByteArray.IsMoveSimple       = isMoveSimple;
                    patchedByteArray.AsmText            = asmMode ? content : "";
                    patchedByteArray.RamOffset          = ramOffset;
                    patchedByteArray.ErrorText          = errorText;
                    patchedByteArray.Label              = label;

                    patches.Add(patchedByteArray);

                    offsetIndex++;
                    if (offsetIndex < strOffsets.Length)
                    {
                        if (isSpecific)
                        {
                            sector = specifics[offsetIndex].Sector;

                            try
                            {
                                ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector));
                            }
                            catch (Exception)
                            {
                                ftrOffset = null;
                            }
                        }
                    }
                }
            }

            currentLocs = node.SelectNodes("STRLocation");
            foreach (XmlNode location in currentLocs)
            {
                XmlAttribute   fileAttribute   = location.Attributes["file"];
                XmlAttribute   sectorAttribute = location.Attributes["sector"];
                PsxIso.Sectors sector          = (PsxIso.Sectors) 0;
                if (fileAttribute != null)
                {
                    sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText);
                }
                else if (sectorAttribute != null)
                {
                    sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber);
                }
                else
                {
                    throw new Exception();
                }

                string filename = location.Attributes["input"].InnerText;
                filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(xmlFileName), filename);

                patches.Add(new STRPatchedByteArray(sector, filename));
            }

            return(new GetPatchResult(nameDesc.Key, nameDesc.Value, patches.AsReadOnly(), hideInDefault, sbOuterErrorText.ToString()));
        }
Example #4
0
        private static void GetPatch(XmlNode node, string xmlFileName, ASMEncodingUtility asmUtility, out string name, out string description, out IList <PatchedByteArray> staticPatches,
                                     out List <bool> outDataSectionList)
        {
            GetPatchNameAndDescription(node, out name, out description);

            XmlNodeList             currentLocs       = node.SelectNodes("Location");
            List <PatchedByteArray> patches           = new List <PatchedByteArray>(currentLocs.Count);
            List <bool>             isDataSectionList = new List <bool>(currentLocs.Count);

            foreach (XmlNode location in currentLocs)
            {
                UInt32       offset                 = UInt32.Parse(location.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber);
                XmlAttribute fileAttribute          = location.Attributes["file"];
                XmlAttribute sectorAttribute        = location.Attributes["sector"];
                XmlAttribute modeAttribute          = location.Attributes["mode"];
                XmlAttribute offsetModeAttribute    = location.Attributes["offsetMode"];
                XmlAttribute inputFileAttribute     = location.Attributes["inputFile"];
                XmlAttribute replaceLabelsAttribute = location.Attributes["replaceLabels"];

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

                bool asmMode      = false;
                bool markedAsData = false;
                if (modeAttribute != null)
                {
                    string modeAttributeText = modeAttribute.InnerText.ToLower().Trim();
                    if (modeAttributeText == "asm")
                    {
                        asmMode = true;
                    }
                    else if (modeAttributeText == "data")
                    {
                        markedAsData = true;
                    }
                }

                bool isRamOffset = false;
                if (offsetModeAttribute != null)
                {
                    if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram")
                    {
                        isRamOffset = true;
                    }
                }

                UInt32 ramOffset  = offset;
                UInt32 fileOffset = offset;

                try
                {
                    PsxIso.FileToRamOffsets ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + fileAttribute.InnerText);
                    if (isRamOffset)
                    {
                        fileOffset -= (UInt32)ftrOffset;
                    }
                    else
                    {
                        ramOffset += (UInt32)ftrOffset;
                    }
                }
                catch (Exception) { }

                ramOffset = ramOffset | 0x80000000;     // KSEG0

                string content = location.InnerText;
                if (inputFileAttribute != null)
                {
                    using (StreamReader streamReader = new StreamReader(inputFileAttribute.InnerText, Encoding.UTF8))
                    {
                        content = streamReader.ReadToEnd();
                    }
                }

                bool replaceLabels = false;
                if (replaceLabelsAttribute != null)
                {
                    if (replaceLabelsAttribute.InnerText.ToLower().Trim() == "true")
                    {
                        replaceLabels = true;
                    }
                }
                if (replaceLabels)
                {
                    content = asmUtility.ReplaceLabelsInHex(content, true);
                }

                byte[] bytes;
                if (asmMode)
                {
                    bytes = asmUtility.EncodeASM(content, ramOffset).EncodedBytes;
                }
                else
                {
                    bytes = GetBytes(content);
                }

                patches.Add(new PatchedByteArray(sector, fileOffset, bytes));

                isDataSectionList.Add(markedAsData);
            }

            currentLocs = node.SelectNodes("STRLocation");
            foreach (XmlNode location in currentLocs)
            {
                XmlAttribute   fileAttribute   = location.Attributes["file"];
                XmlAttribute   sectorAttribute = location.Attributes["sector"];
                PsxIso.Sectors sector          = (PsxIso.Sectors) 0;
                if (fileAttribute != null)
                {
                    sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText);
                }
                else if (sectorAttribute != null)
                {
                    sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber);
                }
                else
                {
                    throw new Exception();
                }

                string filename = location.Attributes["input"].InnerText;
                filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(xmlFileName), filename);

                patches.Add(new STRPatchedByteArray(sector, filename));
            }

            staticPatches      = patches.AsReadOnly();
            outDataSectionList = isDataSectionList;
        }