public bool Tick() { _fetcher.Tick(); if (_lcdc.IsBgAndWindowDisplay() || _gbc) { if (_fifo.GetLength() <= 8) { return(true); } if (_droppedPixels < _r.Get(GpuRegister.Scx) % 8) { _fifo.DropPixel(); _droppedPixels++; return(true); } if (!_window && _lcdc.IsWindowDisplay() && _r.Get(GpuRegister.Ly) >= _r.Get(GpuRegister.Wy) && _x == _r.Get(GpuRegister.Wx) - 7) { _window = true; StartFetchingWindow(); return(true); } } if (_lcdc.IsObjDisplay()) { if (_fetcher.SpriteInProgress()) { return(true); } var spriteAdded = false; for (var i = 0; i < _sprites.Length; i++) { var s = _sprites[i]; if (s == null) { continue; } if (_x == 0 && s.GetX() < 8) { _fetcher.AddSprite(s, 8 - s.GetX(), i); spriteAdded = true; _sprites[i] = null; } else if (s.GetX() - 8 == _x) { _fetcher.AddSprite(s, 0, i); spriteAdded = true; _sprites[i] = null; } if (spriteAdded) { return(true); } } } _fifo.PutPixelToScreen(); if (++_x == 160) { return(false); } return(true); }
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; } }