public void Enqueue8Pixels(int[] pixelLine, TileAttributes tileAttributes)
 {
     foreach (var p in pixelLine)
     {
         Pixels.Enqueue(p);
         _palettes.Enqueue(_registers.Get(GpuRegister.Bgp));
         _pixelType.Enqueue(0);
     }
 }
Example #2
0
        private int GetTileData(int tileId, int line, int byteNumber, int tileDataAddress, bool signed,
                                TileAttributes attr, int tileHeight)
        {
            var effectiveLine = attr.IsYFlip() ? tileHeight - 1 - line : line;
            var tileAddress   = signed ? tileDataAddress + ToSigned(tileId) * 0x10 : tileDataAddress + tileId * 0x10;

            var videoRam = (attr.GetBank() == 0 || !_gbc) ? _videoRam0 : _videoRam1;

            return(videoRam.GetByte(tileAddress + effectiveLine * 2 + byteNumber));
        }
        public void SetOverlay(int[] pixelLine, int offset, TileAttributes flags, int oamIndex)
        {
            var priority       = flags.IsPriority();
            var overlayPalette = _registers.Get(flags.GetDmgPalette());

            for (var j = offset; j < pixelLine.Length; j++)
            {
                var p = pixelLine[j];
                var i = j - offset;

                if (_pixelType.Get(i) == 1)
                {
                    continue;
                }

                if (priority && Pixels.Get(i) == 0 || !priority && p != 0)
                {
                    Pixels.Set(i, p);
                    _palettes.Set(i, overlayPalette);
                    _pixelType.Set(i, 1);
                }
            }
        }
Example #4
0
        public void Tick()
        {
            if (_fetchingDisabled && _state == State.ReadTileId)
            {
                if (_fifo.GetLength() <= 8)
                {
                    _fifo.Enqueue8Pixels(EmptyPixelLine, _tileAttributes);
                }

                return;
            }

            if (--_divider == 0)
            {
                _divider = 2;
            }
            else
            {
                return;
            }

stateSwitch:

            switch (_state)
            {
            case State.ReadTileId:
                _tileId = _videoRam0.GetByte(_mapAddress + _xOffset);

                _tileAttributes = _gbc
                            ? TileAttributes.ValueOf(_videoRam1.GetByte(_mapAddress + _xOffset))
                            : TileAttributes.Empty;

                _state = State.ReadData1;
                break;

            case State.ReadData1:
                _tileData1 = GetTileData(_tileId, _tileLine, 0, _tileDataAddress, _tileIdSigned, _tileAttributes, 8);
                _state     = State.ReadData2;
                break;

            case State.ReadData2:
                _tileData2 = GetTileData(_tileId, _tileLine, 1, _tileDataAddress, _tileIdSigned, _tileAttributes, 8);
                _state     = State.Push;
                goto stateSwitch;     // Sorry mum

            case State.Push:
                if (_fifo.GetLength() <= 8)
                {
                    _fifo.Enqueue8Pixels(Zip(_tileData1, _tileData2, _tileAttributes.IsXFlip()), _tileAttributes);
                    _xOffset = (_xOffset + 1) % 0x20;
                    _state   = State.ReadTileId;
                }

                break;

            case State.ReadSpriteTileId:
                _tileId = _oemRam.GetByte(_sprite.GetAddress() + 2);
                _state  = State.ReadSpriteFlags;
                break;

            case State.ReadSpriteFlags:
                _spriteAttributes = TileAttributes.ValueOf(_oemRam.GetByte(_sprite.GetAddress() + 3));
                _state            = State.ReadSpriteData1;
                break;

            case State.ReadSpriteData1:
                if (_lcdc.GetSpriteHeight() == 16)
                {
                    _tileId &= 0xfe;
                }

                _tileData1 = GetTileData(_tileId, _spriteTileLine, 0, 0x8000, false, _spriteAttributes,
                                         _lcdc.GetSpriteHeight());
                _state = State.ReadSpriteData2;
                break;

            case State.ReadSpriteData2:
                _tileData2 = GetTileData(_tileId, _spriteTileLine, 1, 0x8000, false, _spriteAttributes,
                                         _lcdc.GetSpriteHeight());
                _state = State.PushSprite;
                break;

            case State.PushSprite:
                _fifo.SetOverlay(Zip(_tileData1, _tileData2, _spriteAttributes.IsXFlip()), _spriteOffset,
                                 _spriteAttributes, _spriteOamIndex);
                _state = State.ReadTileId;
                break;
            }
        }