Ejemplo n.º 1
0
        static unsafe void Inject(InjectOptions options)
        {
            var elf      = File.ReadAllBytes(options.File);
            var scanner  = new DatScanner(elf);
            var files    = scanner.FindFiles(options.Dat);
            var jsonFile = JsonDatFile.FromFile(options.JsonPath);

            using var memoryStream         = new MemoryStream(elf, true);
            using var streamReader         = new BufferedStreamReader(memoryStream, 2048);
            using var extendedMemoryStream = new ExtendedMemoryStream(elf, true);

            // Patch all table entries.
            foreach (var offset in files.Keys)
            {
                Console.WriteLine($"Patching table at: {offset:X}, RAM: {scanner.RawToMemoryAddress(offset):X}");

                // Go to 2nd entry and get initial file name write pointer.
                streamReader.Seek(offset, SeekOrigin.Begin);
                streamReader.Read(out DatFileEntry firstEntry);

                // Get file name write pointer.
                streamReader.Peek(out DatFileEntry secondEntry);
                int fileNameWritePointer = scanner.MemoryToRawAddress(secondEntry.NamePtr);

                // Write archive entry
                var newFirstEntry = new DatFileEntry(firstEntry.NamePtr, jsonFile.Files[0].Offset / DatFileEntry.SECTOR_SIZE_BYTES, jsonFile.Files[0].SizeBytes);
                extendedMemoryStream.Seek(offset, SeekOrigin.Begin);
                extendedMemoryStream.Write(newFirstEntry);

                // Now write each file in order, while keeping track of the pointer.
                foreach (var entry in jsonFile.Files)
                {
                    // Make entry for the file.
                    var datEntry = new DatFileEntry(scanner.RawToMemoryAddress(fileNameWritePointer), entry.Offset / DatFileEntry.SECTOR_SIZE_BYTES, entry.SizeBytes);
                    extendedMemoryStream.Write(datEntry);

                    // Get bytes attached to the name (w/ Null Terminator).
                    var alignedTextLength = Utilities.Utilities.RoundUp(entry.Name.Length + 1, 8); // Alignment of 8
                    var nameBytes         = new byte[alignedTextLength];
                    Encoding.ASCII.GetBytes(entry.Name, nameBytes);

                    // Write bytes to pointer.
                    Array.Copy(nameBytes, 0, elf, fileNameWritePointer, nameBytes.Length);

                    // Align text to next predetermined value like in original ELF.
                    fileNameWritePointer += alignedTextLength;
                }
            }

            // Write new executable to file.
            memoryStream.Dispose();
            streamReader.Dispose();
            extendedMemoryStream.Dispose();

            Console.WriteLine($"Writing patched file to: {options.File}");
            File.WriteAllBytes(options.File, elf);
        }
Ejemplo n.º 2
0
        public FileListItem(DatFileEntry entry)
        {
            Entry = entry;
            UseItemStyleForSubItems = false;

            nameItem = SubItems.Add(new ListViewSubItem());
            typeItem = SubItems.Add(new ListViewSubItem());
            sizeItem = SubItems.Add(new ListViewSubItem());

            sizeItem.Font = new System.Drawing.Font("Consolas", 10);

            switch (entry.Type)
            {
            case DatFileEntry.DataType.Image:
                BackColor = Color.FromArgb(255, 220, 255, 220);
                break;

            case DatFileEntry.DataType.Map:
                BackColor = Color.FromArgb(255, 220, 220, 255);
                break;

            case DatFileEntry.DataType.Music:
                BackColor = Color.FromArgb(255, 255, 255, 220);
                break;

            case DatFileEntry.DataType.SoundFX:
                BackColor = Color.FromArgb(255, 255, 255, 180);
                break;

            case DatFileEntry.DataType.SpeakerSound:
                BackColor = Color.FromArgb(255, 255, 255, 140);
                break;

            case DatFileEntry.DataType.Sprite:
                BackColor = Color.FromArgb(255, 180, 255, 180);
                break;

            case DatFileEntry.DataType.Text:
                BackColor = Color.FromArgb(255, 220, 220, 220);
                break;

            case DatFileEntry.DataType.Unknown:
            default:
                BackColor = Color.FromArgb(255, 255, 0, 0);
                break;
            }

            updateCaptions();
        }
Ejemplo n.º 3
0
        public EditForm(Game game, DatFileEntry entry)
        {
            InitializeComponent();
            Entry     = entry;
            this.game = game;

            hexBox                       = new HexBox();
            hexBox.Width                 = hexPanel.Width;
            hexBox.Height                = hexPanel.Height;
            hexBox.ByteProvider          = new DynamicByteProvider(entry.Data);
            hexBox.GroupSize             = 4;
            hexBox.Dock                  = DockStyle.Fill;
            hexBox.GroupSeparatorVisible = true;
            hexBox.VScrollBarVisible     = true;
            hexBox.LineInfoVisible       = true;
            hexPanel.Controls.Add(hexBox);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates a new Json entry given a DAT file entry.
 /// </summary>
 public JsonFileEntry(DatFileEntry entry, BufferedStreamReader stream, Func <int, int> memoryToRawAddress)
 {
     Name      = entry.GetName(stream, memoryToRawAddress);
     SizeBytes = entry.SizeBytes;
     Offset    = entry.Sector * DatFileEntry.SECTOR_SIZE_BYTES;
 }
Ejemplo n.º 5
0
        private void showFileDetails(DatFileEntry entry)
        {
            selectionLabel.Text = "";
            detailsStatusLabel.Text = "";
            cursorStatusLabel.Text = "";
            currentBitmap = null;
            currentSprite = null;
            currentMap = null;
            canvasPanel.Visible = false;
            detailsTextBox.Visible = false;

            pngButton.Visible = false;
            mapButtonsPanel.Visible = false;
            frameSelectionPanel.Visible = false;

            cmfPlayerPanel.Visible = false;
            stopMusicPlayback();

            vocPlayerPanel.Visible = false;

            currentSpriteFrame = 0;

            if (entry == null) return;

            selectionLabel.Text = "[" + entry.TypeString.ToUpper() + "] " + 
                Path.GetFileName(Game.ArchiveFile) + " / " + 
                entry.Filename;

            switch(entry.Type)
            {
                case DatFileEntry.DataType.Sprite:
                    currentSprite = entry.GetSprite(game.MainPalette);

                    if (currentSprite == null)
                    {
                        MessageBox.Show("Failed to load sprite");
                        return;
                    }

                    currentBitmap = currentSprite.Frames[0];

                    detailsStatusLabel.Text = $"Frame size: {currentBitmap.Width}x{currentBitmap.Height}";
                    
                    if (currentSprite.Frames.Length > 1)
                    {
                        frameSelectionPanel.Visible = true;
                        frameLabel.Text = "1/" + currentSprite.Frames.Length;
                        currentSpriteFrame = 0;
                    }

                    pngButton.Visible = true;
                    canvasPanel.Visible = true;
                    break;

                case DatFileEntry.DataType.Image:
                    try
                    {
                        PcxFile pcx = entry.GetPicture();
                        currentBitmap = pcx.Bitmap;
                        detailsStatusLabel.Text = $"Image size: {currentBitmap.Width}x{currentBitmap.Height}";
                        pngButton.Visible = true;
                        canvasPanel.Visible = true;
                    }
                    catch (Exception e)
                    { 
                        MessageBox.Show("Failed to convert from PCX to bitmap: " + e.Message, "Conversion failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    break;

                case DatFileEntry.DataType.Map:
                    currentMap = entry.GetMap();
                    if (currentMap == null)
                    {
                        MessageBox.Show("Failed to load map");
                        return;
                    }

                    Game.MapInfo info = Game.InfoByFilename(currentMap.Entry.Filename);
                    selectionLabel.Text += $" - \"{info.Title}\"";
                    detailsStatusLabel.Text = $"Size: {currentMap.Width}x{currentMap.Height}, Password: \"{info.Password}\", Music: {info.Music}";

                    mapButtonsPanel.Visible = true;
                    canvasPanel.Visible = true;
                    break;

                case DatFileEntry.DataType.Music:
                    try
                    {
                        startMusicPlayback(entry.Data);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("Failed to load CMF music: " + e.Message, "Audio failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    break;

                case DatFileEntry.DataType.SoundFX:
                    currentVoc = new VocFile(entry.Data);

                    int sec = (int)Math.Ceiling(currentVoc.SecDuration);
                    vocTimeLabel.Text = (sec / 60).ToString("D2") + ":" + (sec % 60).ToString("D2") +
                        " @ " + currentVoc.samplerate +
                        " Hz (" + currentVoc.format + ")";

                    vocPlayerPanel.Visible = true;
                    break;

                case DatFileEntry.DataType.Text:
                    detailsTextBox.Text = entry.GetText();
                    detailsTextBox.Visible = true;
                    break;
            }

            draw();
        }