public void Enqueue8Pixels(int[] pixelLine, TileAttributes tileAttributes) { foreach (var p in pixelLine) { Pixels.Enqueue(p); _palettes.Enqueue(_registers.Get(GpuRegister.Bgp)); _pixelType.Enqueue(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); } } }
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; } }