#pragma once #include "stdafx.h" #include "GbTypes.h" #include "../Utilities/ISerializable.h" class Console; class Gameboy; class GbMemoryManager; class GbDmaController; class GbPpu : public ISerializable { private: Console* _console = nullptr; Gameboy* _gameboy = nullptr; GbPpuState _state = {}; GbMemoryManager* _memoryManager = nullptr; GbDmaController* _dmaController = nullptr; uint16_t* _outputBuffers[2] = {}; uint16_t* _currentBuffer = nullptr; uint16_t* _eventViewerBuffers[2] = {}; uint16_t* _currentEventViewerBuffer = nullptr; EvtColor _evtColor = EvtColor::HBlank; int16_t _prevDrawnPixels = 0; uint8_t* _vram = nullptr; uint8_t* _oam = nullptr; uint64_t _lastFrameTime = 0; GbPpuFifo _bgFifo; GbPpuFetcher _bgFetcher; GbPpuFifo _oamFifo; GbPpuFetcher _oamFetcher; int16_t _drawnPixels = 0; uint8_t _fetchColumn = 0; bool _fetchWindow = false; int16_t _windowCounter = -1; uint8_t _latchWindowX = 0; uint8_t _latchWindowY = 0; bool _latchWindowEnabled = false; int16_t _fetchSprite = -1; uint8_t _spriteCount = 0; uint8_t _spriteX[10] = {}; uint8_t _spriteIndexes[10] = {}; bool _isFirstFrame = true; bool _rendererIdle = false; __forceinline void ProcessPpuCycle(); __forceinline void ExecCycle(); __forceinline void ProcessVblankScanline(); void ProcessFirstScanlineAfterPowerOn(); __forceinline void ProcessVisibleScanline(); __forceinline void RunDrawCycle(); __forceinline void RunSpriteEvaluation(); void ResetRenderer(); void ClockSpriteFetcher(); void FindNextSprite(); __forceinline void ClockTileFetcher(); __forceinline void PushSpriteToPixelFifo(); __forceinline void PushTileToPixelFifo(); void UpdateStatIrq(); void SendFrame(); void UpdatePalette(); void WriteCgbPalette(uint8_t& pos, uint16_t* pal, bool autoInc, uint8_t value); public: virtual ~GbPpu(); void Init(Console* console, Gameboy* gameboy, GbMemoryManager* memoryManager, GbDmaController* dmaController, uint8_t* vram, uint8_t* oam); GbPpuState GetState(); uint16_t* GetOutputBuffer(); uint16_t* GetEventViewerBuffer(); uint16_t* GetPreviousEventViewerBuffer(); uint32_t GetFrameCount(); uint8_t GetScanline(); uint16_t GetCycle(); bool IsLcdEnabled(); bool IsCgbEnabled(); PpuMode GetMode(); void Exec(); uint8_t Read(uint16_t addr); void Write(uint16_t addr, uint8_t value); bool IsVramReadAllowed(); bool IsVramWriteAllowed(); uint8_t ReadVram(uint16_t addr); uint8_t PeekVram(uint16_t addr); void WriteVram(uint16_t addr, uint8_t value); bool IsOamReadAllowed(); bool IsOamWriteAllowed(); uint8_t ReadOam(uint8_t addr); uint8_t PeekOam(uint8_t addr); void WriteOam(uint8_t addr, uint8_t value, bool forDma); uint8_t ReadCgbRegister(uint16_t addr); void WriteCgbRegister(uint16_t addr, uint8_t value); void Serialize(Serializer& s) override; };