예제 #1
0
        private void RenderFullImage(Tiny64.Machine machine, GR.Image.MemoryImage img)
        {
            // render image
            bool vicActive = ((machine.Memory.VIC.ReadByte(0x11) & 0x10) != 0);

            if (vicActive)
            {
                int  vicBank          = (machine.Memory.CIA2.ReadByte(0) & 0x03) ^ 0x03;
                int  screenPos        = ((machine.Memory.VIC.ReadByte(0x18) & 0xf0) >> 4) * 1024 + vicBank * 16384;
                int  localCharDataPos = (machine.Memory.VIC.ReadByte(0x18) & 0x0e) * 1024;
                int  charDataPos      = localCharDataPos + vicBank * 16384;
                byte bgColor          = (byte)(machine.Memory.VIC.ReadByte(0x21) & 0x0f);

                GR.Memory.ByteBuffer charData = null;
                if (((vicBank == 0) ||
                     (vicBank == 2)) &&
                    (localCharDataPos == 0x1000))
                {
                    // use default upper case chars
                    charData = new GR.Memory.ByteBuffer();
                    charData.Append(Machine.Memory.CharacterROM, 0, 2048);
                }
                else if (((vicBank == 0) ||
                          (vicBank == 2)) &&
                         (localCharDataPos == 0x2000))
                {
                    // use default lower case chars
                    charData = new GR.Memory.ByteBuffer();
                    charData.Append(Machine.Memory.CharacterROM, 2048, 2048);
                }
                else
                {
                    // use RAM
                    charData = new GR.Memory.ByteBuffer(machine.Memory.RAM);
                    charData = charData.SubBuffer(charDataPos, 2048);
                }
                for (int y = 0; y < 25; ++y)
                {
                    for (int x = 0; x < 40; ++x)
                    {
                        byte charIndex = machine.Memory.RAM[screenPos + x + y * 40];
                        byte charColor = machine.Memory.ColorRAM[x + y * 40];

                        //CharacterDisplayer.DisplayHiResChar( charData.SubBuffer( charIndex * 8, 8 ), bgColor, charColor, img, x * 8, y * 8 );
                    }
                }

                /*
                 * DataObject dataObj = new DataObject();
                 *
                 * GR.Memory.ByteBuffer      dibData = img.CreateHDIBAsBuffer();
                 *
                 * System.IO.MemoryStream    ms = dibData.MemoryStream();
                 *
                 * // WTF - SetData requires streams, NOT global data (HGLOBAL)
                 * dataObj.SetData( "DeviceIndependentBitmap", ms );
                 * Clipboard.SetDataObject( dataObj, true );*/
            }
        }
예제 #2
0
        private void btnOpenBinary_Click(object sender, EventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();

            openDialog.Title = "Choose binary file";
            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                m_OpenedFilename = openDialog.FileName;

                GR.Memory.ByteBuffer data = GR.IO.File.ReadAllBytes(openDialog.FileName);
                if (data != null)
                {
                    ushort loadAddress = 0x801;

                    if (System.IO.Path.GetExtension(openDialog.FileName).ToUpper() == ".PRG")
                    {
                        // treat first two bytes as load address
                        loadAddress = data.UInt16At(0);

                        data = data.SubBuffer(2);
                    }
                    m_Disassembler.SetData(data);
                    m_DisassemblyProject.Data = data;

                    editStartAddress.Text = "$" + loadAddress.ToString("X4");

                    int sysAddress = -1;

                    if (m_Disassembler.HasBASICJumpAddress(loadAddress, out sysAddress))
                    {
                        m_DisassemblyProject.JumpedAtAddresses.Add(sysAddress);

                        ListViewItem item = new ListViewItem();
                        FillItemFromAddress(item, sysAddress);
                        listJumpedAtAddresses.Items.Add(item);
                    }
                    else
                    {
                        // we have no jump address, assume first byte as address
                        m_DisassemblyProject.JumpedAtAddresses.Add(loadAddress);

                        ListViewItem item = new ListViewItem();
                        FillItemFromAddress(item, loadAddress);
                        listJumpedAtAddresses.Items.Add(item);
                    }

                    SetHexData(data);

                    UpdateDisassembly();
                }
            }
        }
예제 #3
0
        public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, Types.FileType Type)
        {
            _LastError = "";

            int fileIndex = 0;

            foreach (FileRecord file in FileRecords)
            {
                if (file.EntryType == 0)
                {
                    // free slot found
                    file.EntryType   = 1;
                    file.C64FileType = Type;
                    if (Type == Types.FileType.PRG)
                    {
                        file.StartAddress = Content.UInt16At(0);
                        if (Content.Length < 2)
                        {
                            FileDatas[fileIndex] = new GR.Memory.ByteBuffer();
                        }
                        else
                        {
                            FileDatas[fileIndex] = Content.SubBuffer(2);
                        }
                    }
                    else
                    {
                        file.StartAddress    = 0x0801;
                        FileDatas[fileIndex] = new GR.Memory.ByteBuffer(Content);
                    }
                    file.EndAddress = (ushort)(file.StartAddress + Content.Length);
                    file.FileOffset = 0;
                    file.Filename   = Filename;
                    return(true);
                }
                ++fileIndex;
            }
            _LastError = "tape image is full";
            return(false);
        }
예제 #4
0
        private void btnReloadFile_Click(object sender, EventArgs e)
        {
            GR.Memory.ByteBuffer data = GR.IO.File.ReadAllBytes(m_OpenedFilename);
            if (data != null)
            {
                ushort loadAddress = 0x801;

                if (System.IO.Path.GetExtension(m_OpenedFilename).ToUpper() == ".PRG")
                {
                    // treat first two bytes as load address
                    loadAddress = data.UInt16At(0);

                    data = data.SubBuffer(2);
                }
                m_Disassembler.SetData(data);
                m_DisassemblyProject.Data = data;

                SetHexData(data);

                UpdateDisassembly();
            }
        }
예제 #5
0
파일: Tap.cs 프로젝트: wowjinxy/C64Studio
        public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type)
        {
            _LastError = "";
            FileEntry file = new FileEntry();

            file.Filename = new GR.Memory.ByteBuffer(Filename);
            file.Data     = new GR.Memory.ByteBuffer(Content);
            if (Type == C64Studio.Types.FileType.PRG)
            {
                if (Content.Length >= 2)
                {
                    file.StartAddress = Content.UInt16At(0);
                    file.Data         = Content.SubBuffer(2);
                }
            }
            file.EndAddress = (ushort)(file.StartAddress + file.Data.Length - 1);
            if (file.StartAddress + file.Data.Length >= 65536)
            {
                _LastError = "file size too large";
                return(false);
            }
            TapFiles.Add(file);
            return(true);
        }
        public bool ReadFromBuffer(GR.Memory.ByteBuffer DataIn)
        {
            if (DataIn == null)
            {
                return(false);
            }
            GR.IO.MemoryReader memIn = DataIn.MemoryReader();

            uint version = memIn.ReadUInt32();

            if (version == 1)
            {
                TotalNumberOfCharacters = 256;

                string name            = memIn.ReadString();
                string charsetFilename = memIn.ReadString();
                for (int i = 0; i < TotalNumberOfCharacters; ++i)
                {
                    Characters[i].Tile.CustomColor = memIn.ReadInt32();
                }

                bool hasAnyMC = false;
                for (int i = 0; i < TotalNumberOfCharacters; ++i)
                {
                    var mode = (TextCharMode)memIn.ReadUInt8();

                    if ((mode == TextCharMode.COMMODORE_MULTICOLOR) &&
                        (Characters[i].Tile.CustomColor < 8))
                    {
                        mode = TextCharMode.COMMODORE_HIRES;
                    }
                    if (mode == TextCharMode.COMMODORE_MULTICOLOR)
                    {
                        hasAnyMC = true;
                    }
                }
                Colors.BackgroundColor = memIn.ReadInt32();
                Colors.MultiColor1     = memIn.ReadInt32();
                Colors.MultiColor2     = memIn.ReadInt32();


                for (int i = 0; i < TotalNumberOfCharacters; ++i)
                {
                    int tileColor1 = memIn.ReadInt32();
                    int tileColor2 = memIn.ReadInt32();
                    int tileColor3 = memIn.ReadInt32();
                    int tileColor4 = memIn.ReadInt32();
                    int tileChar1  = memIn.ReadInt32();
                    int tileChar2  = memIn.ReadInt32();
                    int tileChar3  = memIn.ReadInt32();
                    int tileChar4  = memIn.ReadInt32();
                }

                bool genericMulticolor       = (memIn.ReadInt32() != 0);
                GR.Memory.ByteBuffer testbed = new GR.Memory.ByteBuffer();
                memIn.ReadBlock(testbed, 64);

                GR.Memory.ByteBuffer charsetData = new GR.Memory.ByteBuffer();
                memIn.ReadBlock(charsetData, (uint)(TotalNumberOfCharacters * 8));

                for (int i = 0; i < TotalNumberOfCharacters; ++i)
                {
                    Characters[i].Tile.Data = charsetData.SubBuffer(i * 8, 8);
                }

                UsedTiles = memIn.ReadUInt32();

                ExportFilename = memIn.ReadString();
                string exportPathBlockTable  = memIn.ReadString();
                string exportPathCharset     = memIn.ReadString();
                string exportPathEditorTiles = memIn.ReadString();

                // categories
                Categories.Clear();
                int categoryCount = memIn.ReadInt32();
                for (int i = 0; i < categoryCount; ++i)
                {
                    int    catKey  = memIn.ReadInt32();
                    string catName = memIn.ReadString();

                    Categories.Add(catName);
                }
                if (Categories.Count == 0)
                {
                    // add default category
                    Categories.Add("Uncategorized");
                }
                for (int i = 0; i < TotalNumberOfCharacters; ++i)
                {
                    Characters[i].Category = memIn.ReadInt32();
                    if ((Characters[i].Category < 0) ||
                        (Characters[i].Category >= Categories.Count))
                    {
                        Characters[i].Category = 0;
                    }
                }
                ExportNumCharacters = memIn.ReadInt32();
                if (ExportNumCharacters < TotalNumberOfCharacters)
                {
                    ExportNumCharacters = TotalNumberOfCharacters;
                }
                ShowGrid             = (memIn.ReadInt32() != 0);
                ExportStartCharacter = memIn.ReadInt32();
                Colors.BGColor4      = memIn.ReadInt32();

                // playground
                int w = memIn.ReadInt32();
                int h = memIn.ReadInt32();
                if (w * h < 256)
                {
                    w = 16;
                    h = 16;
                }
                PlaygroundChars = new List <uint>(w * h);
                for (int i = 0; i < w * h; ++i)
                {
                    ushort charInfo = memIn.ReadUInt16();
                    PlaygroundChars.Add((uint)((charInfo & 0xff) | ((charInfo & 0xff00) << 8)));
                }

                Mode = (TextCharMode)memIn.ReadInt32();
                if (hasAnyMC)
                {
                    Mode = TextCharMode.COMMODORE_MULTICOLOR;
                }
            }
            else if (version == 2)
            {
                Characters.Clear();
                Categories.Clear();
                Colors.Palettes.Clear();
                TotalNumberOfCharacters = 256;
                Mode = TextCharMode.COMMODORE_HIRES;

                var chunk = new GR.IO.FileChunk();

                while (chunk.ReadFromStream(memIn))
                {
                    if (chunk.Type == FileChunkConstants.CHARSET_PROJECT)
                    {
                        var chunkIn = chunk.MemoryReader();

                        var subChunk = new GR.IO.FileChunk();

                        while (subChunk.ReadFromStream(chunkIn))
                        {
                            var subMemIn = subChunk.MemoryReader();
                            switch (subChunk.Type)
                            {
                            case FileChunkConstants.CHARSET_INFO:
                                Mode = (TextCharMode)subMemIn.ReadInt32();
                                TotalNumberOfCharacters = subMemIn.ReadInt32();
                                ShowGrid = ((subMemIn.ReadInt32() & 1) == 1);
                                break;

                            case FileChunkConstants.CHARSET_COLOR_SETTINGS:
                                Colors.BackgroundColor = subMemIn.ReadInt32();
                                Colors.MultiColor1     = subMemIn.ReadInt32();
                                Colors.MultiColor2     = subMemIn.ReadInt32();
                                Colors.BGColor4        = subMemIn.ReadInt32();
                                Colors.ActivePalette   = subMemIn.ReadInt32();
                                break;

                            case FileChunkConstants.PALETTE:
                                Colors.Palettes.Add(Palette.Read(subMemIn));
                                break;

                            case FileChunkConstants.CHARSET_EXPORT:
                                ExportStartCharacter = subMemIn.ReadInt32();
                                ExportNumCharacters  = subMemIn.ReadInt32();
                                ExportFilename       = subMemIn.ReadString();
                                break;

                            case FileChunkConstants.CHARSET_CHAR:
                            {
                                var charData = new CharData();

                                subMemIn.ReadInt32(); // was TextCharMode
                                charData.Tile.CustomColor = subMemIn.ReadInt32();
                                charData.Tile.Mode        = Lookup.GraphicTileModeFromTextCharMode(Mode, charData.Tile.CustomColor);

                                charData.Category = subMemIn.ReadInt32();

                                int dataLength = subMemIn.ReadInt32();
                                charData.Tile.Data = new GR.Memory.ByteBuffer();
                                subMemIn.ReadBlock(charData.Tile.Data, (uint)dataLength);

                                Characters.Add(charData);
                            }
                            break;

                            case FileChunkConstants.CHARSET_CATEGORY:
                                Categories.Add(subMemIn.ReadString());
                                break;

                            case FileChunkConstants.CHARSET_PLAYGROUND:
                                PlaygroundWidth  = subMemIn.ReadInt32();
                                PlaygroundHeight = subMemIn.ReadInt32();

                                PlaygroundChars = new List <uint>(PlaygroundWidth * PlaygroundHeight);

                                for (int i = 0; i < PlaygroundWidth * PlaygroundHeight; ++i)
                                {
                                    // 16 bit index, 16 bit color
                                    PlaygroundChars.Add(subMemIn.ReadUInt32());
                                }
                                break;
                            }
                        }
                    }
                }
                if (Colors.Palettes.Count == 0)
                {
                    Colors.Palettes.Add(PaletteManager.PaletteFromNumColors(Lookup.NumberOfColorsInCharacter(Mode)));
                }
            }
            else
            {
                return(false);
            }
            return(true);
        }
        public bool ReadFromBuffer(GR.Memory.ByteBuffer DataIn)
        {
            GR.IO.MemoryReader memIn = DataIn.MemoryReader();

            uint   version         = memIn.ReadUInt32();
            string name            = memIn.ReadString();
            string charsetFilename = memIn.ReadString();

            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Color = memIn.ReadInt32();
            }
            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Multicolor = (memIn.ReadUInt8() != 0);
            }
            BackgroundColor = memIn.ReadInt32();
            MultiColor1     = memIn.ReadInt32();
            MultiColor2     = memIn.ReadInt32();


            for (int i = 0; i < 256; ++i)
            {
                int tileColor1 = memIn.ReadInt32();
                int tileColor2 = memIn.ReadInt32();
                int tileColor3 = memIn.ReadInt32();
                int tileColor4 = memIn.ReadInt32();
                int tileChar1  = memIn.ReadInt32();
                int tileChar2  = memIn.ReadInt32();
                int tileChar3  = memIn.ReadInt32();
                int tileChar4  = memIn.ReadInt32();
            }

            bool genericMulticolor = (memIn.ReadInt32() != 0);

            GR.Memory.ByteBuffer testbed = new GR.Memory.ByteBuffer();
            memIn.ReadBlock(testbed, 64);

            GR.Memory.ByteBuffer charsetData = new GR.Memory.ByteBuffer();
            memIn.ReadBlock(charsetData, 2048);

            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Data = charsetData.SubBuffer(i * 8, 8);
            }

            UsedTiles = memIn.ReadUInt32();

            ExportFilename = memIn.ReadString();
            string exportPathBlockTable  = memIn.ReadString();
            string exportPathCharset     = memIn.ReadString();
            string exportPathEditorTiles = memIn.ReadString();

            // categories
            Categories.Clear();
            int categoryCount = memIn.ReadInt32();

            for (int i = 0; i < categoryCount; ++i)
            {
                int    catKey  = memIn.ReadInt32();
                string catName = memIn.ReadString();

                Categories[catKey] = catName;
            }
            if (Categories.Count == 0)
            {
                // add default category
                Categories[0] = "Uncategorized";
            }
            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Category = memIn.ReadInt32();
            }
            return(true);
        }
예제 #8
0
 public void UpdateValue( RequestData WatchData, GR.Memory.ByteBuffer Data )
 {
   int     delta = WatchData.AdjustedStartAddress - WatchData.Parameter1;
   int     expectedSize = (int)Data.Length;
   if ( ( WatchData.MemDumpOffsetX )
   ||   ( WatchData.MemDumpOffsetY ) )
   {
     delta -= WatchData.AppliedOffset;
   }
   if ( WatchData.Parameter2 != -1 )
   {
     expectedSize = WatchData.Parameter2 - WatchData.Parameter1 + 1;
   }
   if ( delta > 0 )
   {
     // offset had to be adjusted due to VICE weird binary offset/end offset format
     if ( delta < Data.Length )
     {
       UpdateValue( WatchData.Info, WatchData.MemDumpOffsetX, WatchData.MemDumpOffsetY, Data.SubBuffer( delta, expectedSize ) );
     }
   }
   else if ( expectedSize < Data.Length )
   {
     UpdateValue( WatchData.Info, WatchData.MemDumpOffsetX, WatchData.MemDumpOffsetY, Data.SubBuffer( 0, expectedSize ) );
   }
   else
   {
     UpdateValue( WatchData.Info, WatchData.MemDumpOffsetX, WatchData.MemDumpOffsetY, Data );
   }
 }
예제 #9
0
        public override bool Load(string Filename)
        {
            _LastError = "";
            Clear();
            GR.Memory.ByteBuffer data = GR.IO.File.ReadAllBytes(Filename);
            if (data == null)
            {
                _LastError = "could not open/read file";
                return(false);
            }
            if (data.Length < 64)
            {
                _LastError = "file size is too small";
                return(false);
            }

            // Tape Header
            // 0 32 DOS tape description + EOF (for type)
            // 32 2 tape version ($0200)
            // 34 2 number of directory entries
            // 36 2 number of used entries (can be 0 in my loader)
            // 38 2 free
            // 40 24 user description as displayed in tape menu

            for (int i = 0; i < 32; ++i)
            {
                if (data.ByteAt(i) == (char)0x1a)
                {
                    break;
                }
                TapeInfo.Description += (char)data.ByteAt(i);
            }
            ushort version = data.UInt16At(32);

            /*
             * if ( version != 0x0200 )
             * {
             * return false;
             * }*/
            TapeInfo.NumberEntries     = data.UInt16At(34);
            TapeInfo.NumberUsedEntries = data.UInt16At(36);

            for (int i = 0; i < 24; ++i)
            {
                if (data.ByteAt(40 + i) == (char)0x20)
                {
                    break;
                }
                TapeInfo.UserDescription += (char)data.ByteAt(i);
            }
            int entryPos = 64;

            for (int i = 0; i < TapeInfo.NumberEntries; ++i)
            {
                // File Header
                // Offset Size Description
                // 0 1 entry type (see below)
                // 1 1 C64 file type
                // 2 2 start address
                // 4 2 end address
                // 6 2 free
                // 8 4 offset of file contents start within T64 file
                // 12 4 free
                // 16 16 C64 file name

                // Code Explanation
                // 0 free entry
                // 1 normal tape file
                // 2 tape file with header: header is saved just before file data
                // 3 memory snapshot v0.9, uncompressed
                // 4 tape block
                // 5 digitized stream
                // 6 ... 255 reserved
                FileRecord file = new FileRecord();

                file.EntryType = data.ByteAt(entryPos + 0);
                if ((file.EntryType != 1) &&
                    (file.EntryType != 0))
                {
                    // unsupported type!
                    _LastError = "unsupported entry type";
                    return(false);
                }
                if (file.EntryType == 0)
                {
                    FileRecords.Add(file);
                    FileDatas.Add(new GR.Memory.ByteBuffer());

                    entryPos += 32;
                    continue;
                }
                file.C64FileType  = (Types.FileType)data.ByteAt(entryPos + 1);
                file.StartAddress = data.UInt16At(entryPos + 2);
                file.EndAddress   = data.UInt16At(entryPos + 4);
                file.FileOffset   = data.UInt32At(entryPos + 8);
                for (int j = 0; j < 16; ++j)
                {
                    file.Filename.AppendU8(data.ByteAt(entryPos + 16 + j));
                }
                FileRecords.Add(file);
                FileDatas.Add(data.SubBuffer((int)file.FileOffset, (int)(file.EndAddress - file.StartAddress)));
                entryPos += 32;
            }
            return(true);
        }
예제 #10
0
        private bool LoadVersion5(GR.Memory.ByteBuffer Data)
        {
            BackgroundColor = Data.ByteAt(4);
            MultiColor1     = Data.ByteAt(5);
            MultiColor2     = Data.ByteAt(6);
            CustomColor     = Data.ByteAt(7);
            TileColorMode   = (ColorMode)Data.ByteAt(8);

            byte flags   = Data.ByteAt(9);
            bool noTiles = ((flags & 0x01) == 0);

            MultiColor = ((flags & 0x04) != 0);
            bool isExpanded = ((flags & 0x02) != 0);

            NumChars   = Data.UInt16At(10) + 1;
            NumTiles   = Data.UInt16At(12) + 1;
            TileWidth  = Data.ByteAt(14);
            TileHeight = Data.ByteAt(15);

            MapWidth  = Data.UInt16At(16);
            MapHeight = Data.UInt16At(18);

            if (noTiles)
            {
                // fake tiles
                TileWidth  = 1;
                TileHeight = 1;
                NumTiles   = 256;
            }


            int headerSize          = 20;
            int offsetToCharData    = headerSize;
            int offsetToCharAttribs = offsetToCharData + NumChars * 8;
            int offsetToTileData    = offsetToCharAttribs + NumChars;
            int offsetToTileColors  = offsetToTileData + NumTiles * TileWidth * TileHeight * 2;

            if ((isExpanded) ||
                (noTiles))
            {
                offsetToTileColors = offsetToTileData;
            }
            int offsetToMapData = offsetToTileColors + NumTiles;

            if ((TileColorMode != ColorMode.PER_TILE) ||
                (noTiles))
            {
                offsetToMapData = offsetToTileColors;
            }

            // char_data/char_attribs
            for (int charIndex = 0; charIndex < NumChars; ++charIndex)
            {
                SingleChar newChar = new SingleChar();
                newChar.Data = Data.SubBuffer(offsetToCharData + charIndex * 8, 8);
                if (TileColorMode == ColorMode.PER_TILE_CELL)
                {
                    newChar.Color = Data.ByteAt(offsetToCharAttribs + charIndex) & 0x0f;
                }
                else
                {
                    newChar.Color = CustomColor;
                }

                Characters.Add(newChar);
            }

            // tile_data
            if (noTiles)
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    Tile tile = new Tile();

                    tile.CharData.Resize((uint)(TileWidth * TileHeight * 2));
                    tile.CharData.SetU16At(0, (ushort)i);

                    tile.ColorData.Resize((uint)(TileWidth * TileHeight));
                    tile.ColorData.SetU8At(0, (byte)CustomColor);

                    Tiles.Add(tile);
                }
                if (NumChars < 256)
                {
                    // add all chars for safety reasons
                    for (int i = NumChars; i < 256; ++i)
                    {
                        SingleChar newChar = new SingleChar();
                        newChar.Data = new GR.Memory.ByteBuffer(8);
                        if (TileColorMode == ColorMode.PER_TILE_CELL)
                        {
                            newChar.Color = Data.ByteAt(offsetToCharAttribs + i) & 0x0f;
                        }
                        else
                        {
                            newChar.Color = CustomColor;
                        }

                        Characters.Add(newChar);
                    }
                }
            }
            else
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    Tile tile = new Tile();

                    tile.CharData.Resize((uint)(TileWidth * TileHeight * 2));
                    tile.ColorData.Resize((uint)(TileWidth * TileHeight));

                    Tiles.Add(tile);
                }

                if (isExpanded)
                {
                    byte curCharIndex = 0;
                    for (int i = 0; i < NumTiles; ++i)
                    {
                        for (int j = 0; j < TileWidth * TileHeight; ++j)
                        {
                            Tiles[i].CharData.SetU16At(j * 2, curCharIndex);
                            ++curCharIndex;
                        }
                    }
                }
                else
                {
                    // tile_data.      Size = NUM_TILES * TILE_WIDTH * TILE_HEIGHT bytes * 2 bytes. (only exists if CHAR_DATA is not "Expanded")
                    for (int i = 0; i < NumTiles; ++i)
                    {
                        for (int j = 0; j < TileWidth * TileHeight; ++j)
                        {
                            Tiles[i].CharData.SetU16At(j * 2, Data.UInt16At(offsetToTileData + i * TileWidth * TileHeight * 2 + j * 2));
                        }
                    }
                }
            }

            // TILE_COLOURS.   Size = NUM_TILES bytes (1 byte per tile = "RAM colour". only exists if COLOR_MODE = 1 (Per Tile)
            if (TileColorMode == ColorMode.PER_TILE)
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int y = 0; y < TileHeight; ++y)
                    {
                        for (int x = 0; x < TileWidth; ++x)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)(Data.ByteAt(offsetToTileColors + i) & 0x0f));
                        }
                    }
                }
            }
            else if (TileColorMode == ColorMode.PER_TILE_CELL)
            {
                // with V5 this actually means per character
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int y = 0; y < TileHeight; ++y)
                    {
                        for (int x = 0; x < TileWidth; ++x)
                        {
                            byte charColor = (byte)Characters[Tiles[i].CharData.ByteAt(2 * (x + y * TileWidth))].Color;
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, charColor);
                        }
                    }
                }
            }
            else if (TileColorMode == ColorMode.GLOBAL)
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int y = 0; y < TileHeight; ++y)
                    {
                        for (int x = 0; x < TileWidth; ++x)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)CustomColor);
                        }
                    }
                }
            }

            /*
             * else if ( TileColorMode == ColorMode.PER_TILE_CELL )
             * {
             * for ( int i = 0; i < NumTiles; ++i )
             * {
             *  for ( int y = 0; y < TileHeight; ++y )
             *  {
             *    for ( int x = 0; x < TileWidth; ++x )
             *    {
             *      Tiles[i].ColorData.SetU8At( x + y * TileWidth, (byte)( Data.ByteAt( offsetCellAttribs + i * TileWidth * TileHeight + x + y * TileHeight ) & 0x0f ) );
             *    }
             *  }
             * }
             * }*/

            // MAP_DATA.        Size =  MAP_WID x MAP_HEI bytes.
            // tile indices are now 16 bit! for now force 8bit

            //MapData = Data.SubBuffer( offsetMapData, MapWidth * MapHeight * 2 );

            MapData = new GR.Memory.ByteBuffer((uint)(MapWidth * MapHeight));

            for (int i = 0; i < MapHeight; ++i)
            {
                for (int j = 0; j < MapWidth; ++j)
                {
                    MapData.SetU8At(i * MapWidth + j, Data.ByteAt(offsetToMapData + 2 * (i * MapWidth + j)));
                }
            }
            return(true);
        }
예제 #11
0
        private bool LoadVersion4(GR.Memory.ByteBuffer Data)
        {
            BackgroundColor = Data.ByteAt(4);
            MultiColor1     = Data.ByteAt(5);
            MultiColor2     = Data.ByteAt(6);
            CustomColor     = Data.ByteAt(7);
            TileColorMode   = (ColorMode)Data.ByteAt(8);
            MultiColor      = (Data.ByteAt(9) != 0);

            NumChars   = Data.UInt16At(10) + 1;
            NumTiles   = Data.ByteAt(12) + 1;
            TileWidth  = Data.ByteAt(13);
            TileHeight = Data.ByteAt(14);

            MapWidth  = Data.UInt16At(15);
            MapHeight = Data.UInt16At(17);

            bool isExpanded = (Data.ByteAt(19) != 0);

            int offsetToCharAttribs = 24 + NumChars * 8;

            for (int charIndex = 0; charIndex < NumChars; ++charIndex)
            {
                SingleChar newChar = new SingleChar();
                newChar.Data  = Data.SubBuffer(24 + charIndex * 8, 8);
                newChar.Color = Data.ByteAt(offsetToCharAttribs + charIndex) & 0x0f;

                Characters.Add(newChar);
            }

            for (int i = 0; i < NumTiles; ++i)
            {
                Tile tile = new Tile();

                tile.CharData.Resize((uint)(TileWidth * TileHeight * 2));
                tile.ColorData.Resize((uint)(TileWidth * TileHeight));

                Tiles.Add(tile);
            }

            if (isExpanded)
            {
                byte curCharIndex = 0;
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int j = 0; j < TileWidth * TileHeight; ++j)
                    {
                        Tiles[i].CharData.SetU16At(j * 2, curCharIndex);
                        ++curCharIndex;
                    }
                }
            }
            else
            {
                // CELL_DATA.      Size = NUM_TILES * TILE_SIZE * TILE_SIZE bytes * 2 bytes. (only exists if CHAR_DATA is not "Expanded")
                int offsetCellData = 24 + NumChars * 8 + NumChars;
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int j = 0; j < TileWidth * TileHeight; ++j)
                    {
                        Tiles[i].CharData.SetU16At(j * 2, Data.UInt16At(offsetCellData + i * TileWidth * TileHeight * 2 + j * 2));
                    }
                }
            }
            // CELL_ATTRIBS.   Size = NUM_TILES * TILE_SIZE * TILE_SIZE bytes (exists for ALL modes)

            int offsetCellAttribs = 24 + NumChars * 8 + NumChars;

            if (!isExpanded)
            {
                offsetCellAttribs += NumTiles * TileWidth * TileHeight * 2;
            }
            for (int i = 0; i < NumTiles; ++i)
            {
                for (int y = 0; y < TileHeight; ++y)
                {
                    for (int x = 0; x < TileWidth; ++x)
                    {
                        if (TileColorMode == ColorMode.PER_TILE_CELL)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)(Data.ByteAt(offsetCellAttribs + i * TileWidth * TileHeight + x + y * TileHeight) & 0x0f));
                        }
                        else
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)CustomColor);
                        }
                    }
                }
            }

            // TILE_ATTRIBS.   Size = NUM_TILES bytes (1 byte per tile = "RAM colour". only exists if COLOR_MODE = 1 (Per Tile)
            int offsetTileAttribs = offsetCellAttribs + NumTiles * TileWidth * TileHeight;

            if (TileColorMode == ColorMode.PER_TILE)
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int y = 0; y < TileHeight; ++y)
                    {
                        for (int x = 0; x < TileWidth; ++x)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)(Data.ByteAt(offsetTileAttribs + i) & 0x0f));
                        }
                    }
                }
            }

            /*
             * if ( TileColorMode == ColorMode.PER_TILE_CELL )
             * {
             * for ( int i = 0; i < NumTiles; ++i )
             * {
             *  for ( int y = 0; y < TileHeight; ++y )
             *  {
             *    for ( int x = 0; x < TileWidth; ++x )
             *    {
             *      Tiles[i].ColorData.SetU8At( x + y * TileWidth, (byte)( Data.ByteAt( offsetCellAttribs + i * TileWidth * TileHeight + x + y * TileHeight ) & 0x0f ) );
             *    }
             *  }
             * }
             * }*/

            // MAP_DATA.        Size =  MAP_WID x MAP_HEI bytes.
            int offsetMapData = offsetTileAttribs;

            if (TileColorMode == ColorMode.PER_TILE)
            {
                offsetMapData += NumTiles;
            }

            MapData = Data.SubBuffer(offsetMapData, MapWidth * MapHeight);
            return(true);
        }
예제 #12
0
        public bool ReadFromBuffer(GR.Memory.ByteBuffer DataIn)
        {
            if (DataIn == null)
            {
                return(false);
            }
            GR.IO.MemoryReader memIn = DataIn.MemoryReader();

            uint   version         = memIn.ReadUInt32();
            string name            = memIn.ReadString();
            string charsetFilename = memIn.ReadString();

            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Color = memIn.ReadInt32();
            }
            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Mode = (Types.CharsetMode)memIn.ReadUInt8();
            }
            BackgroundColor = memIn.ReadInt32();
            MultiColor1     = memIn.ReadInt32();
            MultiColor2     = memIn.ReadInt32();


            for (int i = 0; i < 256; ++i)
            {
                int tileColor1 = memIn.ReadInt32();
                int tileColor2 = memIn.ReadInt32();
                int tileColor3 = memIn.ReadInt32();
                int tileColor4 = memIn.ReadInt32();
                int tileChar1  = memIn.ReadInt32();
                int tileChar2  = memIn.ReadInt32();
                int tileChar3  = memIn.ReadInt32();
                int tileChar4  = memIn.ReadInt32();
            }

            bool genericMulticolor = (memIn.ReadInt32() != 0);

            GR.Memory.ByteBuffer testbed = new GR.Memory.ByteBuffer();
            memIn.ReadBlock(testbed, 64);

            GR.Memory.ByteBuffer charsetData = new GR.Memory.ByteBuffer();
            memIn.ReadBlock(charsetData, 2048);

            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Data = charsetData.SubBuffer(i * 8, 8);
            }

            UsedTiles = memIn.ReadUInt32();

            ExportFilename = memIn.ReadString();
            string exportPathBlockTable  = memIn.ReadString();
            string exportPathCharset     = memIn.ReadString();
            string exportPathEditorTiles = memIn.ReadString();

            // categories
            Categories.Clear();
            int categoryCount = memIn.ReadInt32();

            for (int i = 0; i < categoryCount; ++i)
            {
                int    catKey  = memIn.ReadInt32();
                string catName = memIn.ReadString();

                Categories.Add(catName);
            }
            if (Categories.Count == 0)
            {
                // add default category
                Categories.Add("Uncategorized");
            }
            for (int i = 0; i < 256; ++i)
            {
                Characters[i].Category = memIn.ReadInt32();
                if ((Characters[i].Category < 0) ||
                    (Characters[i].Category >= Categories.Count))
                {
                    Characters[i].Category = 0;
                }
            }
            NumCharacters = memIn.ReadInt32();
            if (NumCharacters == 0)
            {
                NumCharacters = 256;
            }
            ShowGrid       = (memIn.ReadInt32() != 0);
            StartCharacter = memIn.ReadInt32();
            BGColor4       = memIn.ReadInt32();

            // playground
            int w = memIn.ReadInt32();
            int h = memIn.ReadInt32();

            if (w * h < 256)
            {
                w = 16;
                h = 16;
            }
            PlaygroundChars = new List <ushort>(w * h);
            for (int i = 0; i < w * h; ++i)
            {
                PlaygroundChars.Add(memIn.ReadUInt16());
            }
            return(true);
        }
        public void ConvertScreens(string BasePath, List <string> ProjectFiles)
        {
            var projects = new List <RetroDevStudio.Formats.GraphicScreenProject>();

            foreach (var file in ProjectFiles)
            {
                var project = new RetroDevStudio.Formats.GraphicScreenProject();

                project.ReadFromBuffer(GR.IO.File.ReadAllBytes(file));

                projects.Add(project);
            }


            int numChars = 0;

            foreach (var project in projects)
            {
                numChars += ((project.Image.Width + 7) / 8) * ((project.Image.Height + 7) / 8);
            }


            for (int i = 0; i < numChars; ++i)
            {
                m_Chars.Add(new RetroDevStudio.Formats.CharData());
            }

            int curCharOffset = 0;
            int projectIndex  = 0;

            foreach (var project in projects)
            {
                if (CheckForMCCharsetErrors(project, curCharOffset))
                {
                    Debug.Log("Found error in " + ProjectFiles[projectIndex]);
                    return;
                }
                curCharOffset += ((project.Image.Width + 7) / 8) * ((project.Image.Height + 7) / 8);
                ++projectIndex;
            }

            if (CheckForDuplicates())
            {
                // charset
                GR.Memory.ByteBuffer charSet = new GR.Memory.ByteBuffer();
                foreach (var charInfo in m_Chars)
                {
                    if (charInfo.Replacement == null)
                    {
                        charSet.Append(charInfo.Tile.Data);
                    }
                }
                GR.IO.File.WriteAllBytes(System.IO.Path.Combine(BasePath, "combined.chr"), charSet);

                // screens
                int charIndexOffset = 0;
                projectIndex = 0;
                foreach (var project in projects)
                {
                    // create screens from graphic
                    var screen = new RetroDevStudio.Formats.CharsetScreenProject();

                    int blockWidth  = ((project.Image.Width + 7) / 8);
                    int blockHeight = ((project.Image.Height + 7) / 8);

                    screen.SetScreenSize(blockWidth, blockHeight);
                    for (int y = 0; y < blockHeight; ++y)
                    {
                        for (int x = 0; x < blockWidth; ++x)
                        {
                            var charData     = m_Chars[charIndexOffset + x + y * blockWidth];
                            var origCharData = charData;
                            while (charData.Replacement != null)
                            {
                                charData = charData.Replacement;
                            }

                            screen.Chars[x + y * blockWidth] = (ushort)((origCharData.Tile.CustomColor << 8) + charData.Index);
                            screen.Mode = project.MultiColor ? RetroDevStudio.TextMode.COMMODORE_40_X_25_MULTICOLOR : RetroDevStudio.TextMode.COMMODORE_40_X_25_HIRES;
                            screen.CharSet.Colors.MultiColor1     = project.Colors.MultiColor1;
                            screen.CharSet.Colors.MultiColor2     = project.Colors.MultiColor2;
                            screen.CharSet.Colors.BackgroundColor = project.Colors.BackgroundColor;
                        }
                    }
                    screen.CharSet = new RetroDevStudio.Formats.CharsetProject();
                    screen.CharSet.Colors.BackgroundColor = project.Colors.BackgroundColor;
                    screen.CharSet.Colors.MultiColor1     = project.Colors.MultiColor1;
                    screen.CharSet.Colors.MultiColor2     = project.Colors.MultiColor2;

                    for (uint c = 0; c < charSet.Length / 8; ++c)
                    {
                        screen.CharSet.Characters[(int)c].Tile.Data        = charSet.SubBuffer((int)c * 8, 8);
                        screen.CharSet.Characters[(int)c].Tile.CustomColor = 9;
                    }

                    string origFile = System.IO.Path.GetFileNameWithoutExtension(ProjectFiles[projectIndex]);

                    GR.IO.File.WriteAllBytes(System.IO.Path.Combine(BasePath, origFile + ".charscreen"), screen.SaveToBuffer());

                    ++projectIndex;
                    charIndexOffset += blockWidth * blockHeight;
                }
            }
        }
예제 #14
0
        public bool LoadFromFile(GR.Memory.ByteBuffer Data)
        {
            Characters.Clear();
            MapData.Clear();

            if ((Data == null) ||
                (Data.Length < 24) ||
                (Data.ByteAt(0) != 'C') ||
                (Data.ByteAt(1) != 'T') ||
                (Data.ByteAt(2) != 'M'))
            {
                // not a valid CTM file
                return(false);
            }
            int version = Data.ByteAt(3);

            if (version != 4)
            {
                System.Windows.Forms.MessageBox.Show("Currently only version 4 of Charpad project files is supported. Sorry!", "Unsupported version " + version);
                return(false);
            }

            BackgroundColor = Data.ByteAt(4);
            MultiColor1     = Data.ByteAt(5);
            MultiColor2     = Data.ByteAt(6);
            CustomColor     = Data.ByteAt(7);
            TileColorMode   = (ColorMode)Data.ByteAt(8);
            MultiColor      = (Data.ByteAt(9) != 0);

            NumChars   = Data.UInt16At(10) + 1;
            NumTiles   = Data.ByteAt(12) + 1;
            TileWidth  = Data.ByteAt(13);
            TileHeight = Data.ByteAt(14);

            MapWidth  = Data.UInt16At(15);
            MapHeight = Data.UInt16At(17);

            bool isExpanded = (Data.ByteAt(19) != 0);

            int offsetToCharAttribs = 24 + NumChars * 8;

            for (int charIndex = 0; charIndex < NumChars; ++charIndex)
            {
                SingleChar newChar = new SingleChar();
                newChar.Data  = Data.SubBuffer(24 + charIndex * 8, 8);
                newChar.Color = Data.ByteAt(offsetToCharAttribs + charIndex) & 0x0f;

                Characters.Add(newChar);
            }

            for (int i = 0; i < NumTiles; ++i)
            {
                Tile tile = new Tile();

                tile.CharData.Resize((uint)(TileWidth * TileHeight * 2));
                tile.ColorData.Resize((uint)(TileWidth * TileHeight));

                Tiles.Add(tile);
            }

            if (isExpanded)
            {
                byte curCharIndex = 0;
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int j = 0; j < TileWidth * TileHeight; ++j)
                    {
                        Tiles[i].CharData.SetU16At(j * 2, curCharIndex);
                        ++curCharIndex;
                    }
                }
            }
            else
            {
                // CELL_DATA.      Size = NUM_TILES * TILE_SIZE * TILE_SIZE bytes * 2 bytes. (only exists if CHAR_DATA is not "Expanded")
                int offsetCellData = 24 + NumChars * 8 + NumChars;
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int j = 0; j < TileWidth * TileHeight; ++j)
                    {
                        Tiles[i].CharData.SetU16At(j * 2, Data.UInt16At(offsetCellData + i * TileWidth * TileHeight * 2 + j * 2));
                    }
                }
            }
            // CELL_ATTRIBS.   Size = NUM_TILES * TILE_SIZE * TILE_SIZE bytes (exists for ALL modes)

            int offsetCellAttribs = 24 + NumChars * 8 + NumChars;

            if (!isExpanded)
            {
                offsetCellAttribs += NumTiles * TileWidth * TileHeight * 2;
            }
            for (int i = 0; i < NumTiles; ++i)
            {
                for (int y = 0; y < TileHeight; ++y)
                {
                    for (int x = 0; x < TileWidth; ++x)
                    {
                        if (TileColorMode == ColorMode.PER_TILE_CELL)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)(Data.ByteAt(offsetCellAttribs + i * TileWidth * TileHeight + x + y * TileHeight) & 0x0f));
                        }
                        else
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)CustomColor);
                        }
                    }
                }
            }

            // TILE_ATTRIBS.   Size = NUM_TILES bytes (1 byte per tile = "RAM colour". only exists if COLOR_MODE = 1 (Per Tile)
            int offsetTileAttribs = offsetCellAttribs + NumTiles * TileWidth * TileHeight;

            if (TileColorMode == ColorMode.PER_TILE)
            {
                for (int i = 0; i < NumTiles; ++i)
                {
                    for (int y = 0; y < TileHeight; ++y)
                    {
                        for (int x = 0; x < TileWidth; ++x)
                        {
                            Tiles[i].ColorData.SetU8At(x + y * TileWidth, (byte)(Data.ByteAt(offsetTileAttribs + i) & 0x0f));
                        }
                    }
                }
            }

            /*
             * if ( TileColorMode == ColorMode.PER_TILE_CELL )
             * {
             * for ( int i = 0; i < NumTiles; ++i )
             * {
             *  for ( int y = 0; y < TileHeight; ++y )
             *  {
             *    for ( int x = 0; x < TileWidth; ++x )
             *    {
             *      Tiles[i].ColorData.SetU8At( x + y * TileWidth, (byte)( Data.ByteAt( offsetCellAttribs + i * TileWidth * TileHeight + x + y * TileHeight ) & 0x0f ) );
             *    }
             *  }
             * }
             * }*/

            // MAP_DATA.        Size =  MAP_WID x MAP_HEI bytes.
            int offsetMapData = offsetTileAttribs;

            if (TileColorMode == ColorMode.PER_TILE)
            {
                offsetMapData += NumTiles;
            }

            MapData = Data.SubBuffer(offsetMapData, MapWidth * MapHeight);
            return(true);
        }