예제 #1
0
        public RomFile(string fileName, int fileID, UnknownData rawFileData)
        {
            FileName = fileName;
            FileID = fileID;

            _elements = new N64DataElementCollection();
            _elements.UnknownDataAdded += _elements_UnknownDataAdded;
            _elements.UnknownDataRemoved += _elements_UnknownDataRemoved;

            _elementContainers = new List<IN64ElementContainer>();
            _miscElementContainer = new MiscN64ElementContainer();

            FileLength = rawFileData.RawDataSize;

            _elements.AddElement(rawFileData);
        }
        public bool AddElement(N64DataElement element, bool overwriteUnknownData = true)
        {
            if (element.FileOffset < 0)
                return false;

            int startOffset = element.FileOffset;
            int endOffset = startOffset + element.RawDataSize - 1;

            //Find if it is inside a currently existing element, or if it can be added freely
            int indexToAdd = 0;
            bool insideElement = false;

            for (; indexToAdd < _elements.Count; indexToAdd++)
            {
                if (endOffset < _elements[indexToAdd].FileOffset)
                {
                    //Found where to insert the new element
                    break;
                }
                else if (_elements[indexToAdd].ContainsOffset(startOffset) ||
                    _elements[indexToAdd].ContainsOffset(endOffset) ||
                    element.ContainsOffset(_elements[indexToAdd].FileOffset))
                {
                    insideElement = true;
                    break;
                }
            }

            //If there were conflicts
            if (insideElement)
            {
                //Determine if we can overwrite unknown data with known data
                if (_elements[indexToAdd] is UnknownData && overwriteUnknownData && !((UnknownData)_elements[indexToAdd]).Locked)
                {
                    //Step one: determine how many elements this new one spans
                    int endingIndex = indexToAdd;
                    for (; endingIndex < _elements.Count - 1; endingIndex++)
                    {
                        //If it doesn't run into this next data element, then it stops before it. Break out of the loop
                        if (!_elements[endingIndex + 1].ContainsOffset(endOffset) &&
                            !element.ContainsOffset(_elements[endingIndex + 1].FileOffset))
                            break;

                        //Only unlocked unknown data may be split
                        if (!(_elements[endingIndex + 1] is UnknownData) || ((UnknownData)_elements[indexToAdd]).Locked)
                            return false;
                    }

                    //Step two: determine how to split the start/ends.
                    bool startUnknownLeftOver = false;
                    bool endUnknownLeftOver = false;

                    if (_elements[indexToAdd].ContainsOffset(startOffset) &&
                        _elements[indexToAdd].FileOffset != startOffset)
                        startUnknownLeftOver = true;

                    if (_elements[endingIndex].ContainsOffset(endOffset) &&
                        _elements[endingIndex].FileOffset + _elements[endingIndex].RawDataSize - 1 != endOffset)
                        endUnknownLeftOver = true;

                    if (startUnknownLeftOver)
                    {
                        byte[] unknownData = new byte[startOffset - _elements[indexToAdd].FileOffset];
                        Array.Copy(_elements[indexToAdd].RawData, 0, unknownData, 0, unknownData.Length);

                        UnknownData newData = new UnknownData(_elements[indexToAdd].FileOffset, unknownData);
                        _elements.Insert(indexToAdd, newData);

                        if (UnknownDataAdded != null)
                            UnknownDataAdded(newData);

                        indexToAdd++;
                        endingIndex++;
                    }

                    if (endUnknownLeftOver)
                    {
                        byte[] unknownData = new byte[_elements[endingIndex].FileOffset + _elements[endingIndex].RawDataSize - (endOffset + 1)];
                        Array.Copy(_elements[endingIndex].RawData, (endOffset + 1) - _elements[endingIndex].FileOffset, unknownData, 0, unknownData.Length);

                        UnknownData newData = new UnknownData(endOffset + 1, unknownData);
                        _elements.Insert(endingIndex + 1, newData);

                        if (UnknownDataAdded != null)
                            UnknownDataAdded(newData);
                    }

                    //Step 3: Remove the overlapping unknowns, insert the new data
                    for (int i = 0; i <= endingIndex - indexToAdd; i++)
                    {
                        if (UnknownDataRemoved != null)
                            UnknownDataRemoved((UnknownData)_elements[indexToAdd]);

                        _elements.RemoveAt(indexToAdd);
                    }
                    _elements.Insert(indexToAdd, element);

                    return true;
                }
                else
                {
                    return false;
                }
            }

            //Down here, there were no conflicts
            _elements.Insert(indexToAdd, element);
            return true;
        }
예제 #3
0
        /// <summary>
        /// Allow split data from the N64DataElementCollection to still be sorted into containers
        /// </summary>
        /// <param name="data"></param>
        private void _elements_UnknownDataAdded(UnknownData data)
        {
            bool added = false;

            foreach (IN64ElementContainer container in _elementContainers)
            {
                if (container.AddElement(data))
                    added = true;
            }

            if(!added)
                _miscElementContainer.AddElement(data);
        }
예제 #4
0
        public bool ExpandFileTo(int newFileSize, byte fillByte = 0x00)
        {
            if (newFileSize <= FileLength)
                return false;

            N64DataElement lastElement = GetElementAt(FileLength - 1);
            if (lastElement == null)
                return false;

            //Create a new UnknownData element
            byte[] newBytes =  new byte[newFileSize - FileLength];
            for(int i = 0; i < newBytes.Length; i++)
                newBytes[i] = fillByte;
            UnknownData newData = new UnknownData(FileLength, newBytes);
            return AddElement(newData);
        }
예제 #5
0
 /// <summary>
 /// Allow split data from the N64DataElementCollection to still be sorted into containers
 /// </summary>
 /// <param name="data"></param>
 private void _elements_UnknownDataRemoved(UnknownData data)
 {
     foreach (IN64ElementContainer container in _elementContainers)
     {
         container.RemoveElement(data);
     }
     _miscElementContainer.RemoveElement(data);
 }