Пример #1
0
        private static CompressedWorkItems ReadPacketFromStream(Stream stream)
        {
            const int headerSize = 9;
            var       buffer     = Util.ReadNext(stream, headerSize, out _);

            if (buffer.Length != headerSize)
            {
                throw new InvalidDataException($"invalid header length for compressed data chunk");
            }

            if (buffer[0] != 'Z')
            {
                throw new InvalidDataException($"expected header byte of 'Z', got {buffer[0]} instead.");
            }

            var originalDataSizeBytes = ByteUtil.ByteArrayToInt32(buffer, 1);
            var compressedDataSize    = ByteUtil.ByteArrayToInt32(buffer, 5);

            buffer = Util.ReadNext(stream, compressedDataSize, out _);
            if (buffer.Length != compressedDataSize)
            {
                throw new InvalidDataException(
                          $"compressed data: expected {compressedDataSize} bytes, only got {buffer.Length}");
            }

            return(new CompressedWorkItems()
            {
                Bytes = buffer,
                UncompressedSize = originalDataSizeBytes
            });
        }
Пример #2
0
 public int GetRomCheckSumsFromRomBytes()
 {
     return(ByteUtil.ByteArrayToInt32(GetRomBytes(0xFFDC, 4)));
 }
Пример #3
0
        public override (Project project, string warning) Load(byte[] data)
        {
            if (!IsBinaryFileFormat(data))
            {
                throw new InvalidDataException($"This is not a binary serialized project file!");
            }

            byte version = data[0];

            ValidateProjectFileVersion(version);

            var project = new Project
            {
                Data = new Data()
            };

            // version 0 needs to convert PC to SNES for some addresses
            ByteUtil.AddressConverter converter = address => address;
            if (version == 0)
            {
                converter = project.Data.ConvertPCtoSnes;
            }

            // read mode, speed, size
            project.Data.RomMapMode = (RomMapMode)data[HeaderSize];
            project.Data.RomSpeed   = (RomSpeed)data[HeaderSize + 1];
            var size = ByteUtil.ByteArrayToInt32(data, HeaderSize + 2);

            // read internal title
            var pointer = HeaderSize + 6;

            project.InternalRomGameName = RomUtil.ReadStringFromByteArray(data, RomUtil.LengthOfTitleName, pointer);
            pointer += RomUtil.LengthOfTitleName;

            // read checksums
            project.InternalCheckSum = ByteUtil.ByteArrayToInt32(data, pointer);
            pointer += 4;

            // read full filepath to the ROM .sfc file
            while (data[pointer] != 0)
            {
                project.AttachedRomFilename += (char)data[pointer++];
            }
            pointer++;

            project.Data.RomBytes.Create(size);

            for (int i = 0; i < size; i++)
            {
                project.Data.SetDataBank(i, data[pointer + i]);
            }
            pointer++;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetDirectPage(i, data[pointer + size + i] | (data[pointer + 1 * size + i] << 8));
            }
            pointer += 2;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetXFlag(i, data[pointer * size + i] != 0);
            }
            pointer++;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetMFlag(i, data[pointer * size + i] != 0);
            }
            pointer++;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetFlag(i, (Data.FlagType)data[pointer * size + i]);
            }
            pointer++;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetArchitecture(i, (Data.Architecture)data[pointer * size + i]);
            }
            pointer++;
            for (int i = 0; i < size; i++)
            {
                project.Data.SetInOutPoint(i, (Data.InOutPoint)data[pointer * size + i]);
            }
            pointer++;
            //for (int i = 0; i < size; i++) project.Data.SetBaseAddr(i, (Data.InOutPoint)data[pointer * size + i]); pointer++;

            ReadLabels(project, data, ref pointer, converter, version >= 2);
            ReadComments(project, data, ref pointer, converter);

            project.UnsavedChanges = false;

            var warning = "";

            if (version != LatestFileFormatVersion)
            {
                warning = "This project file is in an older format.\n" +
                          "You may want to back up your work or 'Save As' in case the conversion goes wrong.\n" +
                          "The project file will be untouched until it is saved again.";
            }

            return(project, warning);
        }
Пример #4
0
        private CompressedWorkItem ReadPacketFromStream(Stream stream)
        {
#if PROFILING
            var mainSpan = Markers.EnterSpan("BSNES socket read");
#endif

            var item = AllocateCompressedWorkItem();

            try
            {
                Util.ReadNext(stream, item.Header, CompressedWorkItem.headerSize);
            }
            catch (EndOfStreamException)
            {
                FreeCompressedWorkItem(ref item);
                return(null);
            }

#if PROFILING
            Markers.WriteFlag("initial read");
#endif

            if (item.Header.Length != CompressedWorkItem.headerSize)
            {
                throw new InvalidDataException($"invalid header length for compressed data chunk");
            }

            if (item.Header[0] != 'Z')
            {
                throw new InvalidDataException($"expected header byte of 'Z', got {item.Header[0]} instead.");
            }

            item.UncompressedSize = ByteUtil.ByteArrayToInt32(item.Header, 1);
            item.CompressedSize   = ByteUtil.ByteArrayToInt32(item.Header, 5);

            // allocation pool.  if we need to allocate for compressed data, let's go slightly higher so that
            // we have a chance of re-using this buffer without needing to re-allocate.
            const float
                unscientificGuessAtExtraWeShouldAdd = 1.3f; // total guess. adjust higher if you do too many allocations
            if (item.CompressedBuffer == null || item.CompressedBuffer.Length < item.CompressedSize)
            {
                item.CompressedBuffer = new byte[(int)(item.CompressedSize * unscientificGuessAtExtraWeShouldAdd)];
            }

#if PROFILING
            Markers.WriteFlag("big read start");
#endif
            int bytesRead;
            try
            {
                bytesRead = Util.ReadNext(stream, item.CompressedBuffer, item.CompressedSize);
            }
            catch (EndOfStreamException)
            {
                FreeCompressedWorkItem(ref item);
                return(null);
            }

#if PROFILING
            Markers.WriteFlag("big read done");
#endif

            if (bytesRead != item.CompressedSize)
            {
                throw new InvalidDataException(
                          $"compressed data: expected {item.CompressedSize} bytes, only got {bytesRead}");
            }

#if PROFILING
            mainSpan.Leave();
#endif

            return(item);
        }