diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index f87a9b1..cedf699 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -10,17 +10,18 @@ namespace ComSquare::PPU { - Background::Background(ComSquare::PPU::PPU &_ppu, int backGroundNumber, bool hasPriority): + Background::Background(ComSquare::PPU::PPU &ppu, int backGroundNumber, bool hasPriority): _priority(hasPriority), - _bgNumber(backGroundNumber) + _bgNumber(backGroundNumber), + _ppu(ppu) { - _cgram = _ppu.cgram; - _vram = _ppu.vram; - _bpp = _ppu.getBPP(backGroundNumber); - _characterSize = _ppu.getCharacterSize(backGroundNumber); - _tileMapStartAddress = _ppu.getTileMapStartAddress(backGroundNumber); - _tilesetAddress = _ppu.getTilesetAddress(backGroundNumber); - _tileMaps = _ppu.getBackgroundSize(backGroundNumber); + _cgram = ppu.cgram; + _vram = ppu.vram; + _bpp = ppu.getBPP(backGroundNumber); + _characterSize = ppu.getCharacterSize(backGroundNumber); + _tileMapStartAddress = ppu.getTileMapStartAddress(backGroundNumber); + _tilesetAddress = ppu.getTilesetAddress(backGroundNumber); + _tileMaps = ppu.getBackgroundSize(backGroundNumber); _directColor = false; _highRes = false; } @@ -82,9 +83,17 @@ namespace ComSquare::PPU std::vector Background::getPalette(int nbPalette) { uint8_t nbColors = std::pow(2, this->_bpp); - uint16_t addr = nbPalette * this->_bpp * this->_bpp * 2; + uint16_t addr = nbPalette * this->_bpp * this->_bpp * 2; // 2 because it's 2 addr for 1 color std::vector palette(nbColors); + switch (this->_ppu.getBgMode()) { + case 0: + addr += this->_bgNumber * (4 * 8) * 2; + break; + default: + break; + } + for (int i = 0; i < nbColors; i++) { palette[i] = this->_cgram->read_internal(addr); palette[i] += this->_cgram->read_internal(addr + 1) << 8U; diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index de9ae95..907c9fd 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -25,6 +25,7 @@ namespace ComSquare::PPU #define TILE_PIXEL_HEIGHT 8U #define TILE_SIZE 8 #define NB_TILE_PER_ROW 16 + private: Vector2 _tileMaps; Vector2 _characterSize; @@ -35,6 +36,7 @@ namespace ComSquare::PPU uint16_t _tilesetAddress; bool _priority; int _bgNumber; + ComSquare::PPU::PPU &_ppu; std::shared_ptr _vram; std::shared_ptr _cgram; @@ -59,8 +61,6 @@ namespace ComSquare::PPU //! @param offset The rendering offeset in pixels void drawBasicTileMap(uint16_t baseAddress, Vector2 offset); public: - // TODO getter setter for priority and bgNumber - Vector2 backgroundSize; std::array, 1024> buffer; Background(ComSquare::PPU::PPU &_ppu, int backGroundNumber, bool hasPriority); diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index ca69803..725a89e 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -381,7 +381,7 @@ namespace ComSquare::PPU } } - uint16_t PPU::getVramAddress() + uint16_t PPU::getVramAddress() const { uint16_t vanillaAddress = this->_registers._vmadd.vmadd; @@ -419,7 +419,7 @@ namespace ComSquare::PPU return "PPU"; } - std::string PPU::getValueName(uint24_t addr) + std::string PPU::getValueName(uint24_t addr) const { switch (addr) { case PpuRegisters::inidisp: @@ -560,7 +560,7 @@ namespace ComSquare::PPU return Ppu; } - bool PPU::isDebugger() + bool PPU::isDebugger() const { return false; } @@ -570,7 +570,7 @@ namespace ComSquare::PPU return this->cgram->read_internal(addr); } - int PPU::getBPP(int bgNumber) + int PPU::getBPP(int bgNumber) const { switch (this->_registers._bgmode.bgMode) { case 0: @@ -604,22 +604,22 @@ namespace ComSquare::PPU } } - Vector2 PPU::getCharacterSize(int bgNumber) + Vector2 PPU::getCharacterSize(int bgNumber) const { Vector2 characterSize(8, 8); - //this wont work for modes 5 and 6 and will be reworked + //TODO this wont work for modes 5 and 6 and will be reworked if (this->_registers._bgmode.raw & (1U << (3 + bgNumber))) characterSize = {16, 16}; return characterSize; } - uint16_t PPU::getTileMapStartAddress(int bgNumber) + uint16_t PPU::getTileMapStartAddress(int bgNumber) const { return this->_registers._bgsc[bgNumber - 1].tilemapAddress << 11U; } - uint16_t PPU::getTilesetAddress(int bgNumber) + uint16_t PPU::getTilesetAddress(int bgNumber) const { uint16_t baseAddress = this->_registers._bgnba[bgNumber > 2].raw; @@ -628,7 +628,7 @@ namespace ComSquare::PPU return baseAddress; } - Vector2 PPU::getBackgroundSize(int bgNumber) + Vector2 PPU::getBackgroundSize(int bgNumber) const { Vector2 backgroundSize(0,0); @@ -637,7 +637,7 @@ namespace ComSquare::PPU return backgroundSize; } - void PPU::renderMainAndSubScreen(void) + void PPU::renderMainAndSubScreen() { uint16_t colorPalette; // should only render backgrounds needed (depending of th bgMode) @@ -654,80 +654,80 @@ namespace ComSquare::PPU // the starting palette index isn't implemented switch (this->_registers._bgmode.bgMode) { case 0: - this->addToMainSubScreen(this->_backgrounds[bgName::bg4NoPriority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg3NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg4NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3NoPriority]); //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg4Priority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg3Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg4Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 1: - this->addToMainSubScreen(this->_backgrounds[bgName::bg3NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3NoPriority]); //sprites priority 0 if (!this->_registers._bgmode.mode1Bg3PriorityBit) - this->addToMainSubScreen(this->_backgrounds[bgName::bg3Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 if (this->_registers._bgmode.mode1Bg3PriorityBit) - this->addToMainSubScreen(this->_backgrounds[bgName::bg3Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); break; case 2: - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 3: - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 4: - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 5: - this->addToMainSubScreen(this->_backgrounds[bgName::bg2NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[bgName::bg2Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 6: //sprites priority 0 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1NoPriority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 1 //sprites priority 2 - this->addToMainSubScreen(this->_backgrounds[bgName::bg1Priority]); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 7: @@ -755,4 +755,9 @@ namespace ComSquare::PPU if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) this->add_buffer(this->_subScreen, bg.buffer); } + + int PPU::getBgMode() const + { + return this->_registers._bgmode.bgMode; + } } \ No newline at end of file diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 2719290..3d8d3bc 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -25,7 +25,7 @@ namespace ComSquare::PPU { class Background; - enum bgName { + enum BgName { bg1NoPriority = 0, bg1Priority, bg2NoPriority, @@ -594,30 +594,32 @@ namespace ComSquare::PPU //! @param The number of cycles to update. virtual void update(unsigned cycles); //! @brief Give the Vram Address with the right Address remapping - uint16_t getVramAddress(); + uint16_t getVramAddress() const; //! @brief Give the name of the Address register (used for debug) - std::string getValueName(uint24_t addr); + std::string getValueName(uint24_t addr) const; //! @brief Return true if the CPU is overloaded with debugging features. - virtual bool isDebugger(); + virtual bool isDebugger() const; //! @brief Allow others components to read the CGRAM uint16_t cgramRead(uint16_t addr); //! @brief get the bpp depending of the bgNumber and the Bgmode - int getBPP(int bgNumber); + int getBPP(int bgNumber) const; //! @brief Give the correct character size depending of the bgMode - Vector2 getCharacterSize(int bgNumber); + Vector2 getCharacterSize(int bgNumber) const; //! @brief Give the address where the tilemap starts - uint16_t getTileMapStartAddress(int bgNumber); + uint16_t getTileMapStartAddress(int bgNumber) const; //! @brief Give the address to find the correct tileset for a given x and y - uint16_t getTilesetAddress(int bgNumber); + uint16_t getTilesetAddress(int bgNumber) const; //! @brief Give the number of tilemaps to be rendered - Vector2 getBackgroundSize(int bgNumber); + Vector2 getBackgroundSize(int bgNumber) const; //! @brief Render the Main and sub screen correctly - void renderMainAndSubScreen(void); + void renderMainAndSubScreen(); //! @brief Add a bg buffer to another buffer template void add_buffer(std::array, DEST_SIZE> &bufferDest, std::array, SRC_SIZE> &bufferSrc); //! @brief Add a bg to the sub and/or main screen void addToMainSubScreen(Background &bg); + //! @brief Get the current background Mode + int getBgMode() const; }; }