예제 #1
0
 public Nametable(ChrMapper mapper)
 {
     this.bitmap  = new PaletteBitmap(screenWidth * 8u, screenHeight * 8u);
     this.mapper  = mapper;
     this.ppuAddr = 0x0000;
     this.SetDirection(AccessDirection.Horizontal);
     bitmap.AddColor(0x00000000);                                // Transparent
 }
예제 #2
0
 private void GenerateTile(PaletteBitmap bitmap, ChrMapper mapper, uint row, uint col, byte tile)
 {
     for (uint tileY = 0; tileY < 8; tileY++)
     {
         uint drawY = (uint)(row * 8 + tileY);
         for (uint tileX = 0; tileX < 8; tileX++)
         {
             uint drawX = col * 8 + tileX;
             byte color = mapper.GetPixel(tile, tileX, tileY);
             bitmap.SetPixel(drawX, drawY, (byte)(color + 1));
         }
     }
 }
예제 #3
0
        private IVisualization2d GenerateBitmap(ReadOnlyDictionary <string, object> parms)
        {
            int  tileoffset = Util.GetFromObjDict(parms, P_TILEOFFSET, 0);
            int  width      = Util.GetFromObjDict(parms, P_WIDTH, 1);
            int  height     = Util.GetFromObjDict(parms, P_HEIGHT, 1);
            int  chroffset  = Util.GetFromObjDict(parms, P_CHROFFSET, 0);
            int  chipoffset = Util.GetFromObjDict(parms, P_CHIPOFFSET, 0);
            int  chrbank1   = Util.GetFromObjDict(parms, P_CHRBANK1, 0);
            int  chrbank2   = Util.GetFromObjDict(parms, P_CHRBANK2, 1);
            int  chrbank3   = Util.GetFromObjDict(parms, P_CHRBANK3, 2);
            int  chrbank4   = Util.GetFromObjDict(parms, P_CHRBANK4, 3);
            int  palette1   = Util.GetFromObjDict(parms, P_PALETTE1, 0x0F);
            int  palette2   = Util.GetFromObjDict(parms, P_PALETTE2, 0x00);
            int  palette3   = Util.GetFromObjDict(parms, P_PALETTE3, 0x10);
            int  palette4   = Util.GetFromObjDict(parms, P_PALETTE4, 0x30);
            bool vertical   = Util.GetFromObjDict(parms, P_VERTICAL, false);

            int[] bank = new int[4] {
                chrbank1, chrbank2, chrbank3, chrbank4
            };
            int[] palette = new int[4] {
                palette1, palette2, palette3, palette4
            };
            ChrMapper mapper = null;

            // Check parameters.
            try{
                {                       // tile
                    int lastAddress = tileoffset + width * height - 1;
                    if ((tileoffset < 0) || (lastAddress >= this.mFileData.Length))
                    {
                        this.mAppRef.ReportError("Invalid parameter");
                        return(null);
                    }
                }
                {                                         // bank
                    int lastAddress = chroffset + 0x03FF; // chr = [0, 0, 0, 0] -> 0x1000 / 4 - 1 = 0x03FF
                    if ((chroffset < 0) || (lastAddress >= this.mFileData.Length))
                    {
                        this.mAppRef.ReportError("Invalid parameter");
                        return(null);
                    }
                }
                // palette
                for (int i = 0; i < palette.Length; i++)
                {
                    int color = palette[i];
                    if (color >= NesPalette.Length)
                    {
                        this.mAppRef.ReportError("Invalid parameter");
                        return(null);
                    }
                }
                // Copy CHR data.
                mapper = new ChrMapper(this.mFileData, chroffset, bank);
            }
            catch {
                this.mAppRef.ReportError("Invalid parameter");
                return(null);
            }

            // Set palette.
            PaletteBitmap bitmap = new PaletteBitmap((uint)(width * 8), (uint)(height * 8));

            bitmap.AddColor(0x00000000);                                // Transparent
            for (int i = 0; i < palette.Length; i++)
            {
                int index = palette[i];
                if (index >= 0)
                {
                    UInt32 color = 0xFF000000U | (UInt32)NesPalette[index];
                    bitmap.AddColor((int)color);                        // ARGB
                }
                else
                {
                    bitmap.AddColor(0x00000000);                        // Transparent
                }
            }

            // Convert to pixels.
            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    int address;
                    if (!vertical)
                    {
                        // Horizontal
                        address = tileoffset + (row * width) + col;
                    }
                    else
                    {
                        // Vertical
                        address = tileoffset + (col * height) + row;
                    }
                    byte tile = (byte)(this.mFileData[address] + chipoffset);
                    this.GenerateTile(bitmap, mapper, (uint)row, (uint)col, tile);
                }
            }

            return(bitmap.Bitmap);
        }
예제 #4
0
        private IVisualization2d GenerateBitmap(ReadOnlyDictionary <string, object> parms)
        {
            int tileoffset = Util.GetFromObjDict(parms, P_DATAOFFSET, 0);
            int chroffset  = Util.GetFromObjDict(parms, P_CHROFFSET, 0);
            int chrbank1   = Util.GetFromObjDict(parms, P_CHRBANK1, 0);
            int chrbank2   = Util.GetFromObjDict(parms, P_CHRBANK2, 1);
            int chrbank3   = Util.GetFromObjDict(parms, P_CHRBANK3, 2);
            int chrbank4   = Util.GetFromObjDict(parms, P_CHRBANK4, 3);
            int palette1   = Util.GetFromObjDict(parms, P_PALETTE1, 0x0F);
            int palette2   = Util.GetFromObjDict(parms, P_PALETTE2, 0x00);
            int palette3   = Util.GetFromObjDict(parms, P_PALETTE3, 0x10);
            int palette4   = Util.GetFromObjDict(parms, P_PALETTE4, 0x30);

            int[] bank = new int[4] {
                chrbank1, chrbank2, chrbank3, chrbank4
            };
            int[] palette = new int[4] {
                palette1, palette2, palette3, palette4
            };
            ChrMapper mapper = null;

            // Check parameters.
            try{
                {                                         // bank
                    int lastAddress = chroffset + 0x03FF; // chr = [0, 0, 0, 0] -> 0x1000 / 4 - 1 = 0x03FF
                    if ((chroffset < 0) || (lastAddress >= this.mFileData.Length))
                    {
                        this.mAppRef.ReportError("Invalid parameter");
                        return(null);
                    }
                }
                // palette
                for (int i = 0; i < palette.Length; i++)
                {
                    int color = palette[i];
                    if (color >= Nes.Palette.Length)
                    {
                        this.mAppRef.ReportError("Invalid parameter");
                        return(null);
                    }
                }
                // Copy CHR data.
                mapper = new ChrMapper(this.mFileData, chroffset, bank);
            }
            catch {
                this.mAppRef.ReportError("Invalid parameter");
                return(null);
            }

            // Create virtual nametable.
            Nametable nametable = new Nametable(mapper);

            // Set palette.
            for (int i = 0; i < palette.Length; i++)
            {
                nametable.AddColor(palette[i]);
            }

            // Convert to pixels.
            try{
                int index = tileoffset;
                while (true)
                {
                    byte addrHigh = this.mFileData[index++];
                    if ((addrHigh == 0x00) || (addrHigh >= 0x80))                       // Invalid address
                    {
                        break;
                    }
                    byte addrLow     = this.mFileData[index++];
                    byte length      = this.mFileData[index++];
                    bool isVertical  = (length & 0x80) != 0;
                    bool isSolid     = (length & 0x40) != 0;
                    int  writeLength = (length & 0x3F);

                    int addr = (addrHigh << 8) | addrLow;
                    Nametable.AccessDirection direction = (isVertical)? Nametable.AccessDirection.Vertical : Nametable.AccessDirection.Horizontal;
                    nametable.SetAddress((UInt16)addr);
                    nametable.SetDirection(direction);

                    if (!isSolid)
                    {
                        for (int i = 0; i < writeLength; i++)
                        {
                            byte value = this.mFileData[index++];
                            nametable.Write(value);
                        }
                    }
                    else
                    {
                        byte value = this.mFileData[index++];
                        for (int i = 0; i < writeLength; i++)
                        {
                            nametable.Write(value);
                        }
                    }
                }
            }
            catch {
                this.mAppRef.ReportError("Invalid parameter");
                return(null);
            }

            return(nametable.Bitmap);
        }