From 358977ff06aed0a2619051b64b1f2962e13bf835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 00:20:53 +0200 Subject: [PATCH 01/41] remiove unused add_buffer function --- sources/PPU/PPU.hpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index a96dfa7..6bf913b 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -647,20 +647,6 @@ namespace ComSquare::PPU Vector2 getBgScroll(int bgNumber) const; //! @brief Allow to look the value of each write register (used by Register debugger) const Registers &getWriteRegisters() const; - - template - void add_buffer(const std::array, SRC_SIZE_X> &buffer, - const Vector2 &offset = {0, 0}) - { - for (auto &i : this->_screen) - i.fill(0XFF); - for (unsigned long i = 0; i < buffer.size(); i++) { - for (unsigned long j = 0; j < buffer[i].size(); j++) { - if (buffer[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness - this->_screen[i + offset.x][j + offset.y] = buffer[i][j]; - } - } - } }; } #endif //COMSQUARE_PPU_HPP From 5b900da44f3c31e2b9ccc721a9496b8a1d852f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 01:38:51 +0200 Subject: [PATCH 02/41] modif addBuffer but PPU need x and y cleanup seriously --- sources/PPU/Background.cpp | 1 + sources/PPU/PPU.cpp | 10 +++++----- sources/PPU/PPU.hpp | 7 +++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index 443c755..e7c3dd2 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -92,6 +92,7 @@ namespace ComSquare::PPU Utils::VFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); for (int i = 0; i < this->_characterNbPixels.y; i++) { for (int j = 0; j < this->_characterNbPixels.x; j++) { + //std::copy(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.x, this->buffer[pos.x].begin() ) this->buffer[pos.x][pos.y] = this->_tileBuffer[i][j]; pos.x++; } diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index b6fe012..703b8f5 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - //Utils::Debug::populateEnvironment(*this, 0); + Utils::Debug::populateEnvironment(*this, 0); } uint8_t PPU::read(uint24_t addr) @@ -310,8 +310,8 @@ namespace ComSquare::PPU (void)cycles; this->renderMainAndSubScreen(); - this->add_buffer(this->_screen, this->_subScreen); - this->add_buffer(this->_screen, this->_mainScreen); + this->addBuffer(this->_screen, this->_subScreen); + this->addBuffer(this->_screen, this->_mainScreen); //this->_backgrounds[2].renderBackground(); //add_buffer(this->_screen, this->_backgrounds[2].buffer); for (unsigned long i = 0; i < this->_screen.size(); i++) { @@ -656,9 +656,9 @@ namespace ComSquare::PPU void PPU::addToMainSubScreen(Background &bg) { if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) - this->add_buffer(this->_mainScreen, bg.buffer); + this->addBuffer(this->_mainScreen, bg.buffer); if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) - this->add_buffer(this->_subScreen, bg.buffer); + this->addBuffer(this->_subScreen, bg.buffer); } int PPU::getBgMode() const diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 6bf913b..2a42e7d 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -11,6 +11,7 @@ #include "Renderer/IRenderer.hpp" #include "Ram/Ram.hpp" #include "Models/Vector2.hpp" +#include #include "Background.hpp" #include "PPUUtils.hpp" #include "Debugger/TileViewer/RAMTileRenderer.hpp" @@ -625,11 +626,9 @@ namespace ComSquare::PPU void renderMainAndSubScreen(); //! @brief Add a bg buffer to another buffer template - void add_buffer(std::array, DEST_SIZE_X> &bufferDest, - const std::array, SRC_SIZE_X> &bufferSrc, - const Vector2 &offset = {0, 0}) + void addBuffer(std::array, DEST_SIZE_X> &bufferDest, + const std::array, SRC_SIZE_X> &bufferSrc) { - // TODO use std::ranges for (unsigned long i = 0; i < bufferSrc.size(); i++) { for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness From 14618417a853090afa7bbcc706874510fc03ffe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 09:23:22 +0200 Subject: [PATCH 03/41] fixing ppu compil --- sources/PPU/PPU.cpp | 2 +- sources/PPU/PPU.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 703b8f5..c64a7d1 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 0); + //Utils::Debug::populateEnvironment(*this, 0); } uint8_t PPU::read(uint24_t addr) diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 2a42e7d..873bc91 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -632,7 +632,7 @@ namespace ComSquare::PPU for (unsigned long i = 0; i < bufferSrc.size(); i++) { for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness - bufferDest[i + offset.x ][j + offset.y] = bufferSrc[i][j]; + bufferDest[i][j] = bufferSrc[i][j]; } } } From 5860c10653a34509c9be01395cdc726a45379756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 10:31:25 +0200 Subject: [PATCH 04/41] refactor ppu x and y and little clean up --- sources/PPU/Background.cpp | 8 ++++---- sources/PPU/PPU.cpp | 13 ++++++------- sources/Renderer/SFRenderer.cpp | 3 +-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index e7c3dd2..cc6160c 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -93,11 +93,11 @@ namespace ComSquare::PPU for (int i = 0; i < this->_characterNbPixels.y; i++) { for (int j = 0; j < this->_characterNbPixels.x; j++) { //std::copy(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.x, this->buffer[pos.x].begin() ) - this->buffer[pos.x][pos.y] = this->_tileBuffer[i][j]; - pos.x++; + this->buffer[pos.y + i][pos.x + j] = this->_tileBuffer[i][j]; + //pos.x++; } - pos.x -= this->_characterNbPixels.x; - pos.y++; + //pos.x -= this->_characterNbPixels.x; + //pos.y++; } } diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index c64a7d1..4d28a25 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - //Utils::Debug::populateEnvironment(*this, 0); + Utils::Debug::populateEnvironment(*this, 1); } uint8_t PPU::read(uint24_t addr) @@ -316,7 +316,7 @@ namespace ComSquare::PPU //add_buffer(this->_screen, this->_backgrounds[2].buffer); for (unsigned long i = 0; i < this->_screen.size(); i++) { for (unsigned long j = 0; j < this->_screen[i].size(); j++) { - this->_renderer.putPixel(j, i, this->_screen[i][j]); + this->_renderer.putPixel(i, j, this->_screen[i][j]); } } this->_renderer.drawScreen(); @@ -542,11 +542,10 @@ namespace ComSquare::PPU Vector2 PPU::getBackgroundMirroring(int bgNumber) const { - Vector2 backgroundSize(false, false); - - backgroundSize.y = this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring; - backgroundSize.x = this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring; - return backgroundSize; + return { + static_cast(this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring), + static_cast(this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring) + }; } void PPU::renderMainAndSubScreen() diff --git a/sources/Renderer/SFRenderer.cpp b/sources/Renderer/SFRenderer.cpp index 8bb23fe..3579163 100644 --- a/sources/Renderer/SFRenderer.cpp +++ b/sources/Renderer/SFRenderer.cpp @@ -68,8 +68,7 @@ namespace ComSquare::Renderer if (y >= this->_videoMode.height) throw InvalidPixelPosition("Height", y, this->_videoMode.height); - sf::Color pixels(rgba); - this->_pixelBuffer[this->_videoMode.width * y + x] = pixels; + this->_pixelBuffer[this->_videoMode.width * y + x] = sf::Color(rgba); } void SFRenderer::getEvents() From e4249b1576bfc830a1c6d55da52bd3735bfce0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 10:48:02 +0200 Subject: [PATCH 05/41] clean up a const -> constexpr --- sources/PPU/TileRenderer.cpp | 4 +--- sources/PPU/TileRenderer.hpp | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sources/PPU/TileRenderer.cpp b/sources/PPU/TileRenderer.cpp index 28074de..a484485 100644 --- a/sources/PPU/TileRenderer.cpp +++ b/sources/PPU/TileRenderer.cpp @@ -83,13 +83,11 @@ namespace ComSquare::PPU { // TODO unit test this uint16_t result = 0; - // TODO do a constexpr - const int TileByteSizeRow = 16; switch (this->_bpp) { case 8: - result += this->read2BPPValue(tileRowAddress + TileByteSizeRow * 2, pixelIndex) << 4; result += this->read2BPPValue(tileRowAddress + TileByteSizeRow * 3, pixelIndex) << 6; + result += this->read2BPPValue(tileRowAddress + TileByteSizeRow * 2, pixelIndex) << 4; FALLTHROUGH case 4: result += this->read2BPPValue(tileRowAddress + TileByteSizeRow, pixelIndex) << 2; diff --git a/sources/PPU/TileRenderer.hpp b/sources/PPU/TileRenderer.hpp index e5808c5..11ced75 100644 --- a/sources/PPU/TileRenderer.hpp +++ b/sources/PPU/TileRenderer.hpp @@ -11,6 +11,9 @@ namespace ComSquare::PPU { class TileRenderer { private: + //! @brief The byte size offset for 1 row in VRAM + static constexpr int TileByteSizeRow = 16; + //! @brief ram to render std::shared_ptr _ram; //! @brief cgram to access the colors From 590078bf76982fe15ff322d8cc1109fadf89802e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 11:50:35 +0200 Subject: [PATCH 06/41] fixing missunderstanding of horizontal/vertical tilemap mirroring --- sources/PPU/Background.cpp | 4 ++-- sources/PPU/PPU.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index cc6160c..eb3aa87 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -37,9 +37,9 @@ namespace ComSquare::PPU uint16_t vramAddress = this->_tileMapStartAddress; Vector2 offset = this->_ppu.getBgScroll(this->_bgNumber); this->backgroundSize.x = - static_cast(this->_tileMapsConfig.x) * this->_characterNbPixels.x * NbCharacterWidth; + (static_cast(this->_tileMapsConfig.x) + 1) * this->_characterNbPixels.x * NbCharacterWidth; this->backgroundSize.y = - static_cast(this->_tileMapsConfig.y) * this->_characterNbPixels.y * NbCharacterHeight; + (static_cast(this->_tileMapsConfig.y) + 1) * this->_characterNbPixels.y * NbCharacterHeight; this->_drawBasicTileMap(vramAddress, offset); for (int i = 1; i < 4; i++) { diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 4d28a25..58344fd 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -543,8 +543,8 @@ namespace ComSquare::PPU Vector2 PPU::getBackgroundMirroring(int bgNumber) const { return { - static_cast(this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring), - static_cast(this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring) + static_cast(this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring), + static_cast(this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring) }; } From c5696946ebd225b85983a5fc9ae380eedd6c75cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 12:09:15 +0200 Subject: [PATCH 07/41] adding micro QoL changes segfault found in PPU while running rom --- sources/PPU/Background.cpp | 14 ++++---------- sources/PPU/PPU.cpp | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index eb3aa87..73277ff 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -82,7 +82,7 @@ namespace ComSquare::PPU tileOffset.x += 1; } tileOffset.x = 0; - tileOffset.y += 1; + tileOffset.y++; } // todo check why i need to invert vertical and horizontal flips @@ -90,15 +90,9 @@ namespace ComSquare::PPU Utils::HFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); if (tileData.horizontalFlip) Utils::VFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); - for (int i = 0; i < this->_characterNbPixels.y; i++) { - for (int j = 0; j < this->_characterNbPixels.x; j++) { - //std::copy(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.x, this->buffer[pos.x].begin() ) - this->buffer[pos.y + i][pos.x + j] = this->_tileBuffer[i][j]; - //pos.x++; - } - //pos.x -= this->_characterNbPixels.x; - //pos.y++; - } + std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, [this, &pos](const auto &row) { + std::move(row.begin(), row.begin() + this->_characterNbPixels.x, this->buffer[pos.y++].begin() + pos.x); + }); } void Background::_drawBasicTileMap(uint16_t baseAddress, Vector2 offset) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 58344fd..6114322 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 1); + //Utils::Debug::populateEnvironment(*this, 0); } uint8_t PPU::read(uint24_t addr) From ba43efe26290e2c6f53b82428160e7fa06ef92e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 12:12:30 +0200 Subject: [PATCH 08/41] norm fix --- sources/PPU/Background.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index 73277ff..e0ebf14 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -90,9 +90,11 @@ namespace ComSquare::PPU Utils::HFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); if (tileData.horizontalFlip) Utils::VFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); - std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, [this, &pos](const auto &row) { - std::move(row.begin(), row.begin() + this->_characterNbPixels.x, this->buffer[pos.y++].begin() + pos.x); - }); + std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, + [this, &pos](const auto &row) { + std::move(row.begin(), row.begin() + this->_characterNbPixels.x, + this->buffer[pos.y++].begin() + pos.x); + }); } void Background::_drawBasicTileMap(uint16_t baseAddress, Vector2 offset) From e0d46121a8ed6d70bd9a3fb145d643566f9076d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 4 Jul 2021 22:43:02 +0200 Subject: [PATCH 09/41] fixing hard to track dumb mistake --- sources/PPU/PPU.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 6114322..ce13521 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -146,8 +146,9 @@ namespace ComSquare::PPU FALLTHROUGH case PpuRegisters::bg2hofs: case PpuRegisters::bg3hofs: - case PpuRegisters::bg4hofs: - this->_registers._bgofs[addr - PpuRegisters::bg1hofs].raw = ((data << 8) | (this->_ppuState.hvSharedScrollPrevValue & ~7) | (this->_ppuState.hScrollPrevValue & 7)) & 0x3FF; + case PpuRegisters::bg4hofs: this->_registers._bgofs[addr - PpuRegisters::bg1hofs].raw = + ((data << 8) | (this->_ppuState.hvSharedScrollPrevValue & ~7) | + (this->_ppuState.hScrollPrevValue & 7)) & 0x3FF; this->_ppuState.hScrollPrevValue = data; this->_ppuState.hvSharedScrollPrevValue = data; break; @@ -158,7 +159,7 @@ namespace ComSquare::PPU case PpuRegisters::bg2vofs: case PpuRegisters::bg3vofs: case PpuRegisters::bg4vofs: - this->_registers._bgofs[addr - PpuRegisters::bg1hofs].raw = ((data << 8) | this->_ppuState.hvSharedScrollPrevValue) & 0x3FF; + this->_registers._bgofs[addr - PpuRegisters::bg1vofs].raw = ((data << 8) | this->_ppuState.hvSharedScrollPrevValue) & 0x3FF; this->_ppuState.hvSharedScrollPrevValue = data; break; case PpuRegisters::vmain: From f8a500972af18170af786510c07b807e3042210a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:14:54 +0200 Subject: [PATCH 10/41] renamming _tileMapsConfig to _tileMapMirroring --- sources/PPU/Background.cpp | 12 ++++++------ sources/PPU/Background.hpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index e0ebf14..bc2131e 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -14,7 +14,7 @@ namespace ComSquare::PPU { Background::Background(ComSquare::PPU::PPU &ppu, int backGroundNumber, bool hasPriority): _ppu(ppu), - _tileMapsConfig(ppu.getBackgroundMirroring(backGroundNumber)), + _tileMapMirroring(ppu.getBackgroundMirroring(backGroundNumber)), _characterNbPixels(ppu.getCharacterSize(backGroundNumber)), _bpp(ppu.getBPP(backGroundNumber)), _directColor(false), @@ -37,9 +37,9 @@ namespace ComSquare::PPU uint16_t vramAddress = this->_tileMapStartAddress; Vector2 offset = this->_ppu.getBgScroll(this->_bgNumber); this->backgroundSize.x = - (static_cast(this->_tileMapsConfig.x) + 1) * this->_characterNbPixels.x * NbCharacterWidth; + (static_cast(this->_tileMapMirroring.x) + 1) * this->_characterNbPixels.x * NbCharacterWidth; this->backgroundSize.y = - (static_cast(this->_tileMapsConfig.y) + 1) * this->_characterNbPixels.y * NbCharacterHeight; + (static_cast(this->_tileMapMirroring.y) + 1) * this->_characterNbPixels.y * NbCharacterHeight; this->_drawBasicTileMap(vramAddress, offset); for (int i = 1; i < 4; i++) { @@ -49,9 +49,9 @@ namespace ComSquare::PPU offset.x = 0; offset.y += NbCharacterHeight * this->_characterNbPixels.y; } - if (i > 1 && !this->_tileMapsConfig.y) + if (i > 1 && !this->_tileMapMirroring.y) break; - if ((i == 1 || i == 3) && !this->_tileMapsConfig.x) + if ((i == 1 || i == 3) && !this->_tileMapMirroring.x) continue; this->_drawBasicTileMap(vramAddress, offset); } @@ -145,7 +145,7 @@ namespace ComSquare::PPU void Background::setTilemaps(Vector2 tileMaps) { - this->_tileMapsConfig = tileMaps; + this->_tileMapMirroring = tileMaps; } int Background::getBgNumber() const diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index b8b7642..11e7246 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -32,7 +32,7 @@ namespace ComSquare::PPU ComSquare::PPU::PPU &_ppu; //! @brief The tilemap configuration nb of tileMap vertically and horizontally //! @note members are set to true if the tilemap is expended in their direction - Vector2 _tileMapsConfig; + Vector2 _tileMapMirroring; //! @brief The number of pixels of a character (x: width, y:height) Vector2 _characterNbPixels; //! @brief The number of bits per pixels to currently look for each pixel From b336a637690d98db0caa3341d564f502276f12f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:21:11 +0200 Subject: [PATCH 11/41] moving addBuffer to utils --- sources/PPU/PPU.cpp | 8 ++++---- sources/PPU/PPU.hpp | 12 ------------ sources/PPU/PPUUtils.hpp | 13 +++++++++++++ 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index ce13521..a0e58c8 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -311,8 +311,8 @@ namespace ComSquare::PPU (void)cycles; this->renderMainAndSubScreen(); - this->addBuffer(this->_screen, this->_subScreen); - this->addBuffer(this->_screen, this->_mainScreen); + Utils::addBuffer(this->_screen, this->_subScreen); + Utils::addBuffer(this->_screen, this->_mainScreen); //this->_backgrounds[2].renderBackground(); //add_buffer(this->_screen, this->_backgrounds[2].buffer); for (unsigned long i = 0; i < this->_screen.size(); i++) { @@ -656,9 +656,9 @@ namespace ComSquare::PPU void PPU::addToMainSubScreen(Background &bg) { if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) - this->addBuffer(this->_mainScreen, bg.buffer); + Utils::addBuffer(this->_mainScreen, bg.buffer); if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) - this->addBuffer(this->_subScreen, bg.buffer); + Utils::addBuffer(this->_subScreen, bg.buffer); } int PPU::getBgMode() const diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 873bc91..175eb04 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -624,18 +624,6 @@ namespace ComSquare::PPU Vector2 getBackgroundMirroring(int bgNumber) const; //! @brief Render the Main and sub screen correctly void renderMainAndSubScreen(); - //! @brief Add a bg buffer to another buffer - template - void addBuffer(std::array, DEST_SIZE_X> &bufferDest, - const std::array, SRC_SIZE_X> &bufferSrc) - { - for (unsigned long i = 0; i < bufferSrc.size(); i++) { - for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { - if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness - bufferDest[i][j] = bufferSrc[i][j]; - } - } - } //! @brief Add a bg to the sub and/or main screen void addToMainSubScreen(Background &bg); //! @brief Get the current background Mode diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 9d749a6..cb88312 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -78,5 +78,18 @@ namespace ComSquare::PPU::Utils std::reverse(array.begin() + offset.x, array.begin() + offset.x + size.x); } + //! @brief Add a bg buffer to another buffer + template + static void addBuffer(std::array, DEST_SIZE_X> &bufferDest, + const std::array, SRC_SIZE_X> &bufferSrc) + { + for (unsigned long i = 0; i < bufferSrc.size(); i++) { + for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { + if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness + bufferDest[i][j] = bufferSrc[i][j]; + } + } + } + } #endif //COMSQUARE_PPU_UTILS_HPP \ No newline at end of file From 00435259c40f8363f44eefedb7a19245a2693561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:33:01 +0200 Subject: [PATCH 12/41] opti in Merge2DArray --- sources/PPU/PPUUtils.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index cb88312..916e403 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -51,12 +51,11 @@ namespace ComSquare::PPU::Utils template void merge2DArray(std::array, DEST_SIZE_Y> &bufferDest, const std::array, SRC_SIZE_Y> &bufferSrc, - const Vector2 &offset = {0, 0}) + const Vector2 &offset) { - for (unsigned long i = 0; i < bufferSrc.size(); i++) { - for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { - bufferDest[i + offset.y][j + offset.x] = bufferSrc[i][j]; - } + int offsetY = offset.y; + for (auto &row : bufferSrc) { + std::copy(row.begin(), row.end(), bufferDest[offsetY++].begin() + offset.x); } } From a3ddadacc5f09e6fb4db0b5d7289bb633b8879e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:43:26 +0200 Subject: [PATCH 13/41] opti in addBuffer (use of std::for_each) --- sources/PPU/PPUUtils.hpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 916e403..c1799f1 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -82,12 +82,23 @@ namespace ComSquare::PPU::Utils static void addBuffer(std::array, DEST_SIZE_X> &bufferDest, const std::array, SRC_SIZE_X> &bufferSrc) { - for (unsigned long i = 0; i < bufferSrc.size(); i++) { + int i = 0; + int j = 0; + std::for_each(bufferSrc.begin(), bufferSrc.end(), [&bufferDest, &i, &j](auto &sourceRow) { + i++; + std::for_each(sourceRow.begin(), sourceRow.end(), [&bufferDest, &i, &j](auto &pixel) { + if (pixel > 0xFF) + bufferDest[i][j] = pixel; + j++; + }); + j = 0; + }); + /* for (unsigned long i = 0; i < bufferSrc.size(); i++) { for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness bufferDest[i][j] = bufferSrc[i][j]; } - } + }*/ } } From 513edf34342265f7de802468fd90396f0a162306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:44:05 +0200 Subject: [PATCH 14/41] rm comment --- sources/PPU/PPUUtils.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index c1799f1..814f89e 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -93,12 +93,6 @@ namespace ComSquare::PPU::Utils }); j = 0; }); - /* for (unsigned long i = 0; i < bufferSrc.size(); i++) { - for (unsigned long j = 0; j < bufferSrc[i].size(); j++) { - if (bufferSrc[i][j] > 0xFF) // 0xFF correspond to a black pixel with full brightness - bufferDest[i][j] = bufferSrc[i][j]; - } - }*/ } } From 6e37b8f2500d63f814e0bfed32b9f6a275e2e8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 22:45:58 +0200 Subject: [PATCH 15/41] fixing small error --- sources/PPU/PPUUtils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 814f89e..106f350 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -85,13 +85,13 @@ namespace ComSquare::PPU::Utils int i = 0; int j = 0; std::for_each(bufferSrc.begin(), bufferSrc.end(), [&bufferDest, &i, &j](auto &sourceRow) { - i++; std::for_each(sourceRow.begin(), sourceRow.end(), [&bufferDest, &i, &j](auto &pixel) { if (pixel > 0xFF) bufferDest[i][j] = pixel; j++; }); j = 0; + i++; }); } From 213f1608a796ae4d65927b741ff3ed640e7f28cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 23:13:37 +0200 Subject: [PATCH 16/41] splitting more conveniently drawTile function --- sources/PPU/Background.cpp | 29 +++++++++++++++++++---------- sources/PPU/Background.hpp | 11 +++++++++-- sources/PPU/PPU.cpp | 2 +- sources/PPU/PPUUtils.hpp | 2 +- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index bc2131e..07285e6 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -57,15 +57,8 @@ namespace ComSquare::PPU } } - void Background::_drawBgTile(uint16_t data, Vector2 pos) + void Background::_drawTileFromMemoryToTileBuffer(const Utils::TileData &tileData) { - union Utils::TileMapData tileData; - - tileData.raw = data; - - if (tileData.tilePriority != this->_priority) - return; - uint16_t graphicAddress; Vector2i tileOffset = {0, 0}; // X horizontal @@ -84,6 +77,17 @@ namespace ComSquare::PPU tileOffset.x = 0; tileOffset.y++; } + } + + void Background::_drawTile(uint16_t data, Vector2 pos) + { + union Utils::TileData tileData; + + tileData.raw = data; + + //if (tileData.tilePriority != this->_priority) + // return; + this->_drawTileFromMemoryToTileBuffer(tileData); // todo check why i need to invert vertical and horizontal flips if (tileData.verticalFlip) @@ -107,8 +111,8 @@ namespace ComSquare::PPU // TODO function to read 2 bytes (LSB order or bits reversed) tileMapValue = this->_vram->read(vramAddress); tileMapValue += this->_vram->read(vramAddress + 1) << 8U; - _drawBgTile(tileMapValue, {(pos.x * this->_characterNbPixels.x) + offset.x, - (pos.y * this->_characterNbPixels.y) + offset.y}); + this->_drawTile(tileMapValue, {(pos.x * this->_characterNbPixels.x) + offset.x, + (pos.y * this->_characterNbPixels.y) + offset.y}); vramAddress += 2; if (pos.x % 31 == 0 && pos.x) { pos.y++; @@ -162,4 +166,9 @@ namespace ComSquare::PPU { return this->_priority; } + + bool Background::isPriorityPixel(int y, int x) const + { + return this->tilesPriority[y / this->_characterNbPixels.y][x / this->_characterNbPixels.x]; + } } \ No newline at end of file diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index 11e7246..175efe2 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -11,6 +11,7 @@ #include "TileRenderer.hpp" #include "../Ram/Ram.hpp" #include "PPU.hpp" +#include "PPUUtils.hpp" namespace ComSquare::PPU { @@ -33,7 +34,7 @@ namespace ComSquare::PPU //! @brief The tilemap configuration nb of tileMap vertically and horizontally //! @note members are set to true if the tilemap is expended in their direction Vector2 _tileMapMirroring; - //! @brief The number of pixels of a character (x: width, y:height) + //! @brief The number of pixels of a character (x: height, y:width) Vector2 _characterNbPixels; //! @brief The number of bits per pixels to currently look for each pixel int _bpp; @@ -59,7 +60,9 @@ namespace ComSquare::PPU //! @brief The access to cgram std::shared_ptr _cgram; //! @brief Draw a tile on the screen at x y pos - void _drawBgTile(uint16_t data, Vector2 pos); + void _drawTile(uint16_t data, Vector2 pos); + //! @brief Draw the tile to the tile Buffer + void _drawTileFromMemoryToTileBuffer(const union Utils::TileData &tileData); //! @brief draw a tileMap 32x32 starting at baseAddress //! @param baseAddress The starting address of the tileMap //! @param offset The rendering offeset in pixels @@ -70,6 +73,10 @@ namespace ComSquare::PPU //! @brief The output buffer (pixels are written on it) std::array, 1024> buffer; + std::array, 64> tilesPriority; + + bool isPriorityPixel(int x, int y) const; + //! @brief Render a background on his internal buffer void renderBackground(); //! @brief Set the tileMap start address diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index a0e58c8..89c6325 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - //Utils::Debug::populateEnvironment(*this, 0); + Utils::Debug::populateEnvironment(*this, 1); } uint8_t PPU::read(uint24_t addr) diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 106f350..4faa8c2 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -22,7 +22,7 @@ namespace ComSquare::PPU::Utils //! @brief Transform SNES color code BGR to uint32_t RGB uint32_t getRealColor(uint16_t color); //! @brief Used to parse easily VRAM Tile information - union TileMapData { + union TileData { struct { //! @brief Tile X offset uint16_t posX: 4; From 9f0f03ebedcc3c227939e1a3ed62b083e7f10426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 6 Jul 2021 23:52:24 +0200 Subject: [PATCH 17/41] removing half of backgrounds (priority not functional) --- sources/PPU/Background.cpp | 25 +++++++++++++++---------- sources/PPU/Background.hpp | 9 ++++++--- sources/PPU/PPU.cpp | 34 ++++++++++++++++------------------ sources/PPU/PPU.hpp | 8 ++++---- sources/PPU/PpuDebug.cpp | 8 ++++---- 5 files changed, 45 insertions(+), 39 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index 07285e6..dc10de3 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -35,7 +35,8 @@ namespace ComSquare::PPU void Background::renderBackground() { uint16_t vramAddress = this->_tileMapStartAddress; - Vector2 offset = this->_ppu.getBgScroll(this->_bgNumber); + //Vector2 offset = this->_ppu.getBgScroll(this->_bgNumber); + Vector2i offset = {0, 0}; this->backgroundSize.x = (static_cast(this->_tileMapMirroring.x) + 1) * this->_characterNbPixels.x * NbCharacterWidth; this->backgroundSize.y = @@ -44,10 +45,10 @@ namespace ComSquare::PPU this->_drawBasicTileMap(vramAddress, offset); for (int i = 1; i < 4; i++) { vramAddress += TileMapByteSize; - offset.x += NbCharacterWidth * this->_characterNbPixels.x; + offset.x++; if (i == 2) { offset.x = 0; - offset.y += NbCharacterHeight * this->_characterNbPixels.y; + offset.y++; } if (i > 1 && !this->_tileMapMirroring.y) break; @@ -79,7 +80,7 @@ namespace ComSquare::PPU } } - void Background::_drawTile(uint16_t data, Vector2 pos) + void Background::_drawTile(uint16_t data, Vector2 indexOffset) { union Utils::TileData tileData; @@ -87,6 +88,7 @@ namespace ComSquare::PPU //if (tileData.tilePriority != this->_priority) // return; + this->tilesPriority[indexOffset.x][indexOffset.y] = tileData.tilePriority; this->_drawTileFromMemoryToTileBuffer(tileData); // todo check why i need to invert vertical and horizontal flips @@ -94,10 +96,12 @@ namespace ComSquare::PPU Utils::HFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); if (tileData.horizontalFlip) Utils::VFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y}); + + Vector2 pixelPosition{indexOffset.x * this->_characterNbPixels.x, indexOffset.y * this->_characterNbPixels.y}; std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, - [this, &pos](const auto &row) { + [this, &pixelPosition](const auto &row) { std::move(row.begin(), row.begin() + this->_characterNbPixels.x, - this->buffer[pos.y++].begin() + pos.x); + this->buffer[pixelPosition.y++].begin() + pixelPosition.x); }); } @@ -111,15 +115,16 @@ namespace ComSquare::PPU // TODO function to read 2 bytes (LSB order or bits reversed) tileMapValue = this->_vram->read(vramAddress); tileMapValue += this->_vram->read(vramAddress + 1) << 8U; - this->_drawTile(tileMapValue, {(pos.x * this->_characterNbPixels.x) + offset.x, - (pos.y * this->_characterNbPixels.y) + offset.y}); + this->_drawTile(tileMapValue, {(offset.x * NbCharacterWidth) + pos.x, + (offset.y * NbCharacterHeight) + pos.y}); vramAddress += 2; if (pos.x % 31 == 0 && pos.x) { pos.y++; pos.x = 0; } - else + else { pos.x++; + } } } @@ -147,7 +152,7 @@ namespace ComSquare::PPU this->_tileRenderer.setBpp(this->_bpp); } - void Background::setTilemaps(Vector2 tileMaps) + void Background::setTileMapMirroring(Vector2 tileMaps) { this->_tileMapMirroring = tileMaps; } diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index 175efe2..ca62f38 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -60,12 +60,15 @@ namespace ComSquare::PPU //! @brief The access to cgram std::shared_ptr _cgram; //! @brief Draw a tile on the screen at x y pos - void _drawTile(uint16_t data, Vector2 pos); + //! @param data The VRAM value to be interpreted as a Utils::TileData + //! @param indexOffset The index offset of the Tile (ranging from 0 to 63) + void _drawTile(uint16_t data, Vector2 indexOffset); //! @brief Draw the tile to the tile Buffer + //! @param tileData The tile data to use to render the tile void _drawTileFromMemoryToTileBuffer(const union Utils::TileData &tileData); //! @brief draw a tileMap 32x32 starting at baseAddress //! @param baseAddress The starting address of the tileMap - //! @param offset The rendering offeset in pixels + //! @param offset The offset of the tile map (ranging from 0 to 1) void _drawBasicTileMap(uint16_t baseAddress, Vector2 offset); public: //! @brief The size of the background (x, y) @@ -92,7 +95,7 @@ namespace ComSquare::PPU void setBpp(int bpp); //! @brief setter for private variable _tileMaps //! @param tileMaps The tileMaps to set - void setTilemaps(Vector2 tileMaps); + void setTileMapMirroring(Vector2 tileMaps); //! @brief Get the BackGround Number //! @return the current Background number diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 89c6325..46c86da 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -23,13 +23,13 @@ namespace ComSquare::PPU _renderer(renderer), _backgrounds{ Background(*this, 1, false), - Background(*this, 1, true), + //Background(*this, 1, true), Background(*this, 2, false), - Background(*this, 2, true), + //Background(*this, 2, true), Background(*this, 3, false), - Background(*this, 3, true), + //Background(*this, 3, true), Background(*this, 4, false), - Background(*this, 4, true) + //Background(*this, 4, true) }, _mainScreen({{{0}}}), _subScreen({{{0}}}) @@ -129,10 +129,10 @@ namespace ComSquare::PPU this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapStartAddress( this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); - this->_backgrounds[addr - PpuRegisters::bg1sc].setTilemaps( + this->_backgrounds[addr - PpuRegisters::bg1sc].setTileMapMirroring( {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); - this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTilemaps( + this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapMirroring( {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); break; @@ -553,9 +553,7 @@ namespace ComSquare::PPU { uint16_t colorPalette; // should only render backgrounds needed (depending of th bgMode) - int i = 0; for (auto &_background : this->_backgrounds) { - i++; _background.renderBackground(); } // TODO make a function getDefaultBgColor @@ -572,30 +570,30 @@ namespace ComSquare::PPU 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]); //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]); //sprites priority 0 - if (!this->_registers._bgmode.mode1Bg3PriorityBit) - this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); + // if (!this->_registers._bgmode.mode1Bg3PriorityBit) + // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 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]); + // if (this->_registers._bgmode.mode1Bg3PriorityBit) + // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); break; case 2: this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 175eb04..f0b4ebf 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -34,11 +34,11 @@ namespace ComSquare::PPU enum BgName { bg1NoPriority = 0, bg1Priority, - bg2NoPriority, + bg2NoPriority = 1, bg2Priority, - bg3NoPriority, + bg3NoPriority = 2, bg3Priority, - bg4NoPriority, + bg4NoPriority = 3, bg4Priority }; @@ -564,7 +564,7 @@ namespace ComSquare::PPU Registers _registers{}; Renderer::IRenderer &_renderer; //! @brief Backgrounds buffers - Background _backgrounds[8]; + Background _backgrounds[4]; //! @brief Main Screen buffer std::array, 1024> _mainScreen; //! @brief Sub Screen buffer diff --git a/sources/PPU/PpuDebug.cpp b/sources/PPU/PpuDebug.cpp index f4f3301..2657e27 100644 --- a/sources/PPU/PpuDebug.cpp +++ b/sources/PPU/PpuDebug.cpp @@ -3795,13 +3795,13 @@ namespace ComSquare::PPU::Utils::Debug ppu._registers._bgsc[1].tilemapHorizontalMirroring = 1; ppu._registers._bgsc[2].tilemapAddress = 0x5C00U >> 10U; ppu._backgrounds[0].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); - ppu._backgrounds[0].setTilemaps(ppu.getBackgroundMirroring(1)); + ppu._backgrounds[0].setTileMapMirroring(ppu.getBackgroundMirroring(1)); ppu._backgrounds[1].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); - ppu._backgrounds[1].setTilemaps(ppu.getBackgroundMirroring(1)); + ppu._backgrounds[1].setTileMapMirroring(ppu.getBackgroundMirroring(1)); ppu._backgrounds[2].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); - ppu._backgrounds[2].setTilemaps(ppu.getBackgroundMirroring(2)); + ppu._backgrounds[2].setTileMapMirroring(ppu.getBackgroundMirroring(2)); ppu._backgrounds[3].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); - ppu._backgrounds[3].setTilemaps(ppu.getBackgroundMirroring(2)); + ppu._backgrounds[3].setTileMapMirroring(ppu.getBackgroundMirroring(2)); ppu._backgrounds[4].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); ppu._backgrounds[5].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); From 3e73370a9a55a058a1cad927c86f10c434d0fd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Wed, 7 Jul 2021 00:40:50 +0200 Subject: [PATCH 18/41] try to make priority work but not yet functionnal --- sources/PPU/Background.hpp | 31 +++++++++++++++++++++++++++++ sources/PPU/PPU.cpp | 40 ++++++++++++++++++++++++-------------- sources/PPU/PPU.hpp | 4 +++- sources/PPU/PPUUtils.hpp | 1 - 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index ca62f38..c7ad7f6 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -107,6 +107,37 @@ namespace ComSquare::PPU //! @return the current Background priority bool getPriority() const; + + //! @brief Add a bg buffer to another buffer + template + static void mergeBackgroundBuffer(std::array, DEST_SIZE_X> &bufferDest, + std::array, DEST_SIZE_X> &pixelDestinationLevelMap, + const Background &backgroundSrc, + int levelLow, + int levelHigh) + { + int i = 0; + int j = 0; + int pixelLevel; + std::for_each(backgroundSrc.buffer.begin(), backgroundSrc.buffer.end(), [&](auto &sourceRow) { + std::for_each(sourceRow.begin(), sourceRow.end(), [&](auto &pixel) { + if (pixel <= 0xFF) { + j++; + return; + } + pixelLevel = backgroundSrc.isPriorityPixel(i, j) ? levelHigh : levelLow; + + if (pixelLevel > pixelDestinationLevelMap[i][j]) { + bufferDest[i][j] = pixel; + pixelDestinationLevelMap[i][j] = pixelLevel; + } + j++; + }); + j = 0; + i++; + }); + } + //! @brief ctor Background(ComSquare::PPU::PPU &_ppu, int backGroundNumber, bool hasPriority); //! @brief Default copy ctor diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 46c86da..6cc0f65 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -317,8 +317,10 @@ namespace ComSquare::PPU //add_buffer(this->_screen, this->_backgrounds[2].buffer); for (unsigned long i = 0; i < this->_screen.size(); i++) { for (unsigned long j = 0; j < this->_screen[i].size(); j++) { - this->_renderer.putPixel(i, j, this->_screen[i][j]); + this->_renderer.putPixel(i + 200, j, this->_screen[i][j]); } + if (i > 500) + break; } this->_renderer.drawScreen(); for (auto &i : this->_mainScreen) @@ -563,31 +565,35 @@ namespace ComSquare::PPU uint32_t color = Utils::getRealColor(colorPalette); for (auto &row : this->_subScreen) row.fill(color); + for (auto &row : this->_mainScreenLevelMap) + row.fill(0); + for (auto &row : this->_subScreenLevelMap) + row.fill(0); // the buffer is overwrite if necessary by a new bg so the background priority is from back to front // 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], {0, 15}); + this->addToMainSubScreen(this->_backgrounds[BgName::bg3NoPriority], {10, 16}); //sprites priority 0 // 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], {20, 35}); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority], {30, 36}); //sprites priority 2 // 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], {0, this->_registers._bgmode.mode1Bg3PriorityBit ? 30 : 5}); //sprites priority 0 // if (!this->_registers._bgmode.mode1Bg3PriorityBit) // 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], {10, 25}); + this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority], {20, 26}); //sprites priority 2 // this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); @@ -595,7 +601,7 @@ namespace ComSquare::PPU // if (this->_registers._bgmode.mode1Bg3PriorityBit) // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); break; - case 2: + /* case 2: this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority]); //sprites priority 0 this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority]); @@ -642,7 +648,7 @@ namespace ComSquare::PPU //sprites priority 2 this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority - break; + break;*/ case 7: // Not implemented throw std::runtime_error("not implemented"); @@ -651,12 +657,16 @@ namespace ComSquare::PPU } } - void PPU::addToMainSubScreen(Background &bg) + void PPU::addToMainSubScreen(Background &bg, const Vector2 &level) { - if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) - Utils::addBuffer(this->_mainScreen, bg.buffer); - if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) - Utils::addBuffer(this->_subScreen, bg.buffer); + if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) { + Background::mergeBackgroundBuffer(this->_mainScreen, this->_mainScreenLevelMap, bg, level.x, level.y); + } + // Utils::addBuffer(this->_mainScreen, bg.buffer); + if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) { + //Utils::addBuffer(this->_subScreen, bg.buffer); + Background::mergeBackgroundBuffer(this->_subScreen, this->_subScreenLevelMap, bg, level.x, level.y); + } } int PPU::getBgMode() const diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index f0b4ebf..02ea9a9 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -567,7 +567,9 @@ namespace ComSquare::PPU Background _backgrounds[4]; //! @brief Main Screen buffer std::array, 1024> _mainScreen; + std::array, 1024> _mainScreenLevelMap; //! @brief Sub Screen buffer + std::array, 1024> _subScreenLevelMap; std::array, 1024> _subScreen; //! @brief Final Screen buffer std::array, 1024> _screen; @@ -625,7 +627,7 @@ namespace ComSquare::PPU //! @brief Render the Main and sub screen correctly void renderMainAndSubScreen(); //! @brief Add a bg to the sub and/or main screen - void addToMainSubScreen(Background &bg); + void addToMainSubScreen(Background &bg, const Vector2 &level); //! @brief Get the current background Mode int getBgMode() const; //! @brief update the Vram buffer diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 4faa8c2..207062e 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -94,6 +94,5 @@ namespace ComSquare::PPU::Utils i++; }); } - } #endif //COMSQUARE_PPU_UTILS_HPP \ No newline at end of file From 8a4a515d4c30b4dec9bedd365c76c6cd2c040cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Wed, 7 Jul 2021 01:05:23 +0200 Subject: [PATCH 19/41] updating debug registers result is better but it's weird --- sources/PPU/PpuDebug.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/sources/PPU/PpuDebug.cpp b/sources/PPU/PpuDebug.cpp index 2657e27..2de7ba1 100644 --- a/sources/PPU/PpuDebug.cpp +++ b/sources/PPU/PpuDebug.cpp @@ -3776,18 +3776,18 @@ namespace ComSquare::PPU::Utils::Debug { ppu._registers._bgmode.bgMode = 1; ppu._backgrounds[0].setBpp(ppu.getBPP(1)); - ppu._backgrounds[1].setBpp(ppu.getBPP(1)); - ppu._backgrounds[2].setBpp(ppu.getBPP(2)); - ppu._backgrounds[3].setBpp(ppu.getBPP(2)); - ppu._backgrounds[4].setBpp(ppu.getBPP(3)); - ppu._backgrounds[5].setBpp(ppu.getBPP(3)); + ppu._backgrounds[1].setBpp(ppu.getBPP(2)); + ppu._backgrounds[2].setBpp(ppu.getBPP(3)); + ppu._backgrounds[3].setBpp(ppu.getBPP(4)); + //ppu._backgrounds[4].setBpp(ppu.getBPP(3)); + //ppu._backgrounds[5].setBpp(ppu.getBPP(3)); //ppu._registers._bgmode.characterSizeBg1 = false; //ppu._registers._bgmode.characterSizeBg2 = false; ppu._registers._bgmode.mode1Bg3PriorityBit = true; ppu._backgrounds[0].setCharacterSize(ppu.getCharacterSize(1)); - ppu._backgrounds[1].setCharacterSize(ppu.getCharacterSize(1)); - ppu._backgrounds[2].setCharacterSize(ppu.getCharacterSize(2)); - ppu._backgrounds[3].setCharacterSize(ppu.getCharacterSize(2)); + ppu._backgrounds[1].setCharacterSize(ppu.getCharacterSize(2)); + ppu._backgrounds[2].setCharacterSize(ppu.getCharacterSize(3)); + ppu._backgrounds[3].setCharacterSize(ppu.getCharacterSize(4)); ppu._registers._bgsc[0].tilemapAddress = 0x4800U >> 10U; // 0x4800 ppu._registers._bgsc[0].tilemapHorizontalMirroring = 1; @@ -3796,14 +3796,15 @@ namespace ComSquare::PPU::Utils::Debug ppu._registers._bgsc[2].tilemapAddress = 0x5C00U >> 10U; ppu._backgrounds[0].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); ppu._backgrounds[0].setTileMapMirroring(ppu.getBackgroundMirroring(1)); - ppu._backgrounds[1].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); - ppu._backgrounds[1].setTileMapMirroring(ppu.getBackgroundMirroring(1)); - ppu._backgrounds[2].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); - ppu._backgrounds[2].setTileMapMirroring(ppu.getBackgroundMirroring(2)); - ppu._backgrounds[3].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); - ppu._backgrounds[3].setTileMapMirroring(ppu.getBackgroundMirroring(2)); - ppu._backgrounds[4].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); - ppu._backgrounds[5].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); + ppu._backgrounds[1].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); + ppu._backgrounds[1].setTileMapMirroring(ppu.getBackgroundMirroring(2)); + ppu._backgrounds[2].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); + ppu._backgrounds[2].setTileMapMirroring(ppu.getBackgroundMirroring(3)); + ppu._backgrounds[3].setTileMapStartAddress(ppu.getTileMapStartAddress(4)); + ppu._backgrounds[3].setTileMapMirroring(ppu.getBackgroundMirroring(4)); + + //ppu._backgrounds[4].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); + //ppu._backgrounds[5].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); //registres bgnba //ppu._registers._bgnba[0].baseAddressBg1a3 = 0x5; @@ -3814,8 +3815,8 @@ namespace ComSquare::PPU::Utils::Debug //ppu._backgrounds[1].setTilesetAddress(ppu.getTilesetAddress(1)); //ppu._backgrounds[2].setTilesetAddress(ppu.getTilesetAddress(2)); //ppu._backgrounds[3].setTilesetAddress(ppu.getTilesetAddress(2)); - ppu._backgrounds[4].setTilesetAddress(ppu.getTilesetAddress(3)); - ppu._backgrounds[5].setTilesetAddress(ppu.getTilesetAddress(3)); + ppu._backgrounds[2].setTilesetAddress(ppu.getTilesetAddress(3)); + //ppu._backgrounds[3].setTilesetAddress(ppu.getTilesetAddress(3)); ppu._registers._vmain.incrementMode = true; ppu._registers._vmain.incrementAmount = 1; From 948b4cb51a299a4db9cef892402cdded3ac640fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Wed, 7 Jul 2021 01:08:10 +0200 Subject: [PATCH 20/41] fixing unit tests ci --- CMakeLists.txt | 4 ++-- sources/PPU/PPU.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c8272e..62af7d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,8 @@ set(SOURCES sources/PPU/TileRenderer.cpp sources/PPU/TileRenderer.hpp sources/PPU/Tile.hpp + sources/PPU/PpuDebug.cpp + sources/PPU/PpuDebug.hpp ) set(CMAKE_AUTOMOC ON) @@ -118,8 +120,6 @@ add_executable(ComSquare sources/Renderer/QtRenderer/QtSfmlTileRenderer.hpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.hpp - sources/PPU/PpuDebug.cpp - sources/PPU/PpuDebug.hpp sources/Debugger/CPU/CPUDebug.cpp sources/Debugger/CPU/CPUDebug.hpp sources/Debugger/MemoryViewer.cpp diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 6cc0f65..f4f4f13 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -36,7 +36,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 1); +// Utils::Debug::populateEnvironment(*this, 1); } uint8_t PPU::read(uint24_t addr) From 11c5ac8476aa5b25283a80488393cfe09a37423e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 8 Jul 2021 00:13:59 +0200 Subject: [PATCH 21/41] fixing ppu x and y --- sources/PPU/Background.cpp | 10 +++++----- sources/PPU/Background.hpp | 4 +++- sources/PPU/PPU.cpp | 22 +++++++++------------- sources/PPU/PPU.hpp | 6 +----- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index dc10de3..ab2159a 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -101,7 +101,7 @@ namespace ComSquare::PPU std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, [this, &pixelPosition](const auto &row) { std::move(row.begin(), row.begin() + this->_characterNbPixels.x, - this->buffer[pixelPosition.y++].begin() + pixelPosition.x); + this->buffer[pixelPosition.x++].begin() + pixelPosition.y); }); } @@ -118,12 +118,12 @@ namespace ComSquare::PPU this->_drawTile(tileMapValue, {(offset.x * NbCharacterWidth) + pos.x, (offset.y * NbCharacterHeight) + pos.y}); vramAddress += 2; - if (pos.x % 31 == 0 && pos.x) { - pos.y++; - pos.x = 0; + if (pos.y % 31 == 0 && pos.y) { + pos.x++; + pos.y = 0; } else { - pos.x++; + pos.y++; } } } diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index c7ad7f6..7ca9421 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../Models/Vector2.hpp" #include "TileRenderer.hpp" #include "../Ram/Ram.hpp" @@ -127,7 +128,7 @@ namespace ComSquare::PPU } pixelLevel = backgroundSrc.isPriorityPixel(i, j) ? levelHigh : levelLow; - if (pixelLevel > pixelDestinationLevelMap[i][j]) { + if (pixelLevel >= pixelDestinationLevelMap[i][j]) { bufferDest[i][j] = pixel; pixelDestinationLevelMap[i][j] = pixelLevel; } @@ -136,6 +137,7 @@ namespace ComSquare::PPU j = 0; i++; }); + } //! @brief ctor diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index f4f4f13..1fccd12 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -23,20 +23,16 @@ namespace ComSquare::PPU _renderer(renderer), _backgrounds{ Background(*this, 1, false), - //Background(*this, 1, true), Background(*this, 2, false), - //Background(*this, 2, true), Background(*this, 3, false), - //Background(*this, 3, true), Background(*this, 4, false), - //Background(*this, 4, true) }, _mainScreen({{{0}}}), _subScreen({{{0}}}) { this->_registers._isLowByte = true; -// Utils::Debug::populateEnvironment(*this, 1); + Utils::Debug::populateEnvironment(*this, 1); } uint8_t PPU::read(uint24_t addr) @@ -111,9 +107,9 @@ namespace ComSquare::PPU case PpuRegisters::bgmode: this->_registers._bgmode.raw = data; // update backgrounds - for (int i = 0; i < 8; i++) { - this->_backgrounds[i].setBpp(this->getBPP((i / 2) + 1)); - this->_backgrounds[i].setCharacterSize(this->getCharacterSize((i / 2) + 1)); + for (int i = 0; i < 4; i++) { + this->_backgrounds[i].setBpp(this->getBPP(i + 1)); + this->_backgrounds[i].setCharacterSize(this->getCharacterSize(i + 1)); } break; case PpuRegisters::mosaic: @@ -127,14 +123,14 @@ namespace ComSquare::PPU // update background tilemap address this->_backgrounds[addr - PpuRegisters::bg1sc].setTileMapStartAddress( this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); - this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapStartAddress( - this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); + //this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapStartAddress( + // this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); this->_backgrounds[addr - PpuRegisters::bg1sc].setTileMapMirroring( {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); - this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapMirroring( - {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), - static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); + //this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapMirroring( + // {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), + // static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); break; case PpuRegisters::bg12nba: case PpuRegisters::bg34nba: diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 02ea9a9..32d8302 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -33,13 +33,9 @@ namespace ComSquare::PPU //! @brief Enum to access more easily the ppu background array enum BgName { bg1NoPriority = 0, - bg1Priority, bg2NoPriority = 1, - bg2Priority, bg3NoPriority = 2, - bg3Priority, - bg4NoPriority = 3, - bg4Priority + bg4NoPriority = 3 }; enum PpuRegisters { From 5527a1934826cec45b90a70fdce63add83248bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 8 Jul 2021 00:28:05 +0200 Subject: [PATCH 22/41] really fixing ppu x and y --- sources/PPU/Background.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index ab2159a..7854e25 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -73,7 +73,7 @@ namespace ComSquare::PPU ((tileData.posX + tileOffset.x) * this->_bpp * Tile::BaseByteSize); this->_tileRenderer.render(graphicAddress); Utils::merge2DArray(this->_tileBuffer, this->_tileRenderer.buffer, {j, i}); - tileOffset.x += 1; + tileOffset.x++; } tileOffset.x = 0; tileOffset.y++; @@ -88,7 +88,7 @@ namespace ComSquare::PPU //if (tileData.tilePriority != this->_priority) // return; - this->tilesPriority[indexOffset.x][indexOffset.y] = tileData.tilePriority; + this->tilesPriority[indexOffset.y][indexOffset.x] = tileData.tilePriority; this->_drawTileFromMemoryToTileBuffer(tileData); // todo check why i need to invert vertical and horizontal flips @@ -101,7 +101,7 @@ namespace ComSquare::PPU std::for_each(this->_tileBuffer.begin(), this->_tileBuffer.begin() + this->_characterNbPixels.y, [this, &pixelPosition](const auto &row) { std::move(row.begin(), row.begin() + this->_characterNbPixels.x, - this->buffer[pixelPosition.x++].begin() + pixelPosition.y); + this->buffer[pixelPosition.y++].begin() + pixelPosition.x); }); } @@ -118,12 +118,12 @@ namespace ComSquare::PPU this->_drawTile(tileMapValue, {(offset.x * NbCharacterWidth) + pos.x, (offset.y * NbCharacterHeight) + pos.y}); vramAddress += 2; - if (pos.y % 31 == 0 && pos.y) { - pos.x++; - pos.y = 0; + if (pos.x % 31 == 0 && pos.x) { + pos.y++; + pos.x = 0; } else { - pos.y++; + pos.x++; } } } From 3964da952688399c8546ec216185ceec6cbe2d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 8 Jul 2021 00:48:10 +0200 Subject: [PATCH 23/41] general clean up --- sources/PPU/Background.cpp | 2 -- sources/PPU/Background.hpp | 5 +++-- sources/PPU/PPU.cpp | 37 ++++++++++++++++++++++++------------- sources/PPU/PpuDebug.cpp | 27 ++++++++++----------------- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index 7854e25..6ba526f 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -86,8 +86,6 @@ namespace ComSquare::PPU tileData.raw = data; - //if (tileData.tilePriority != this->_priority) - // return; this->tilesPriority[indexOffset.y][indexOffset.x] = tileData.tilePriority; this->_drawTileFromMemoryToTileBuffer(tileData); diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index 7ca9421..552a5c7 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -127,10 +127,11 @@ namespace ComSquare::PPU return; } pixelLevel = backgroundSrc.isPriorityPixel(i, j) ? levelHigh : levelLow; + auto &pixelInitialLevel = pixelDestinationLevelMap[i][j]; - if (pixelLevel >= pixelDestinationLevelMap[i][j]) { + if (pixelLevel >= pixelInitialLevel) { bufferDest[i][j] = pixel; - pixelDestinationLevelMap[i][j] = pixelLevel; + pixelInitialLevel = pixelLevel; } j++; }); diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 1fccd12..f648786 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -32,7 +32,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 1); + Utils::Debug::populateEnvironment(*this, 0); } uint8_t PPU::read(uint24_t addr) @@ -309,20 +309,33 @@ namespace ComSquare::PPU this->renderMainAndSubScreen(); Utils::addBuffer(this->_screen, this->_subScreen); Utils::addBuffer(this->_screen, this->_mainScreen); - //this->_backgrounds[2].renderBackground(); - //add_buffer(this->_screen, this->_backgrounds[2].buffer); + + int i = 0; + int j = 0; + std::for_each(this->_screen.begin(), this->_screen.end(), [this, &i, &j](const auto &row) { + std::for_each(row.begin(), row.end(), [this, &i, &j](const auto &pixel) { + this->_renderer.putPixel(i, j++, pixel); + }); + j = 0; + i++; + }); + + + /* + // loop used for debug for (unsigned long i = 0; i < this->_screen.size(); i++) { for (unsigned long j = 0; j < this->_screen[i].size(); j++) { - this->_renderer.putPixel(i + 200, j, this->_screen[i][j]); + this->_renderer.putPixel(i, j, this->_screen[i][j]); } - if (i > 500) - break; + //if (i > 500) + // break; } + */ this->_renderer.drawScreen(); - for (auto &i : this->_mainScreen) - i.fill(0XFF); - for (auto &i : this->_subScreen) - i.fill(0XFF); + for (auto &row : this->_mainScreen) + row.fill(0XFF); + for (auto &row : this->_subScreen) + row.fill(0XFF); } std::string PPU::getName() const @@ -649,7 +662,7 @@ namespace ComSquare::PPU // Not implemented throw std::runtime_error("not implemented"); default: - break; + throw std::runtime_error("Bg mode not implemented or commented (bg nb " + std::to_string(this->_registers._bgmode.bgMode) + ")"); } } @@ -658,9 +671,7 @@ namespace ComSquare::PPU if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) { Background::mergeBackgroundBuffer(this->_mainScreen, this->_mainScreenLevelMap, bg, level.x, level.y); } - // Utils::addBuffer(this->_mainScreen, bg.buffer); if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) { - //Utils::addBuffer(this->_subScreen, bg.buffer); Background::mergeBackgroundBuffer(this->_subScreen, this->_subScreenLevelMap, bg, level.x, level.y); } } diff --git a/sources/PPU/PpuDebug.cpp b/sources/PPU/PpuDebug.cpp index 2de7ba1..b1ae774 100644 --- a/sources/PPU/PpuDebug.cpp +++ b/sources/PPU/PpuDebug.cpp @@ -3833,31 +3833,24 @@ namespace ComSquare::PPU::Utils::Debug //registers tic tac toe ppu._registers._bgmode.bgMode = 0; ppu._backgrounds[0].setBpp(ppu.getBPP(1)); - ppu._backgrounds[1].setBpp(ppu.getBPP(1)); - ppu._backgrounds[2].setBpp(ppu.getBPP(2)); - ppu._backgrounds[3].setBpp(ppu.getBPP(2)); - ppu._backgrounds[4].setBpp(ppu.getBPP(3)); - ppu._backgrounds[5].setBpp(ppu.getBPP(3)); - ppu._backgrounds[6].setBpp(ppu.getBPP(4)); - ppu._backgrounds[7].setBpp(ppu.getBPP(4)); + ppu._backgrounds[1].setBpp(ppu.getBPP(2)); + ppu._backgrounds[2].setBpp(ppu.getBPP(3)); + ppu._backgrounds[3].setBpp(ppu.getBPP(4)); ppu._registers._bgmode.characterSizeBg1 = true; ppu._registers._bgmode.characterSizeBg2 = true; ppu._backgrounds[0].setCharacterSize(ppu.getCharacterSize(1)); - ppu._backgrounds[1].setCharacterSize(ppu.getCharacterSize(1)); - ppu._backgrounds[2].setCharacterSize(ppu.getCharacterSize(2)); - ppu._backgrounds[3].setCharacterSize(ppu.getCharacterSize(2)); - ppu._backgrounds[4].setCharacterSize(ppu.getCharacterSize(3)); - ppu._backgrounds[5].setCharacterSize(ppu.getCharacterSize(3)); - ppu._backgrounds[6].setCharacterSize(ppu.getCharacterSize(4)); - ppu._backgrounds[7].setCharacterSize(ppu.getCharacterSize(4)); + ppu._backgrounds[1].setCharacterSize(ppu.getCharacterSize(2)); + ppu._backgrounds[2].setCharacterSize(ppu.getCharacterSize(3)); + ppu._backgrounds[3].setCharacterSize(ppu.getCharacterSize(4)); + ppu._registers._bgsc[0].tilemapAddress = 0x4000 >> 10U; ppu._registers._bgsc[1].tilemapAddress = 0x6000 >> 10U; ppu._backgrounds[0].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); - ppu._backgrounds[1].setTileMapStartAddress(ppu.getTileMapStartAddress(1)); - ppu._backgrounds[2].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); - ppu._backgrounds[3].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); + ppu._backgrounds[1].setTileMapStartAddress(ppu.getTileMapStartAddress(2)); + ppu._backgrounds[2].setTileMapStartAddress(ppu.getTileMapStartAddress(3)); + ppu._backgrounds[3].setTileMapStartAddress(ppu.getTileMapStartAddress(4)); //ppu._registers._bgofs[2].raw = 0x03E0; //ppu._registers._bgofs[3].raw = 0x03DF; From 79dcdebf706aae5f0b9ce73ce1731175cbd46694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 8 Jul 2021 00:51:06 +0200 Subject: [PATCH 24/41] more clean up using 4 backgrounds is working nicely --- sources/PPU/PPU.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index f648786..7e2927c 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -32,7 +32,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 0); + //Utils::Debug::populateEnvironment(*this, 0); } uint8_t PPU::read(uint24_t addr) @@ -123,14 +123,9 @@ namespace ComSquare::PPU // update background tilemap address this->_backgrounds[addr - PpuRegisters::bg1sc].setTileMapStartAddress( this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); - //this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapStartAddress( - // this->getTileMapStartAddress(addr - PpuRegisters::bg1sc + 1)); this->_backgrounds[addr - PpuRegisters::bg1sc].setTileMapMirroring( {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); - //this->_backgrounds[addr - PpuRegisters::bg1sc + 1].setTileMapMirroring( - // {static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapHorizontalMirroring), - // static_cast(this->_registers._bgsc[addr - PpuRegisters::bg1sc].tilemapVerticalMirroring)}); break; case PpuRegisters::bg12nba: case PpuRegisters::bg34nba: From c6899c6b632fdba2f6fceb9eefaa2d216ee76d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 8 Jul 2021 01:09:26 +0200 Subject: [PATCH 25/41] push unit test passed --- sources/PPU/PPU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 2a3d69e..4a2e1f1 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -30,7 +30,7 @@ namespace ComSquare::PPU { this->_registers._isLowByte = true; - Utils::Debug::populateEnvironment(*this, 1); + //Utils::Debug::populateEnvironment(*this, 1); } uint8_t PPU::read(uint24_t addr) From 3002f9272e8538fd903d9a3b84024b363d93a695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Fri, 9 Jul 2021 01:17:37 +0200 Subject: [PATCH 26/41] adding unit tests for TileRenderer but 8bpp test isn't finished --- CMakeLists.txt | 1 + sources/PPU/TileRenderer.cpp | 1 - sources/PPU/TileRenderer.hpp | 6 +- tests/PPU/testTileRenderer.cpp | 173 +++++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 tests/PPU/testTileRenderer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ee9d3d6..cad4546 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,6 +185,7 @@ add_executable(unit_tests EXCLUDE_FROM_ALL tests/CPU/testDMA.cpp tests/CPU/testAddressingMode.cpp tests/testMemoryBus.cpp + tests/PPU/testTileRenderer.cpp ) target_include_directories(unit_tests PUBLIC tests) target_compile_definitions(unit_tests PUBLIC TESTS) diff --git a/sources/PPU/TileRenderer.cpp b/sources/PPU/TileRenderer.cpp index f480f82..571134a 100644 --- a/sources/PPU/TileRenderer.cpp +++ b/sources/PPU/TileRenderer.cpp @@ -65,7 +65,6 @@ namespace ComSquare::PPU uint8_t TileRenderer::read2BPPValue(uint16_t tileRowAddress, uint8_t pixelIndex) { - // TODO unit test this size_t size = this->_ram.getSize(); uint8_t highByte = this->_ram.read(tileRowAddress % size); uint8_t lowByte = this->_ram.read((tileRowAddress + 1) % size); diff --git a/sources/PPU/TileRenderer.hpp b/sources/PPU/TileRenderer.hpp index ec2c20a..7444a33 100644 --- a/sources/PPU/TileRenderer.hpp +++ b/sources/PPU/TileRenderer.hpp @@ -31,9 +31,9 @@ namespace ComSquare::PPU //! @brief Set the bpp to render graphics void setBpp(int bpp); //! @brief Get the current bpp - int getBpp() const; + [[nodiscard]] int getBpp() const; //! @brief Get the index of the current palette used - int getPaletteIndex() const; + [[nodiscard]] int getPaletteIndex() const; //! @brief Get the color pixel reference from the tile address and pixelIndex //! @param tileAddress The starting address of the tile //! @param pixelIndex The index of the pixel (0 - 255) @@ -50,6 +50,8 @@ namespace ComSquare::PPU //! @warning Values are CGRAM colors use PPU::getRealColor function to get the actual real color std::vector getPalette(int nbPalette); //! @brief read the 2bpp value for a pixel (used multple times for 4bpp and 8bpp) + //! @param tileRowAddress Address where the read is done. Usage: Address of the tile row to render + //! @param pixelIndex The offset form tileRowAddress, Usage: the pixel to read uint8_t read2BPPValue(uint16_t tileRowAddress, uint8_t pixelIndex); //! @brief render the tile (8x8) at the tileAddress //! @param tileAddress The address of the tile to render diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp new file mode 100644 index 0000000..a4de5e9 --- /dev/null +++ b/tests/PPU/testTileRenderer.cpp @@ -0,0 +1,173 @@ +// +// Created by cbihan on 08/07/2021. +// + +#include +#include +#include +#include +#include +#include "PPU/TileRenderer.hpp" +#include "Ram/Ram.hpp" +#include "PPU/Tile.hpp" + +TEST_CASE("read2BPPValue", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + vram.write(0, 0xBA); + vram.write(1, 0x7C); + + CHECK(tileRenderer.read2BPPValue(0, 0) == 1); + CHECK(tileRenderer.read2BPPValue(0, 1) == 2); + CHECK(tileRenderer.read2BPPValue(0, 2) == 3); + CHECK(tileRenderer.read2BPPValue(0, 3) == 3); + CHECK(tileRenderer.read2BPPValue(0, 4) == 3); + CHECK(tileRenderer.read2BPPValue(0, 5) == 2); + CHECK(tileRenderer.read2BPPValue(0, 6) == 1); + CHECK(tileRenderer.read2BPPValue(0, 7) == 0); +} + +TEST_CASE("read2BPPValue with circular ram", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + vram.write(9, 0xBA); + vram.write(0, 0x7C); + + CHECK(tileRenderer.read2BPPValue(9, 0) == 1); + CHECK(tileRenderer.read2BPPValue(9, 1) == 2); + CHECK(tileRenderer.read2BPPValue(9, 2) == 3); + CHECK(tileRenderer.read2BPPValue(9, 3) == 3); + CHECK(tileRenderer.read2BPPValue(9, 4) == 3); + CHECK(tileRenderer.read2BPPValue(9, 5) == 2); + CHECK(tileRenderer.read2BPPValue(9, 6) == 1); + CHECK(tileRenderer.read2BPPValue(9, 7) == 0); +} + +TEST_CASE("getPixelReferenceFromTileRow 2bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(2); + + vram.write(2, 0xD6); + vram.write(3, 0x00); + + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 0) == 1); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 1) == 1); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 2) == 0); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 3) == 1); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 4) == 0); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 5) == 1); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 6) == 1); + CHECK(tileRenderer.getPixelReferenceFromTileRow(2, 7) == 0); +} + +TEST_CASE("getPixelReferenceFromTileRow 4bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(40, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(4); + + std::vector vramValues { + "7C7C82EE82FE7C7C", + "0000D68254443838", + "7C00AA1082007C00", + "1000540038000000" + }; + + uint8_t value; + int i = 0; + + for (auto row : vramValues) { + while (!row.empty()) { + value = std::stoul(row.substr(0, 2), nullptr, 16); + row.erase(0, 2); + vram.write(i++, value); + } + } + + char correctValues[8][8] = { + {0, 7, 7, 7, 7, 7, 0, 0}, + {7, 2, 6, 8, 6, 2, 7, 0}, + {7, 2, 2, 2, 2, 2, 7, 0}, + {0, 7, 7, 7, 7, 7, 0, 0}, + {0, 0, 0, 4, 0, 0, 0, 0}, + {3, 5, 0, 5, 0, 5, 3, 0}, + {0, 3, 4, 5, 4, 3, 0, 0}, + {0, 0, 3, 3, 3, 0, 0, 0} + }; + + i = 0; + int j = 0; + for (const auto &row : correctValues) { + for (const auto &refValue : row) { + CHECK(tileRenderer.getPixelReferenceFromTileRow(i, j++) == refValue); + } + j = 0; + i += 2; + } +} +/* +TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(8); + + std::vector vramValues { + "0022222223230000", + "2211422141112400", + "2311121212122400", + "0024252525250000", + "0000003300000000", + "3532003100313500", + "0034333133340000", + "0000353636000000", + }; + + uint8_t value; + int i = 0; + + for (auto row : vramValues) { + while (!row.empty()) { + value = std::stoul(row.substr(0, 2), nullptr, 16); + row.erase(0, 2); + vram.write(i++, value); + } + } + + uint8_t correctValues[8][8] = { + {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, + {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, + {0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00}, + {0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00}, + {0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00}, + {0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00}, + {0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00}, + }; + + + i = 0; + int j = 0; + for (const auto &row : correctValues) { + for (const auto &refValue : row) { + std::cout << i << ' ' << j << std::endl; + CHECK(tileRenderer.getPixelReferenceFromTileRow(i, j++) == refValue); + } + j = 0; + i += 2; + } +}*/ \ No newline at end of file From 08259d018fb13996bce786644090fe647da5472e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Fri, 9 Jul 2021 13:57:29 +0200 Subject: [PATCH 27/41] Reenable 8bpp test with new vram test --- tests/PPU/testTileRenderer.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index a4de5e9..4dc0144 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -117,7 +117,7 @@ TEST_CASE("getPixelReferenceFromTileRow 4bpp", "[PPU][TileRenderer]") i += 2; } } -/* + TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") { ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); @@ -127,14 +127,10 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") tileRenderer.setBpp(8); std::vector vramValues { - "0022222223230000", - "2211422141112400", - "2311121212122400", - "0024252525250000", - "0000003300000000", - "3532003100313500", - "0034333133340000", - "0000353636000000", + "0C7C5CA0C0BC3C001010964038282018", + "0000020002007C000000820044003800", + "007C44927C82007C1010D6D67C7C3838", + "00002800000000000000000000000000" }; uint8_t value; @@ -170,4 +166,4 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") j = 0; i += 2; } -}*/ \ No newline at end of file +} From 5e72662d88365f0bd1e7a052a94f1f10560cddc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Fri, 9 Jul 2021 14:02:15 +0200 Subject: [PATCH 28/41] removing debug print in tests --- tests/PPU/testTileRenderer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index 4dc0144..2392394 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -160,7 +160,6 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") int j = 0; for (const auto &row : correctValues) { for (const auto &refValue : row) { - std::cout << i << ' ' << j << std::endl; CHECK(tileRenderer.getPixelReferenceFromTileRow(i, j++) == refValue); } j = 0; From 83ce8c6148b60f39ba77e5c03cecc72ea5bc4a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 11 Jul 2021 17:29:52 +0200 Subject: [PATCH 29/41] adding python script --- Utils/pythonvram.py | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100755 Utils/pythonvram.py diff --git a/Utils/pythonvram.py b/Utils/pythonvram.py new file mode 100755 index 0000000..45674ea --- /dev/null +++ b/Utils/pythonvram.py @@ -0,0 +1,76 @@ + +# python script to convert tile indexes to correct values in vram depending on the bpp + +def getVRAMValue2bpp(nums): + vramValues = [] + + + valHex1 = 0 + valHex2 = 0 + for i in nums: + valHex1 = 0 + valHex2 = 0 + shift = 7 + for j in i: + valHex1 += (j & 1) << shift + valHex2 += ((j & 2) >> 1) << shift + shift -= 1 + + vramValues.append((valHex1 << 8) + valHex2) + + padding = 4 + for i in vramValues: + print('{0:0{1}X}'.format(i, 4), end=' ') + print("") + +def getVRAMValue4bpp(nums): + getVRAMValue2bpp(extract2BppBitPlans(nums, 0)) + getVRAMValue2bpp(extract2BppBitPlans(nums, 1)) + +def getVRAMValue8bpp(nums): + getVRAMValue2bpp(extract2BppBitPlans(nums, 0)) + getVRAMValue2bpp(extract2BppBitPlans(nums, 1)) + getVRAMValue2bpp(extract2BppBitPlans(nums, 2)) + getVRAMValue2bpp(extract2BppBitPlans(nums, 3)) + +def extract2BppBitPlans(nums, index): + high = [] + for i in nums: + high.append([(j & (0x3 << (2 * index))) >> (index * 2) for j in i]) + return high + +result2 = [ + [0, 1, 1, 1, 1, 1, 0, 0], + [1, 2, 3, 3, 3, 2, 1, 0], + [1, 2, 3, 3, 3, 2, 1, 0], + [0, 1, 1, 1, 1, 1, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [1, 1, 0, 1, 0, 1, 1, 0], + [0, 1, 1, 1, 1, 1, 0, 0], + [0, 0, 1, 1, 1, 0, 0, 0] + ] + +result2 = [ + [0, 7, 7, 7, 7, 7, 0, 0], + [7, 2, 6, 8, 6, 2, 7, 0], + [7, 2, 2, 2, 2, 2, 7, 0], + [0, 7, 7, 7, 7, 7, 0, 0], + [0, 0, 0, 4, 0, 0, 0, 0], + [3, 5, 0, 5, 0, 5, 3, 0], + [0, 3, 4, 5, 4, 3, 0, 0], + [0, 0, 3, 3, 3, 0, 0, 0], + ] + +result2 = [ + [0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00], + [0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00], + [0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00], + [0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00], + [0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00], + [0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00], + [0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00] + ] + +getVRAMValue8bpp(result2) + From a5bcc7da17a348009122640f1f01ffb17d43e1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 11 Jul 2021 17:52:27 +0200 Subject: [PATCH 30/41] adding python script --- {Utils => utils}/pythonvram.py | 78 ++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 37 deletions(-) rename {Utils => utils}/pythonvram.py (50%) diff --git a/Utils/pythonvram.py b/utils/pythonvram.py similarity index 50% rename from Utils/pythonvram.py rename to utils/pythonvram.py index 45674ea..e5babb5 100755 --- a/Utils/pythonvram.py +++ b/utils/pythonvram.py @@ -1,10 +1,11 @@ +#!/usr/bin/env python3 + # python script to convert tile indexes to correct values in vram depending on the bpp def getVRAMValue2bpp(nums): vramValues = [] - - + valHex1 = 0 valHex2 = 0 for i in nums: @@ -15,62 +16,65 @@ def getVRAMValue2bpp(nums): valHex1 += (j & 1) << shift valHex2 += ((j & 2) >> 1) << shift shift -= 1 - + vramValues.append((valHex1 << 8) + valHex2) - + padding = 4 for i in vramValues: - print('{0:0{1}X}'.format(i, 4), end=' ') + print(f"{i:0{padding}X}", end=' ') print("") + def getVRAMValue4bpp(nums): getVRAMValue2bpp(extract2BppBitPlans(nums, 0)) getVRAMValue2bpp(extract2BppBitPlans(nums, 1)) + def getVRAMValue8bpp(nums): getVRAMValue2bpp(extract2BppBitPlans(nums, 0)) getVRAMValue2bpp(extract2BppBitPlans(nums, 1)) getVRAMValue2bpp(extract2BppBitPlans(nums, 2)) getVRAMValue2bpp(extract2BppBitPlans(nums, 3)) + def extract2BppBitPlans(nums, index): high = [] for i in nums: high.append([(j & (0x3 << (2 * index))) >> (index * 2) for j in i]) return high - -result2 = [ - [0, 1, 1, 1, 1, 1, 0, 0], - [1, 2, 3, 3, 3, 2, 1, 0], - [1, 2, 3, 3, 3, 2, 1, 0], - [0, 1, 1, 1, 1, 1, 0, 0], - [0, 0, 0, 1, 0, 0, 0, 0], - [1, 1, 0, 1, 0, 1, 1, 0], - [0, 1, 1, 1, 1, 1, 0, 0], - [0, 0, 1, 1, 1, 0, 0, 0] - ] - -result2 = [ - [0, 7, 7, 7, 7, 7, 0, 0], - [7, 2, 6, 8, 6, 2, 7, 0], - [7, 2, 2, 2, 2, 2, 7, 0], - [0, 7, 7, 7, 7, 7, 0, 0], - [0, 0, 0, 4, 0, 0, 0, 0], - [3, 5, 0, 5, 0, 5, 3, 0], - [0, 3, 4, 5, 4, 3, 0, 0], - [0, 0, 3, 3, 3, 0, 0, 0], - ] + result2 = [ - [0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00], - [0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00], - [0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00], - [0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00], - [0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00], - [0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00], - [0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00] - ] + [0, 1, 1, 1, 1, 1, 0, 0], + [1, 2, 3, 3, 3, 2, 1, 0], + [1, 2, 3, 3, 3, 2, 1, 0], + [0, 1, 1, 1, 1, 1, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [1, 1, 0, 1, 0, 1, 1, 0], + [0, 1, 1, 1, 1, 1, 0, 0], + [0, 0, 1, 1, 1, 0, 0, 0] +] + +result2 = [ + [0, 7, 7, 7, 7, 7, 0, 0], + [7, 2, 6, 8, 6, 2, 7, 0], + [7, 2, 2, 2, 2, 2, 7, 0], + [0, 7, 7, 7, 7, 7, 0, 0], + [0, 0, 0, 4, 0, 0, 0, 0], + [3, 5, 0, 5, 0, 5, 3, 0], + [0, 3, 4, 5, 4, 3, 0, 0], + [0, 0, 3, 3, 3, 0, 0, 0], +] + +result2 = [ + [0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00], + [0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00], + [0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00], + [0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00], + [0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00], + [0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00], + [0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00] +] getVRAMValue8bpp(result2) - From 7e2281a6402d7e47289c7984348654e30ac90ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 11 Jul 2021 18:22:57 +0200 Subject: [PATCH 31/41] adding tests on getPixelReferenceFromTile tests --- tests/PPU/testTileRenderer.cpp | 136 +++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 23 deletions(-) diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index 2392394..43c5e7b 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -11,6 +11,20 @@ #include "Ram/Ram.hpp" #include "PPU/Tile.hpp" +void fillRAMFromStrings(const std::vector &values, ComSquare::Ram::Ram &ram) +{ + uint8_t value; + int i = 0; + + for (auto row : values) { + while (!row.empty()) { + value = std::stoul(row.substr(0, 2), nullptr, 16); + row.erase(0, 2); + ram.write(i++, value); + } + } +} + TEST_CASE("read2BPPValue", "[PPU][TileRenderer]") { ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); @@ -85,16 +99,7 @@ TEST_CASE("getPixelReferenceFromTileRow 4bpp", "[PPU][TileRenderer]") "1000540038000000" }; - uint8_t value; - int i = 0; - - for (auto row : vramValues) { - while (!row.empty()) { - value = std::stoul(row.substr(0, 2), nullptr, 16); - row.erase(0, 2); - vram.write(i++, value); - } - } + fillRAMFromStrings(vramValues, vram); char correctValues[8][8] = { {0, 7, 7, 7, 7, 7, 0, 0}, @@ -107,7 +112,7 @@ TEST_CASE("getPixelReferenceFromTileRow 4bpp", "[PPU][TileRenderer]") {0, 0, 3, 3, 3, 0, 0, 0} }; - i = 0; + int i = 0; int j = 0; for (const auto &row : correctValues) { for (const auto &refValue : row) { @@ -133,17 +138,7 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") "00002800000000000000000000000000" }; - uint8_t value; - int i = 0; - - for (auto row : vramValues) { - while (!row.empty()) { - value = std::stoul(row.substr(0, 2), nullptr, 16); - row.erase(0, 2); - vram.write(i++, value); - } - } - + fillRAMFromStrings(vramValues, vram); uint8_t correctValues[8][8] = { {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, @@ -156,7 +151,7 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") }; - i = 0; + int i = 0; int j = 0; for (const auto &row : correctValues) { for (const auto &refValue : row) { @@ -166,3 +161,98 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") i += 2; } } + +TEST_CASE("getPixelReferenceFromTile 2bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(2); + + vram.write(2, 0xD6); + vram.write(3, 0x00); + + CHECK(tileRenderer.getPixelReferenceFromTile(2, 0) == 1); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 1) == 1); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 2) == 0); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 3) == 1); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 4) == 0); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 5) == 1); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 6) == 1); + CHECK(tileRenderer.getPixelReferenceFromTile(2, 7) == 0); +} + +TEST_CASE("getPixelReferenceFromTile 4bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(40, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(4); + + std::vector vramValues { + "7C7C82EE82FE7C7C", + "0000D68254443838", + "7C00AA1082007C00", + "1000540038000000" + }; + + fillRAMFromStrings(vramValues, vram); + + char correctValues[8][8] = { + {0, 7, 7, 7, 7, 7, 0, 0}, + {7, 2, 6, 8, 6, 2, 7, 0}, + {7, 2, 2, 2, 2, 2, 7, 0}, + {0, 7, 7, 7, 7, 7, 0, 0}, + {0, 0, 0, 4, 0, 0, 0, 0}, + {3, 5, 0, 5, 0, 5, 3, 0}, + {0, 3, 4, 5, 4, 3, 0, 0}, + {0, 0, 3, 3, 3, 0, 0, 0} + }; + + int i = 0; + int j = 0; + for (const auto &row : correctValues) { + for (const auto &refValue : row) { + CHECK(tileRenderer.getPixelReferenceFromTile(i, j++) == refValue); + } + } +} + +TEST_CASE("getPixelReferenceFromTile 8bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(8); + + std::vector vramValues { + "0C7C5CA0C0BC3C001010964038282018", + "0000020002007C000000820044003800", + "007C44927C82007C1010D6D67C7C3838", + "00002800000000000000000000000000" + }; + + fillRAMFromStrings(vramValues, vram); + uint8_t correctValues[8][8] = { + {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, + {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, + {0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00}, + {0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00}, + {0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00}, + {0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00}, + {0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00}, + }; + + + int i = 0; + int j = 0; + for (const auto &row : correctValues) { + for (const auto &refValue : row) { + CHECK(tileRenderer.getPixelReferenceFromTile(i, j++) == refValue); + } + } +} From 8a84258c5a2c97c11d18eef253c2867fe03065a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 11 Jul 2021 19:15:46 +0200 Subject: [PATCH 32/41] adding tests for the getPalette function --- sources/PPU/TileRenderer.hpp | 2 + tests/PPU/testTileRenderer.cpp | 281 ++++++++++++++++++++++++++++++++- 2 files changed, 278 insertions(+), 5 deletions(-) diff --git a/sources/PPU/TileRenderer.hpp b/sources/PPU/TileRenderer.hpp index 7444a33..6ea3e13 100644 --- a/sources/PPU/TileRenderer.hpp +++ b/sources/PPU/TileRenderer.hpp @@ -46,7 +46,9 @@ namespace ComSquare::PPU //! @return The color Reference uint8_t getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex); //! @brief Gives the actual selected palette with all of it's colors + //! @param nbPalette The index of the palette wanted //! @return The array of color of the palette + //! @note The return and argument depends on the current bpp //! @warning Values are CGRAM colors use PPU::getRealColor function to get the actual real color std::vector getPalette(int nbPalette); //! @brief read the 2bpp value for a pixel (used multple times for 4bpp and 8bpp) diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index 43c5e7b..1f421ca 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -11,7 +11,7 @@ #include "Ram/Ram.hpp" #include "PPU/Tile.hpp" -void fillRAMFromStrings(const std::vector &values, ComSquare::Ram::Ram &ram) +void fillRAM(const std::vector &values, ComSquare::Ram::Ram &ram) { uint8_t value; int i = 0; @@ -25,6 +25,16 @@ void fillRAMFromStrings(const std::vector &values, ComSquare::Ram:: } } +void fillRAM(const std::vector &values, ComSquare::Ram::Ram &ram) +{ + int i = 0; + + for (const auto &value : values) { + ram.write(i++, value); + } +} + + TEST_CASE("read2BPPValue", "[PPU][TileRenderer]") { ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); @@ -99,7 +109,7 @@ TEST_CASE("getPixelReferenceFromTileRow 4bpp", "[PPU][TileRenderer]") "1000540038000000" }; - fillRAMFromStrings(vramValues, vram); + fillRAM(vramValues, vram); char correctValues[8][8] = { {0, 7, 7, 7, 7, 7, 0, 0}, @@ -138,7 +148,7 @@ TEST_CASE("getPixelReferenceFromTileRow 8bpp", "[PPU][TileRenderer]") "00002800000000000000000000000000" }; - fillRAMFromStrings(vramValues, vram); + fillRAM(vramValues, vram); uint8_t correctValues[8][8] = { {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, @@ -198,7 +208,7 @@ TEST_CASE("getPixelReferenceFromTile 4bpp", "[PPU][TileRenderer]") "1000540038000000" }; - fillRAMFromStrings(vramValues, vram); + fillRAM(vramValues, vram); char correctValues[8][8] = { {0, 7, 7, 7, 7, 7, 0, 0}, @@ -235,7 +245,7 @@ TEST_CASE("getPixelReferenceFromTile 8bpp", "[PPU][TileRenderer]") "00002800000000000000000000000000" }; - fillRAMFromStrings(vramValues, vram); + fillRAM(vramValues, vram); uint8_t correctValues[8][8] = { {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, @@ -256,3 +266,264 @@ TEST_CASE("getPixelReferenceFromTile 8bpp", "[PPU][TileRenderer]") } } } + +TEST_CASE("getPalette 2bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(2); + + std::vector cgram_dump = { + 0xCE, 0x69, 0xDF, 0x63, 0xDE, 0x16, 0x8B, 0x00, 0x00, 0x00, 0xBF, 0x67, 0x98, 0x42, 0x0E, 0x15, 0x00, 0x00, + 0xBF, 0x4B, 0xDD, 0x01, 0xCB, 0x0C, 0x00, 0x00, 0xDF, 0x55, 0x3C, 0x0C, 0x8B, 0x10, 0xCE, 0x69, 0x95, 0x7A, + 0x74, 0x76, 0x53, 0x72, 0x32, 0x6E, 0x11, 0x6A, 0xF0, 0x69, 0xEF, 0x69, 0xDC, 0x7B, 0x16, 0x67, 0x73, 0x5A, + 0x0F, 0x42, 0x4C, 0x31, 0xE9, 0x24, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0xA9, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0xCE, 0x69, 0xC7, 0x18, 0xBC, 0x3E, 0x1B, 0x2E, 0x96, 0x4E, 0x2B, 0x41, + 0xCD, 0x10, 0x39, 0x57, 0xF2, 0x35, 0x8E, 0x29, 0x09, 0x1D, 0x16, 0x26, 0x8A, 0x10, 0xE9, 0x34, 0x76, 0x21, + 0x34, 0x19, 0xDF, 0x57, 0xB2, 0x64, 0xAF, 0x54, 0xCE, 0x3C, 0x57, 0x22, 0x71, 0x19, 0xCC, 0x20, 0xF7, 0x51, + 0xCB, 0x0C, 0x15, 0x75, 0xB9, 0x21, 0x76, 0x21, 0x54, 0x1D, 0x12, 0x15, 0xF0, 0x10, 0xCD, 0x0C, 0xCE, 0x69, + 0x5F, 0x3B, 0xDC, 0x3A, 0x3B, 0x26, 0xB7, 0x19, 0x53, 0x15, 0xED, 0x10, 0xA9, 0x0C, 0xFE, 0x59, 0x5B, 0x41, + 0xF6, 0x34, 0xB3, 0x28, 0x90, 0x20, 0x6E, 0x18, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDE, 0x5F, 0xFC, 0x3A, + 0x79, 0x26, 0xF5, 0x19, 0x71, 0x15, 0x0B, 0x11, 0xC8, 0x0C, 0x94, 0x5F, 0x29, 0x3F, 0x69, 0x3A, 0xA9, 0x35, + 0x47, 0x2D, 0x04, 0x2D, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0x17, 0x2E, 0x37, 0x2E, 0xF5, 0x25, 0xB3, 0x21, + 0x71, 0x21, 0x2F, 0x25, 0x6E, 0x35, 0x11, 0x6A, 0xEE, 0x08, 0xB0, 0x51, 0xD2, 0x18, 0xD0, 0x1C, 0x11, 0x0D, + 0x7A, 0x36, 0x0E, 0x21, 0x0B, 0x46, 0x37, 0x2E, 0xBA, 0x42, 0x7D, 0x63, 0xCF, 0x04, 0x38, 0x09, 0x1C, 0x2A, + 0xDC, 0x4A, 0x1C, 0x14, 0x28, 0x44, 0x6F, 0x58, 0x52, 0x6D, 0x91, 0x1D, 0x2C, 0x11, 0xA8, 0x14, 0x00, 0x00, + 0x48, 0x2D, 0x6A, 0x00, 0xCE, 0x08, 0x78, 0x0D, 0xFC, 0x15, 0xBE, 0x1E, 0x5C, 0x63, 0x33, 0x46, 0x0A, 0x6D, + 0x46, 0x30, 0xBA, 0x14, 0xB1, 0x75, 0x13, 0x0D, 0x0C, 0x08, 0xC9, 0x38, 0x00, 0x00, 0xF0, 0x31, 0xAA, 0x04, + 0xE0, 0x14, 0x80, 0x05, 0x00, 0x53, 0x80, 0x73, 0x9C, 0x7F, 0x10, 0x00, 0x3C, 0x0C, 0xDF, 0x55, 0xFC, 0x26, + 0x9E, 0x5B, 0x5C, 0x32, 0xD7, 0x21, 0x12, 0x11, 0x8E, 0x08, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0x88, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0x30, 0x15, 0x0A, 0x0D, 0x2C, 0x11, 0x4D, 0x19, 0xF3, 0x25, 0x35, 0x36, + 0xB9, 0x4A, 0x74, 0x42, 0x19, 0x57, 0xF0, 0x31, 0x9C, 0x73, 0xCC, 0x00, 0x10, 0x01, 0x76, 0x01, 0x3E, 0x03, + 0x00, 0x00, 0xEA, 0x29, 0xE6, 0x00, 0x07, 0x09, 0x29, 0x11, 0x8C, 0x19, 0xEE, 0x21, 0x50, 0x2A, 0xB2, 0x32, + 0x34, 0x43, 0xA0, 0x01, 0x40, 0x02, 0xE1, 0x16, 0x80, 0x2B, 0x9C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x88, 0x29, + 0x6F, 0x21, 0x98, 0x3E, 0x7D, 0x63, 0xED, 0x04, 0xEF, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0xDD, 0x3E, 0x3C, 0x4F, + 0xF1, 0x00, 0x1C, 0x00, 0x3B, 0x01, 0x9E, 0x02, 0xA5, 0x14, 0x00, 0x00, 0x88, 0x29, 0xD3, 0x2D, 0x4D, 0x19, + 0xF9, 0x52, 0xAB, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0x35, 0x32, 0x0D, 0x00, 0x05, 0x28, 0x66, 0x40, 0x9A, 0x10, + 0xC9, 0x0C, 0xD2, 0x25, 0xA5, 0x14, 0x00, 0x00 + }; + + fillRAM(cgram_dump, cgram); + uint16_t correctValues[64][4] = { + {0x69ce, 0x63df, 0x16de, 0x008b}, + {0x0000, 0x67bf, 0x4298, 0x150e}, + {0x0000, 0x4bbf, 0x01dd, 0x0ccb}, + {0x0000, 0x55df, 0x0c3c, 0x108b}, + {0x69ce, 0x7a95, 0x7674, 0x7253}, + {0x6e32, 0x6a11, 0x69f0, 0x69ef}, + {0x7bdc, 0x6716, 0x5a73, 0x420f}, + {0x314c, 0x24e9, 0x2176, 0x1934}, + {0x69ce, 0x57df, 0x473c, 0x3adb}, + {0x2e78, 0x2616, 0x19b4, 0x1152}, + {0x08a9, 0x3abe, 0x261b, 0x2199}, + {0x2176, 0x1934, 0x0d0f, 0x10eb}, + {0x69ce, 0x18c7, 0x3ebc, 0x2e1b}, + {0x4e96, 0x412b, 0x10cd, 0x5739}, + {0x35f2, 0x298e, 0x1d09, 0x2616}, + {0x108a, 0x34e9, 0x2176, 0x1934}, + {0x57df, 0x64b2, 0x54af, 0x3cce}, + {0x2257, 0x1971, 0x20cc, 0x51f7}, + {0x0ccb, 0x7515, 0x21b9, 0x2176}, + {0x1d54, 0x1512, 0x10f0, 0x0ccd}, + {0x69ce, 0x3b5f, 0x3adc, 0x263b}, + {0x19b7, 0x1553, 0x10ed, 0x0ca9}, + {0x59fe, 0x415b, 0x34f6, 0x28b3}, + {0x2090, 0x186e, 0x2176, 0x1934}, + {0x69ce, 0x5fde, 0x3afc, 0x2679}, + {0x19f5, 0x1571, 0x110b, 0x0cc8}, + {0x5f94, 0x3f29, 0x3a69, 0x35a9}, + {0x2d47, 0x2d04, 0x2176, 0x1934}, + {0x69ce, 0x2e17, 0x2e37, 0x25f5}, + {0x21b3, 0x2171, 0x252f, 0x356e}, + {0x6a11, 0x08ee, 0x51b0, 0x18d2}, + {0x1cd0, 0x0d11, 0x367a, 0x210e}, + {0x460b, 0x2e37, 0x42ba, 0x637d}, + {0x04cf, 0x0938, 0x2a1c, 0x4adc}, + {0x141c, 0x4428, 0x586f, 0x6d52}, + {0x1d91, 0x112c, 0x14a8, 0x0000}, + {0x2d48, 0x006a, 0x08ce, 0x0d78}, + {0x15fc, 0x1ebe, 0x635c, 0x4633}, + {0x6d0a, 0x3046, 0x14ba, 0x75b1}, + {0x0d13, 0x080c, 0x38c9, 0x0000}, + {0x31f0, 0x04aa, 0x14e0, 0x0580}, + {0x5300, 0x7380, 0x7f9c, 0x0010}, + {0x0c3c, 0x55df, 0x26fc, 0x5b9e}, + {0x325c, 0x21d7, 0x1112, 0x088e}, + {0x69ce, 0x57df, 0x473c, 0x3adb}, + {0x2e78, 0x2616, 0x19b4, 0x1152}, + {0x0888, 0x3abe, 0x261b, 0x2199}, + {0x2176, 0x1934, 0x0d0f, 0x10eb}, + {0x1530, 0x0d0a, 0x112c, 0x194d}, + {0x25f3, 0x3635, 0x4ab9, 0x4274}, + {0x5719, 0x31f0, 0x739c, 0x00cc}, + {0x0110, 0x0176, 0x033e, 0x0000}, + {0x29ea, 0x00e6, 0x0907, 0x1129}, + {0x198c, 0x21ee, 0x2a50, 0x32b2}, + {0x4334, 0x01a0, 0x0240, 0x16e1}, + {0x2b80, 0x739c, 0x0000, 0x0000}, + {0x2988, 0x216f, 0x3e98, 0x637d}, + {0x04ed, 0x08ef, 0x1556, 0x2e5c}, + {0x3edd, 0x4f3c, 0x00f1, 0x001c}, + {0x013b, 0x029e, 0x14a5, 0x0000}, + {0x2988, 0x2dd3, 0x194d, 0x52f9}, + {0x08ab, 0x1556, 0x2e5c, 0x3235}, + {0x000d, 0x2805, 0x4066, 0x109a}, + {0x0cc9, 0x25d2, 0x14a5, 0x0000} + }; + + int i = 0; + int j = 0; + for (const auto &row : correctValues) { + const auto &palette = tileRenderer.getPalette(j++); + for (const auto &refValue : row) { + CHECK(palette.at(i++) == refValue); + } + i = 0; + } +} + +TEST_CASE("getPalette 4bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(4); + + std::vector cgram_dump = { + 0xCE, 0x69, 0xDF, 0x63, 0xDE, 0x16, 0x8B, 0x00, 0x00, 0x00, 0xBF, 0x67, 0x98, 0x42, 0x0E, 0x15, 0x00, 0x00, + 0xBF, 0x4B, 0xDD, 0x01, 0xCB, 0x0C, 0x00, 0x00, 0xDF, 0x55, 0x3C, 0x0C, 0x8B, 0x10, 0xCE, 0x69, 0x95, 0x7A, + 0x74, 0x76, 0x53, 0x72, 0x32, 0x6E, 0x11, 0x6A, 0xF0, 0x69, 0xEF, 0x69, 0xDC, 0x7B, 0x16, 0x67, 0x73, 0x5A, + 0x0F, 0x42, 0x4C, 0x31, 0xE9, 0x24, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0xA9, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0xCE, 0x69, 0xC7, 0x18, 0xBC, 0x3E, 0x1B, 0x2E, 0x96, 0x4E, 0x2B, 0x41, + 0xCD, 0x10, 0x39, 0x57, 0xF2, 0x35, 0x8E, 0x29, 0x09, 0x1D, 0x16, 0x26, 0x8A, 0x10, 0xE9, 0x34, 0x76, 0x21, + 0x34, 0x19, 0xDF, 0x57, 0xB2, 0x64, 0xAF, 0x54, 0xCE, 0x3C, 0x57, 0x22, 0x71, 0x19, 0xCC, 0x20, 0xF7, 0x51, + 0xCB, 0x0C, 0x15, 0x75, 0xB9, 0x21, 0x76, 0x21, 0x54, 0x1D, 0x12, 0x15, 0xF0, 0x10, 0xCD, 0x0C, 0xCE, 0x69, + 0x5F, 0x3B, 0xDC, 0x3A, 0x3B, 0x26, 0xB7, 0x19, 0x53, 0x15, 0xED, 0x10, 0xA9, 0x0C, 0xFE, 0x59, 0x5B, 0x41, + 0xF6, 0x34, 0xB3, 0x28, 0x90, 0x20, 0x6E, 0x18, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDE, 0x5F, 0xFC, 0x3A, + 0x79, 0x26, 0xF5, 0x19, 0x71, 0x15, 0x0B, 0x11, 0xC8, 0x0C, 0x94, 0x5F, 0x29, 0x3F, 0x69, 0x3A, 0xA9, 0x35, + 0x47, 0x2D, 0x04, 0x2D, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0x17, 0x2E, 0x37, 0x2E, 0xF5, 0x25, 0xB3, 0x21, + 0x71, 0x21, 0x2F, 0x25, 0x6E, 0x35, 0x11, 0x6A, 0xEE, 0x08, 0xB0, 0x51, 0xD2, 0x18, 0xD0, 0x1C, 0x11, 0x0D, + 0x7A, 0x36, 0x0E, 0x21, 0x0B, 0x46, 0x37, 0x2E, 0xBA, 0x42, 0x7D, 0x63, 0xCF, 0x04, 0x38, 0x09, 0x1C, 0x2A, + 0xDC, 0x4A, 0x1C, 0x14, 0x28, 0x44, 0x6F, 0x58, 0x52, 0x6D, 0x91, 0x1D, 0x2C, 0x11, 0xA8, 0x14, 0x00, 0x00, + 0x48, 0x2D, 0x6A, 0x00, 0xCE, 0x08, 0x78, 0x0D, 0xFC, 0x15, 0xBE, 0x1E, 0x5C, 0x63, 0x33, 0x46, 0x0A, 0x6D, + 0x46, 0x30, 0xBA, 0x14, 0xB1, 0x75, 0x13, 0x0D, 0x0C, 0x08, 0xC9, 0x38, 0x00, 0x00, 0xF0, 0x31, 0xAA, 0x04, + 0xE0, 0x14, 0x80, 0x05, 0x00, 0x53, 0x80, 0x73, 0x9C, 0x7F, 0x10, 0x00, 0x3C, 0x0C, 0xDF, 0x55, 0xFC, 0x26, + 0x9E, 0x5B, 0x5C, 0x32, 0xD7, 0x21, 0x12, 0x11, 0x8E, 0x08, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0x88, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0x30, 0x15, 0x0A, 0x0D, 0x2C, 0x11, 0x4D, 0x19, 0xF3, 0x25, 0x35, 0x36, + 0xB9, 0x4A, 0x74, 0x42, 0x19, 0x57, 0xF0, 0x31, 0x9C, 0x73, 0xCC, 0x00, 0x10, 0x01, 0x76, 0x01, 0x3E, 0x03, + 0x00, 0x00, 0xEA, 0x29, 0xE6, 0x00, 0x07, 0x09, 0x29, 0x11, 0x8C, 0x19, 0xEE, 0x21, 0x50, 0x2A, 0xB2, 0x32, + 0x34, 0x43, 0xA0, 0x01, 0x40, 0x02, 0xE1, 0x16, 0x80, 0x2B, 0x9C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x88, 0x29, + 0x6F, 0x21, 0x98, 0x3E, 0x7D, 0x63, 0xED, 0x04, 0xEF, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0xDD, 0x3E, 0x3C, 0x4F, + 0xF1, 0x00, 0x1C, 0x00, 0x3B, 0x01, 0x9E, 0x02, 0xA5, 0x14, 0x00, 0x00, 0x88, 0x29, 0xD3, 0x2D, 0x4D, 0x19, + 0xF9, 0x52, 0xAB, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0x35, 0x32, 0x0D, 0x00, 0x05, 0x28, 0x66, 0x40, 0x9A, 0x10, + 0xC9, 0x0C, 0xD2, 0x25, 0xA5, 0x14, 0x00, 0x00 + }; + + fillRAM(cgram_dump, cgram); + uint16_t correctValues[16][16] = { + {0x69ce, 0x63df, 0x16de, 0x008b, 0x0000, 0x67bf, 0x4298, 0x150e, 0x0000, 0x4bbf, 0x01dd, 0x0ccb, 0x0000, 0x55df, 0x0c3c, 0x108b}, + {0x69ce, 0x7a95, 0x7674, 0x7253, 0x6e32, 0x6a11, 0x69f0, 0x69ef, 0x7bdc, 0x6716, 0x5a73, 0x420f, 0x314c, 0x24e9, 0x2176, 0x1934}, + {0x69ce, 0x57df, 0x473c, 0x3adb, 0x2e78, 0x2616, 0x19b4, 0x1152, 0x08a9, 0x3abe, 0x261b, 0x2199, 0x2176, 0x1934, 0x0d0f, 0x10eb}, + {0x69ce, 0x18c7, 0x3ebc, 0x2e1b, 0x4e96, 0x412b, 0x10cd, 0x5739, 0x35f2, 0x298e, 0x1d09, 0x2616, 0x108a, 0x34e9, 0x2176, 0x1934}, + {0x57df, 0x64b2, 0x54af, 0x3cce, 0x2257, 0x1971, 0x20cc, 0x51f7, 0x0ccb, 0x7515, 0x21b9, 0x2176, 0x1d54, 0x1512, 0x10f0, 0x0ccd}, + {0x69ce, 0x3b5f, 0x3adc, 0x263b, 0x19b7, 0x1553, 0x10ed, 0x0ca9, 0x59fe, 0x415b, 0x34f6, 0x28b3, 0x2090, 0x186e, 0x2176, 0x1934}, + {0x69ce, 0x5fde, 0x3afc, 0x2679, 0x19f5, 0x1571, 0x110b, 0x0cc8, 0x5f94, 0x3f29, 0x3a69, 0x35a9, 0x2d47, 0x2d04, 0x2176, 0x1934}, + {0x69ce, 0x2e17, 0x2e37, 0x25f5, 0x21b3, 0x2171, 0x252f, 0x356e, 0x6a11, 0x08ee, 0x51b0, 0x18d2, 0x1cd0, 0x0d11, 0x367a, 0x210e}, + {0x460b, 0x2e37, 0x42ba, 0x637d, 0x04cf, 0x0938, 0x2a1c, 0x4adc, 0x141c, 0x4428, 0x586f, 0x6d52, 0x1d91, 0x112c, 0x14a8, 0x0000}, + {0x2d48, 0x006a, 0x08ce, 0x0d78, 0x15fc, 0x1ebe, 0x635c, 0x4633, 0x6d0a, 0x3046, 0x14ba, 0x75b1, 0x0d13, 0x080c, 0x38c9, 0x0000}, + {0x31f0, 0x04aa, 0x14e0, 0x0580, 0x5300, 0x7380, 0x7f9c, 0x0010, 0x0c3c, 0x55df, 0x26fc, 0x5b9e, 0x325c, 0x21d7, 0x1112, 0x088e}, + {0x69ce, 0x57df, 0x473c, 0x3adb, 0x2e78, 0x2616, 0x19b4, 0x1152, 0x0888, 0x3abe, 0x261b, 0x2199, 0x2176, 0x1934, 0x0d0f, 0x10eb}, + {0x1530, 0x0d0a, 0x112c, 0x194d, 0x25f3, 0x3635, 0x4ab9, 0x4274, 0x5719, 0x31f0, 0x739c, 0x00cc, 0x0110, 0x0176, 0x033e, 0x0000}, + {0x29ea, 0x00e6, 0x0907, 0x1129, 0x198c, 0x21ee, 0x2a50, 0x32b2, 0x4334, 0x01a0, 0x0240, 0x16e1, 0x2b80, 0x739c, 0x0000, 0x0000}, + {0x2988, 0x216f, 0x3e98, 0x637d, 0x04ed, 0x08ef, 0x1556, 0x2e5c, 0x3edd, 0x4f3c, 0x00f1, 0x001c, 0x013b, 0x029e, 0x14a5, 0x0000}, + {0x2988, 0x2dd3, 0x194d, 0x52f9, 0x08ab, 0x1556, 0x2e5c, 0x3235, 0x000d, 0x2805, 0x4066, 0x109a, 0x0cc9, 0x25d2, 0x14a5, 0x0000} + }; + + int i = 0; + int j = 0; + for (const auto &row : correctValues) { + const auto &palette = tileRenderer.getPalette(j++); + for (const auto &refValue : row) { + CHECK(palette.at(i++) == refValue); + } + i = 0; + } +} + +TEST_CASE("getPalette 8bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(10, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(8); + + std::vector cgram_dump = { + 0xCE, 0x69, 0xDF, 0x63, 0xDE, 0x16, 0x8B, 0x00, 0x00, 0x00, 0xBF, 0x67, 0x98, 0x42, 0x0E, 0x15, 0x00, 0x00, + 0xBF, 0x4B, 0xDD, 0x01, 0xCB, 0x0C, 0x00, 0x00, 0xDF, 0x55, 0x3C, 0x0C, 0x8B, 0x10, 0xCE, 0x69, 0x95, 0x7A, + 0x74, 0x76, 0x53, 0x72, 0x32, 0x6E, 0x11, 0x6A, 0xF0, 0x69, 0xEF, 0x69, 0xDC, 0x7B, 0x16, 0x67, 0x73, 0x5A, + 0x0F, 0x42, 0x4C, 0x31, 0xE9, 0x24, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0xA9, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0xCE, 0x69, 0xC7, 0x18, 0xBC, 0x3E, 0x1B, 0x2E, 0x96, 0x4E, 0x2B, 0x41, + 0xCD, 0x10, 0x39, 0x57, 0xF2, 0x35, 0x8E, 0x29, 0x09, 0x1D, 0x16, 0x26, 0x8A, 0x10, 0xE9, 0x34, 0x76, 0x21, + 0x34, 0x19, 0xDF, 0x57, 0xB2, 0x64, 0xAF, 0x54, 0xCE, 0x3C, 0x57, 0x22, 0x71, 0x19, 0xCC, 0x20, 0xF7, 0x51, + 0xCB, 0x0C, 0x15, 0x75, 0xB9, 0x21, 0x76, 0x21, 0x54, 0x1D, 0x12, 0x15, 0xF0, 0x10, 0xCD, 0x0C, 0xCE, 0x69, + 0x5F, 0x3B, 0xDC, 0x3A, 0x3B, 0x26, 0xB7, 0x19, 0x53, 0x15, 0xED, 0x10, 0xA9, 0x0C, 0xFE, 0x59, 0x5B, 0x41, + 0xF6, 0x34, 0xB3, 0x28, 0x90, 0x20, 0x6E, 0x18, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0xDE, 0x5F, 0xFC, 0x3A, + 0x79, 0x26, 0xF5, 0x19, 0x71, 0x15, 0x0B, 0x11, 0xC8, 0x0C, 0x94, 0x5F, 0x29, 0x3F, 0x69, 0x3A, 0xA9, 0x35, + 0x47, 0x2D, 0x04, 0x2D, 0x76, 0x21, 0x34, 0x19, 0xCE, 0x69, 0x17, 0x2E, 0x37, 0x2E, 0xF5, 0x25, 0xB3, 0x21, + 0x71, 0x21, 0x2F, 0x25, 0x6E, 0x35, 0x11, 0x6A, 0xEE, 0x08, 0xB0, 0x51, 0xD2, 0x18, 0xD0, 0x1C, 0x11, 0x0D, + 0x7A, 0x36, 0x0E, 0x21, 0x0B, 0x46, 0x37, 0x2E, 0xBA, 0x42, 0x7D, 0x63, 0xCF, 0x04, 0x38, 0x09, 0x1C, 0x2A, + 0xDC, 0x4A, 0x1C, 0x14, 0x28, 0x44, 0x6F, 0x58, 0x52, 0x6D, 0x91, 0x1D, 0x2C, 0x11, 0xA8, 0x14, 0x00, 0x00, + 0x48, 0x2D, 0x6A, 0x00, 0xCE, 0x08, 0x78, 0x0D, 0xFC, 0x15, 0xBE, 0x1E, 0x5C, 0x63, 0x33, 0x46, 0x0A, 0x6D, + 0x46, 0x30, 0xBA, 0x14, 0xB1, 0x75, 0x13, 0x0D, 0x0C, 0x08, 0xC9, 0x38, 0x00, 0x00, 0xF0, 0x31, 0xAA, 0x04, + 0xE0, 0x14, 0x80, 0x05, 0x00, 0x53, 0x80, 0x73, 0x9C, 0x7F, 0x10, 0x00, 0x3C, 0x0C, 0xDF, 0x55, 0xFC, 0x26, + 0x9E, 0x5B, 0x5C, 0x32, 0xD7, 0x21, 0x12, 0x11, 0x8E, 0x08, 0xCE, 0x69, 0xDF, 0x57, 0x3C, 0x47, 0xDB, 0x3A, + 0x78, 0x2E, 0x16, 0x26, 0xB4, 0x19, 0x52, 0x11, 0x88, 0x08, 0xBE, 0x3A, 0x1B, 0x26, 0x99, 0x21, 0x76, 0x21, + 0x34, 0x19, 0x0F, 0x0D, 0xEB, 0x10, 0x30, 0x15, 0x0A, 0x0D, 0x2C, 0x11, 0x4D, 0x19, 0xF3, 0x25, 0x35, 0x36, + 0xB9, 0x4A, 0x74, 0x42, 0x19, 0x57, 0xF0, 0x31, 0x9C, 0x73, 0xCC, 0x00, 0x10, 0x01, 0x76, 0x01, 0x3E, 0x03, + 0x00, 0x00, 0xEA, 0x29, 0xE6, 0x00, 0x07, 0x09, 0x29, 0x11, 0x8C, 0x19, 0xEE, 0x21, 0x50, 0x2A, 0xB2, 0x32, + 0x34, 0x43, 0xA0, 0x01, 0x40, 0x02, 0xE1, 0x16, 0x80, 0x2B, 0x9C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x88, 0x29, + 0x6F, 0x21, 0x98, 0x3E, 0x7D, 0x63, 0xED, 0x04, 0xEF, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0xDD, 0x3E, 0x3C, 0x4F, + 0xF1, 0x00, 0x1C, 0x00, 0x3B, 0x01, 0x9E, 0x02, 0xA5, 0x14, 0x00, 0x00, 0x88, 0x29, 0xD3, 0x2D, 0x4D, 0x19, + 0xF9, 0x52, 0xAB, 0x08, 0x56, 0x15, 0x5C, 0x2E, 0x35, 0x32, 0x0D, 0x00, 0x05, 0x28, 0x66, 0x40, 0x9A, 0x10, + 0xC9, 0x0C, 0xD2, 0x25, 0xA5, 0x14, 0x00, 0x00 + }; + + fillRAM(cgram_dump, cgram); + uint16_t correctValues[1][256] = { + {0x69ce, 0x63df, 0x16de, 0x008b, 0x0000, 0x67bf, 0x4298, 0x150e, 0x0000, 0x4bbf, 0x01dd, 0x0ccb, 0x0000, 0x55df, 0x0c3c, 0x108b, + 0x69ce, 0x7a95, 0x7674, 0x7253, 0x6e32, 0x6a11, 0x69f0, 0x69ef, 0x7bdc, 0x6716, 0x5a73, 0x420f, 0x314c, 0x24e9, 0x2176, 0x1934, + 0x69ce, 0x57df, 0x473c, 0x3adb, 0x2e78, 0x2616, 0x19b4, 0x1152, 0x08a9, 0x3abe, 0x261b, 0x2199, 0x2176, 0x1934, 0x0d0f, 0x10eb, + 0x69ce, 0x18c7, 0x3ebc, 0x2e1b, 0x4e96, 0x412b, 0x10cd, 0x5739, 0x35f2, 0x298e, 0x1d09, 0x2616, 0x108a, 0x34e9, 0x2176, 0x1934, + 0x57df, 0x64b2, 0x54af, 0x3cce, 0x2257, 0x1971, 0x20cc, 0x51f7, 0x0ccb, 0x7515, 0x21b9, 0x2176, 0x1d54, 0x1512, 0x10f0, 0x0ccd, + 0x69ce, 0x3b5f, 0x3adc, 0x263b, 0x19b7, 0x1553, 0x10ed, 0x0ca9, 0x59fe, 0x415b, 0x34f6, 0x28b3, 0x2090, 0x186e, 0x2176, 0x1934, + 0x69ce, 0x5fde, 0x3afc, 0x2679, 0x19f5, 0x1571, 0x110b, 0x0cc8, 0x5f94, 0x3f29, 0x3a69, 0x35a9, 0x2d47, 0x2d04, 0x2176, 0x1934, + 0x69ce, 0x2e17, 0x2e37, 0x25f5, 0x21b3, 0x2171, 0x252f, 0x356e, 0x6a11, 0x08ee, 0x51b0, 0x18d2, 0x1cd0, 0x0d11, 0x367a, 0x210e, + 0x460b, 0x2e37, 0x42ba, 0x637d, 0x04cf, 0x0938, 0x2a1c, 0x4adc, 0x141c, 0x4428, 0x586f, 0x6d52, 0x1d91, 0x112c, 0x14a8, 0x0000, + 0x2d48, 0x006a, 0x08ce, 0x0d78, 0x15fc, 0x1ebe, 0x635c, 0x4633, 0x6d0a, 0x3046, 0x14ba, 0x75b1, 0x0d13, 0x080c, 0x38c9, 0x0000, + 0x31f0, 0x04aa, 0x14e0, 0x0580, 0x5300, 0x7380, 0x7f9c, 0x0010, 0x0c3c, 0x55df, 0x26fc, 0x5b9e, 0x325c, 0x21d7, 0x1112, 0x088e, + 0x69ce, 0x57df, 0x473c, 0x3adb, 0x2e78, 0x2616, 0x19b4, 0x1152, 0x0888, 0x3abe, 0x261b, 0x2199, 0x2176, 0x1934, 0x0d0f, 0x10eb, + 0x1530, 0x0d0a, 0x112c, 0x194d, 0x25f3, 0x3635, 0x4ab9, 0x4274, 0x5719, 0x31f0, 0x739c, 0x00cc, 0x0110, 0x0176, 0x033e, 0x0000, + 0x29ea, 0x00e6, 0x0907, 0x1129, 0x198c, 0x21ee, 0x2a50, 0x32b2, 0x4334, 0x01a0, 0x0240, 0x16e1, 0x2b80, 0x739c, 0x0000, 0x0000, + 0x2988, 0x216f, 0x3e98, 0x637d, 0x04ed, 0x08ef, 0x1556, 0x2e5c, 0x3edd, 0x4f3c, 0x00f1, 0x001c, 0x013b, 0x029e, 0x14a5, 0x0000, + 0x2988, 0x2dd3, 0x194d, 0x52f9, 0x08ab, 0x1556, 0x2e5c, 0x3235, 0x000d, 0x2805, 0x4066, 0x109a, 0x0cc9, 0x25d2, 0x14a5, 0x0000} + }; + + int i = 0; + int j = 0; + for (const auto &row : correctValues) { + const auto &palette = tileRenderer.getPalette(j++); + for (const auto &refValue : row) { + CHECK(palette.at(i++) == refValue); + } + i = 0; + } +} \ No newline at end of file From 09520658a1f4eb6b731f8e406c3e8a5410d8dee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Sun, 11 Jul 2021 20:10:39 +0200 Subject: [PATCH 33/41] adding test for render in 2bpp and using mesen formula for getRealColor function --- sources/Debugger/CGramDebug.cpp | 26 +++++++----------- sources/PPU/PPUUtils.cpp | 19 ++++++------- sources/PPU/PPUUtils.hpp | 4 +-- tests/PPU/testTileRenderer.cpp | 47 +++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/sources/Debugger/CGramDebug.cpp b/sources/Debugger/CGramDebug.cpp index 387f4f9..ad5ae94 100644 --- a/sources/Debugger/CGramDebug.cpp +++ b/sources/Debugger/CGramDebug.cpp @@ -8,6 +8,7 @@ #include #include #include "Utility/Utility.hpp" +#include "PPU/PPUUtils.hpp" namespace ComSquare::Debugger { @@ -45,16 +46,14 @@ namespace ComSquare::Debugger uint8_t blue = (cgramValue & 0x7D00U) >> 10U; uint8_t green = (cgramValue & 0x03E0U) >> 5U; uint8_t red = (cgramValue & 0x001FU); - uint24_t hexColorValue = 0; + uint32_t hexColorValue = PPU::Utils::getRealColor(cgramValue); this->_ui.indexLineEdit->setText(std::to_string(addr / 2).c_str()); this->_ui.valueLineEdit->setText(Utility::to_hex(cgramValue).c_str()); this->_ui.rLineEdit->setText(std::to_string(red).c_str()); this->_ui.gLineEdit->setText(std::to_string(green).c_str()); this->_ui.bLineEdit->setText(std::to_string(blue).c_str()); - hexColorValue += (red * 255U / 31U) << 16U; - hexColorValue += (green * 255U / 31U) << 8U; - hexColorValue += (blue * 255U / 31U); + hexColorValue >>= 8; this->_ui.hexLineEdit->setText(Utility::to_hex(hexColorValue).c_str()); } @@ -81,27 +80,20 @@ namespace ComSquare::Debugger QVariant CGramModel::data(const QModelIndex &index, int role) const { - u_int16_t addressValue; - uint8_t red; - uint8_t green; - uint8_t blue; if (role == Qt::TextAlignmentRole) return Qt::AlignCenter; if (role != Qt::BackgroundRole) return QVariant(); + int idDisplayTile = index.row() * 16 + index.column(); uint16_t cgramAddress = idDisplayTile / 8 * 16 + (idDisplayTile % 8 * 2); - addressValue = this->_ppu.cgramRead(cgramAddress); + uint16_t addressValue = this->_ppu.cgramRead(cgramAddress); addressValue += this->_ppu.cgramRead(cgramAddress + 1) << 8U; + uint32_t color = PPU::Utils::getRealColor(addressValue); - blue = (addressValue & 0x7D00U) >> 10U; - green = (addressValue & 0x03E0U) >> 5U; - red = (addressValue & 0x001FU); - - red = red * 255U / 31U; - green = green * 255U / 31U; - blue = blue * 255U / 31U; - return QColor(red, green, blue); + return QColor(static_cast((color & 0xFF000000) >> 24), + static_cast((color & 0x00FF0000) >> 16), + static_cast((color & 0x0000FF00) >> 8)); } } \ No newline at end of file diff --git a/sources/PPU/PPUUtils.cpp b/sources/PPU/PPUUtils.cpp index eb41ab1..2ea779a 100644 --- a/sources/PPU/PPUUtils.cpp +++ b/sources/PPU/PPUUtils.cpp @@ -7,16 +7,17 @@ namespace ComSquare::PPU::Utils { - uint32_t getRealColor(uint16_t color) + uint8_t To8Bit(int color) { - uint8_t blue = (color & 0x7D00U) >> 10U; - uint8_t green = (color & 0x03E0U) >> 5U; - uint8_t red = (color & 0x001FU); - uint32_t pixelTmp = 0xFF; + return (uint)((color << 3) + (color >> 2)); + } - pixelTmp += (red * 255U / 31U) << 24U; - pixelTmp += (green * 255U / 31U) << 16U; - pixelTmp += (blue * 255U / 31U) << 8U; - return pixelTmp; + uint32_t getRealColor(uint16_t cgramColor) + { + uint b = To8Bit(cgramColor >> 10); + uint g = To8Bit((cgramColor >> 5) & 0x1F); + uint r = To8Bit(cgramColor & 0x1F); + + return (0x000000FF | (r << 24) | (g << 16) | (b << 8)); } } \ No newline at end of file diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 5e704a4..485b0b3 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -18,8 +18,8 @@ namespace ComSquare::PPU namespace ComSquare::PPU::Utils { - //! @brief Transform SNES color code BGR to uint32_t RGB - uint32_t getRealColor(uint16_t color); + //! @brief Transform SNES color code BGR to uint32_t RGBA + uint32_t getRealColor(uint16_t cgramColor); //! @brief Used to parse easily VRAM Tile information union TileData { struct { diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index 1f421ca..c511635 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -526,4 +526,51 @@ TEST_CASE("getPalette 8bpp", "[PPU][TileRenderer]") } i = 0; } +} + +TEST_CASE("render 2bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(2); + tileRenderer.setPaletteIndex(1); + + std::vector vramValues { + "7C00BA7C827C7C00", + "1000D6007C003800" + }; + + std::vector cgramValues = { + 0xCE, 0x69, 0xDF, 0x63, 0xDE, 0x16, 0x8B, 0x00, + 0x00, 0x00, 0xBF, 0x67, 0x98, 0x42, 0x0E, 0x15 + }; + //{0x3600, 0x67bf, 0x4298, 0x150e}, +// 0 FFEFCE C6A584 734229 + uint32_t correctValues[8][8] = { + {0x00000000, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0x00000000, 0x00000000}, + {0xFFEFCEFF, 0xC6A584FF, 0x734229FF, 0x734229FF, 0x734229FF, 0xC6A584FF, 0xFFEFCEFF, 0x00000000}, + {0xFFEFCEFF, 0xC6A584FF, 0xC6A584FF, 0xC6A584FF, 0xC6A584FF, 0xC6A584FF, 0xFFEFCEFF, 0x00000000}, + {0x00000000, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0x00000000, 0x00000000}, + {0x00000000, 0x00000000, 0x00000000, 0xFFEFCEFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0xFFEFCEFF, 0xFFEFCEFF, 0x00000000, 0xFFEFCEFF, 0x00000000, 0xFFEFCEFF, 0xFFEFCEFF, 0x00000000}, + {0x00000000, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0x00000000, 0x00000000}, + {0x00000000, 0x00000000, 0xFFEFCEFF, 0xFFEFCEFF, 0xFFEFCEFF, 0x00000000, 0x00000000, 0x00000000} + }; + + fillRAM(vramValues, vram); + fillRAM(cgramValues, cgram); + + tileRenderer.render(0); + + int i = 0; + int j = 0; + for (const auto &row : tileRenderer.buffer) { + for (const auto &pixel : row) { + CHECK(correctValues[i][j++] == pixel); + } + j = 0; + i++; + } } \ No newline at end of file From 8a158bbeb36a68b8eb7bcc84e3fa50a91f58ac04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Mon, 12 Jul 2021 00:17:12 +0200 Subject: [PATCH 34/41] renaming getRealColor to CGRAMColorToRGBA and finishing great random test on 8bpp rander --- sources/Debugger/CGramDebug.cpp | 4 +- sources/PPU/PPU.cpp | 2 +- sources/PPU/PPUUtils.cpp | 12 +-- sources/PPU/PPUUtils.hpp | 9 ++- sources/PPU/TileRenderer.cpp | 2 +- sources/PPU/TileRenderer.hpp | 2 +- tests/PPU/testTileRenderer.cpp | 130 ++++++++++++++++++++++++++++++++ 7 files changed, 148 insertions(+), 13 deletions(-) diff --git a/sources/Debugger/CGramDebug.cpp b/sources/Debugger/CGramDebug.cpp index ad5ae94..f77b2db 100644 --- a/sources/Debugger/CGramDebug.cpp +++ b/sources/Debugger/CGramDebug.cpp @@ -46,7 +46,7 @@ namespace ComSquare::Debugger uint8_t blue = (cgramValue & 0x7D00U) >> 10U; uint8_t green = (cgramValue & 0x03E0U) >> 5U; uint8_t red = (cgramValue & 0x001FU); - uint32_t hexColorValue = PPU::Utils::getRealColor(cgramValue); + uint32_t hexColorValue = PPU::Utils::CGRAMColorToRGBA(cgramValue); this->_ui.indexLineEdit->setText(std::to_string(addr / 2).c_str()); this->_ui.valueLineEdit->setText(Utility::to_hex(cgramValue).c_str()); @@ -90,7 +90,7 @@ namespace ComSquare::Debugger uint16_t cgramAddress = idDisplayTile / 8 * 16 + (idDisplayTile % 8 * 2); uint16_t addressValue = this->_ppu.cgramRead(cgramAddress); addressValue += this->_ppu.cgramRead(cgramAddress + 1) << 8U; - uint32_t color = PPU::Utils::getRealColor(addressValue); + uint32_t color = PPU::Utils::CGRAMColorToRGBA(addressValue); return QColor(static_cast((color & 0xFF000000) >> 24), static_cast((color & 0x00FF0000) >> 16), diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 4a2e1f1..a488e23 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -559,7 +559,7 @@ namespace ComSquare::PPU colorPalette = this->cgram.read(0); colorPalette += this->cgram.read(1) << 8U; - uint32_t color = Utils::getRealColor(colorPalette); + uint32_t color = Utils::CGRAMColorToRGBA(colorPalette); for (auto &row : this->_subScreen) row.fill(color); for (auto &row : this->_mainScreenLevelMap) diff --git a/sources/PPU/PPUUtils.cpp b/sources/PPU/PPUUtils.cpp index 2ea779a..0a0d588 100644 --- a/sources/PPU/PPUUtils.cpp +++ b/sources/PPU/PPUUtils.cpp @@ -7,16 +7,16 @@ namespace ComSquare::PPU::Utils { - uint8_t To8Bit(int color) + inline uint8_t to8Bit(int color) { - return (uint)((color << 3) + (color >> 2)); + return static_cast((color << 3) + (color >> 2)); } - uint32_t getRealColor(uint16_t cgramColor) + uint32_t CGRAMColorToRGBA(uint16_t CGRAMColor) { - uint b = To8Bit(cgramColor >> 10); - uint g = To8Bit((cgramColor >> 5) & 0x1F); - uint r = To8Bit(cgramColor & 0x1F); + uint8_t b = to8Bit(CGRAMColor >> 10); + uint8_t g = to8Bit((CGRAMColor >> 5) & 0x1F); + uint8_t r = to8Bit(CGRAMColor & 0x1F); return (0x000000FF | (r << 24) | (g << 16) | (b << 8)); } diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 485b0b3..212993b 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -17,9 +17,14 @@ namespace ComSquare::PPU namespace ComSquare::PPU::Utils { - + //! @brief Transform CGRAM color data to 8bits + //! @note Used with b, g and r values + //! @return The 8 bit value of the color + inline uint8_t to8Bit(int color); //! @brief Transform SNES color code BGR to uint32_t RGBA - uint32_t getRealColor(uint16_t cgramColor); + //! @param CGRAMColor The color of the CGRAM + //! @return The CGRAM color to RGBA format + uint32_t CGRAMColorToRGBA(uint16_t CGRAMColor); //! @brief Used to parse easily VRAM Tile information union TileData { struct { diff --git a/sources/PPU/TileRenderer.cpp b/sources/PPU/TileRenderer.cpp index 571134a..5dfa5f9 100644 --- a/sources/PPU/TileRenderer.cpp +++ b/sources/PPU/TileRenderer.cpp @@ -29,7 +29,7 @@ namespace ComSquare::PPU for (auto &row : this->buffer) { for (auto &pixel : row) { uint8_t pixelReference = this->getPixelReferenceFromTile(tileAddress, it++); - pixel = pixelReference ? Utils::getRealColor(palette[pixelReference]) : 0; + pixel = pixelReference ? Utils::CGRAMColorToRGBA(palette[pixelReference]) : 0; } } } diff --git a/sources/PPU/TileRenderer.hpp b/sources/PPU/TileRenderer.hpp index 6ea3e13..ba0f4e5 100644 --- a/sources/PPU/TileRenderer.hpp +++ b/sources/PPU/TileRenderer.hpp @@ -49,7 +49,7 @@ namespace ComSquare::PPU //! @param nbPalette The index of the palette wanted //! @return The array of color of the palette //! @note The return and argument depends on the current bpp - //! @warning Values are CGRAM colors use PPU::getRealColor function to get the actual real color + //! @warning Values are CGRAM colors use PPU::CGRAMColorToRGBA function to get the actual real color std::vector getPalette(int nbPalette); //! @brief read the 2bpp value for a pixel (used multple times for 4bpp and 8bpp) //! @param tileRowAddress Address where the read is done. Usage: Address of the tile row to render diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index c511635..b102f5c 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -7,9 +7,11 @@ #include #include #include +#include #include "PPU/TileRenderer.hpp" #include "Ram/Ram.hpp" #include "PPU/Tile.hpp" +#include "PPU/PPUUtils.hpp" void fillRAM(const std::vector &values, ComSquare::Ram::Ram &ram) { @@ -564,6 +566,134 @@ TEST_CASE("render 2bpp", "[PPU][TileRenderer]") tileRenderer.render(0); + int i = 0; + int j = 0; + for (const auto &row : tileRenderer.buffer) { + for (const auto &pixel : row) { + CHECK(correctValues[i][j++] == pixel); + } + j = 0; + i++; + } +} + +TEST_CASE("render 4bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(4); + tileRenderer.setPaletteIndex(0); + + std::vector vramValues { + "7C7C82EE82FE7C7C", + "0000D68254443838", + "7C00AA1082007C00", + "1000540038000000" + }; + + std::vector cgramValues = { + 0x00, 0x00, + 0x00, 0x00, + 0xFF, 0x7F, + 0x21, 0x0E, + 0xE2, 0x0E, + 0xE3, 0x0F, + 0x79, 0x0C, + 0xFD, 0x11, + 0x9F, 0x07, + 0xBF, 0x4B, + 0xDD, 0x01, + 0xCB, 0x0C, + 0x00, 0x00, + 0xDF, 0x55, + 0x3C, 0x0C, + 0x8B, 0x10, + 0xCE, 0x69, + 0x95, 0x7A + }; + + uint32_t correctValues[8][8] = { + {0x00000000, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0x00000000, 0x00000000}, + {0xef7b21ff, 0xffffffff, 0xce1818ff, 0xffe708ff, 0xce1818ff, 0xffffffff, 0xef7b21ff, 0x00000000}, + {0xef7b21ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xef7b21ff, 0x00000000}, + {0x00000000, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0xef7b21ff, 0x00000000, 0x00000000}, + {0x00000000, 0x00000000, 0x00000000, 0x10bd18ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x088c18ff, 0x18ff18ff, 0x00000000, 0x18ff18ff, 0x00000000, 0x18ff18ff, 0x088c18ff, 0x00000000}, + {0x00000000, 0x088c18ff, 0x10bd18ff, 0x18ff18ff, 0x10bd18ff, 0x088c18ff, 0x00000000, 0x00000000}, + {0x00000000, 0x00000000, 0x088c18ff, 0x088c18ff, 0x088c18ff, 0x00000000, 0x00000000, 0x00000000} + }; + + fillRAM(vramValues, vram); + fillRAM(cgramValues, cgram); + + tileRenderer.render(0); + + int i = 0; + int j = 0; + for (const auto &row : tileRenderer.buffer) { + for (const auto &pixel : row) { + CHECK(correctValues[i][j++] == pixel); + } + j = 0; + i++; + } +} + +TEST_CASE("render 8bpp", "[PPU][TileRenderer]") +{ + ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); + ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); + ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + + tileRenderer.setBpp(8); + tileRenderer.setPaletteIndex(0); + + std::vector vramValues{ + "0C7C5CA0C0BC3C001010964038282018", + "0000020002007C000000820044003800", + "007C44927C82007C1010D6D67C7C3838", + "00002800000000000000000000000000" + }; + + uint8_t correctReferences[8][8] = { + {0x00, 0x22, 0x22, 0x22, 0x23, 0x23, 0x00, 0x00}, + {0x22, 0x11, 0x42, 0x21, 0x41, 0x11, 0x24, 0x00}, + {0x23, 0x11, 0x12, 0x12, 0x12, 0x12, 0x24, 0x00}, + {0x00, 0x24, 0x25, 0x25, 0x25, 0x25, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00}, + {0x35, 0x32, 0x00, 0x31, 0x00, 0x31, 0x35, 0x00}, + {0x00, 0x34, 0x33, 0x31, 0x33, 0x34, 0x00, 0x00}, + {0x00, 0x00, 0x35, 0x36, 0x36, 0x00, 0x00, 0x00}, + }; + + for (int i = 0; i < 512; i++) { + cgram.write(i, std::rand()); + } + + uint32_t correctValues[8][8] = {{0}}; + + int k = 0; + int l = 0; + for (const auto &row : correctReferences) { + for (const auto &reference : row) { + if (reference == 0) { + l++; + continue; + } + correctValues[k][l++] = ComSquare::PPU::Utils::CGRAMColorToRGBA( + cgram.read(reference * 2) + | (cgram.read((reference * 2) + 1) << 8) + ); + } + l = 0; + k++; + } + + fillRAM(vramValues, vram); + tileRenderer.render(0); + int i = 0; int j = 0; for (const auto &row : tileRenderer.buffer) { From 6964290dcfc755521d3b50821817b0d6d6a1d4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Mon, 12 Jul 2021 00:43:08 +0200 Subject: [PATCH 35/41] transforming the addBuffer function into a templated function to save time with level etc --- sources/PPU/Background.hpp | 7 +++---- sources/PPU/PPU.cpp | 28 +++++++++++----------------- sources/PPU/PPU.hpp | 11 ++++++++++- tests/PPU/testTileRenderer.cpp | 1 + 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index f71d992..6ec57e7 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -110,12 +110,11 @@ namespace ComSquare::PPU //! @brief Add a bg buffer to another buffer - template + template static void mergeBackgroundBuffer(std::array, DEST_SIZE_X> &bufferDest, std::array, DEST_SIZE_X> &pixelDestinationLevelMap, - const Background &backgroundSrc, - int levelLow, - int levelHigh) + const Background &backgroundSrc + ) { int i = 0; int j = 0; diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index a488e23..93a662f 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -6,6 +6,7 @@ #include #include "PPU.hpp" #include "Exceptions/InvalidAddress.hpp" +#include "PPU/Background.hpp" #include "Models/Vector2.hpp" namespace ComSquare::PPU::Utils::Debug { @@ -570,27 +571,30 @@ namespace ComSquare::PPU // the starting palette index isn't implemented switch (this->_registers._bgmode.bgMode) { case 0: - this->addToMainSubScreen(this->_backgrounds[BgName::bg4NoPriority], {0, 15}); - this->addToMainSubScreen(this->_backgrounds[BgName::bg3NoPriority], {10, 16}); + this->addToMainSubScreen<0, 15>(this->_backgrounds[BgName::bg4NoPriority]); + this->addToMainSubScreen<10, 16>(this->_backgrounds[BgName::bg3NoPriority]); //sprites priority 0 // this->addToMainSubScreen(this->_backgrounds[BgName::bg4Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority], {20, 35}); - this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority], {30, 36}); + this->addToMainSubScreen<20, 35>(this->_backgrounds[BgName::bg2NoPriority]); + this->addToMainSubScreen<30, 36>(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 2 // this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); //sprites priority 3 break; case 1: - this->addToMainSubScreen(this->_backgrounds[BgName::bg3NoPriority], {0, this->_registers._bgmode.mode1Bg3PriorityBit ? 30 : 5}); + if (!this->_registers._bgmode.mode1Bg3PriorityBit) + this->addToMainSubScreen<0, 5>(this->_backgrounds[BgName::bg3NoPriority]); + else + this->addToMainSubScreen<0, 30>(this->_backgrounds[BgName::bg3NoPriority]); //sprites priority 0 // if (!this->_registers._bgmode.mode1Bg3PriorityBit) // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen(this->_backgrounds[BgName::bg2NoPriority], {10, 25}); - this->addToMainSubScreen(this->_backgrounds[BgName::bg1NoPriority], {20, 26}); + this->addToMainSubScreen<10, 25>(this->_backgrounds[BgName::bg2NoPriority]); + this->addToMainSubScreen<20, 26>(this->_backgrounds[BgName::bg1NoPriority]); //sprites priority 2 // this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); @@ -654,16 +658,6 @@ namespace ComSquare::PPU } } - void PPU::addToMainSubScreen(Background &bg, const Vector2 &level) - { - if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) { - Background::mergeBackgroundBuffer(this->_mainScreen, this->_mainScreenLevelMap, bg, level.x, level.y); - } - if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) { - Background::mergeBackgroundBuffer(this->_subScreen, this->_subScreenLevelMap, bg, level.x, level.y); - } - } - int PPU::getBgMode() const { return this->_registers._bgmode.bgMode; diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index fbbdcc3..1639cd1 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -624,7 +624,16 @@ namespace ComSquare::PPU //! @brief Render the Main and sub screen correctly void renderMainAndSubScreen(); //! @brief Add a bg to the sub and/or main screen - void addToMainSubScreen(Background &bg, const Vector2 &level); + template + void addToMainSubScreen(Background &bg) + { + if (this->_registers._t[0].raw & (1U << (bg.getBgNumber() - 1U))) { + Background::mergeBackgroundBuffer(this->_mainScreen, this->_mainScreenLevelMap, bg); + } + if (this->_registers._t[1].raw & (1U << (bg.getBgNumber() - 1U))) { + Background::mergeBackgroundBuffer(this->_subScreen, this->_subScreenLevelMap, bg); + } + } //! @brief Get the current background Mode [[nodiscard]] int getBgMode() const; //! @brief update the Vram buffer diff --git a/tests/PPU/testTileRenderer.cpp b/tests/PPU/testTileRenderer.cpp index b102f5c..85df464 100644 --- a/tests/PPU/testTileRenderer.cpp +++ b/tests/PPU/testTileRenderer.cpp @@ -646,6 +646,7 @@ TEST_CASE("render 8bpp", "[PPU][TileRenderer]") ComSquare::Ram::Ram vram(100, static_cast(0), "vramTest"); ComSquare::Ram::Ram cgram(512, static_cast(0), "cgramTest"); ComSquare::PPU::TileRenderer tileRenderer(vram, cgram); + std::srand(std::time(nullptr)); tileRenderer.setBpp(8); tileRenderer.setPaletteIndex(0); From a835bd17b5353dee90ebf76575509dcb43db1735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 22:00:09 +0200 Subject: [PATCH 36/41] moving PPU Registers into separate file and some name cleanup --- CMakeLists.txt | 2 +- sources/PPU/PPU.cpp | 16 +- sources/PPU/PPU.hpp | 521 +---------------------------------- sources/PPU/PPURegisters.hpp | 519 ++++++++++++++++++++++++++++++++++ 4 files changed, 534 insertions(+), 524 deletions(-) create mode 100644 sources/PPU/PPURegisters.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cad4546..ddbdcbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,7 @@ set(SOURCES sources/Models/Logger.hpp sources/PPU/PpuDebug.cpp sources/PPU/PpuDebug.hpp - ) + sources/PPU/PPURegisters.hpp) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 93a662f..b073435 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -571,14 +571,14 @@ namespace ComSquare::PPU // the starting palette index isn't implemented switch (this->_registers._bgmode.bgMode) { case 0: - this->addToMainSubScreen<0, 15>(this->_backgrounds[BgName::bg4NoPriority]); - this->addToMainSubScreen<10, 16>(this->_backgrounds[BgName::bg3NoPriority]); + this->addToMainSubScreen<0, 15>(this->_backgrounds[BgName::Background4]); + this->addToMainSubScreen<10, 16>(this->_backgrounds[BgName::Background3]); //sprites priority 0 // this->addToMainSubScreen(this->_backgrounds[BgName::bg4Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen<20, 35>(this->_backgrounds[BgName::bg2NoPriority]); - this->addToMainSubScreen<30, 36>(this->_backgrounds[BgName::bg1NoPriority]); + this->addToMainSubScreen<20, 35>(this->_backgrounds[BgName::Background2]); + this->addToMainSubScreen<30, 36>(this->_backgrounds[BgName::Background1]); //sprites priority 2 // this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); @@ -586,15 +586,15 @@ namespace ComSquare::PPU break; case 1: if (!this->_registers._bgmode.mode1Bg3PriorityBit) - this->addToMainSubScreen<0, 5>(this->_backgrounds[BgName::bg3NoPriority]); + this->addToMainSubScreen<0, 5>(this->_backgrounds[BgName::Background3]); else - this->addToMainSubScreen<0, 30>(this->_backgrounds[BgName::bg3NoPriority]); + this->addToMainSubScreen<0, 30>(this->_backgrounds[BgName::Background3]); //sprites priority 0 // if (!this->_registers._bgmode.mode1Bg3PriorityBit) // this->addToMainSubScreen(this->_backgrounds[BgName::bg3Priority]); //sprites priority 1 - this->addToMainSubScreen<10, 25>(this->_backgrounds[BgName::bg2NoPriority]); - this->addToMainSubScreen<20, 26>(this->_backgrounds[BgName::bg1NoPriority]); + this->addToMainSubScreen<10, 25>(this->_backgrounds[BgName::Background2]); + this->addToMainSubScreen<20, 26>(this->_backgrounds[BgName::Background1]); //sprites priority 2 // this->addToMainSubScreen(this->_backgrounds[BgName::bg2Priority]); // this->addToMainSubScreen(this->_backgrounds[BgName::bg1Priority]); diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 1639cd1..42b0ba0 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -12,7 +12,8 @@ #include "Models/Vector2.hpp" #include #include "Background.hpp" -#include "PPUUtils.hpp" +#include "PPU/PPUUtils.hpp" +#include "PPU/PPURegisters.hpp" #ifdef DEBUGGER_ENABLED #include "Debugger/TileViewer/RAMTileRenderer.hpp" @@ -35,520 +36,10 @@ namespace ComSquare::PPU class Background; //! @brief Enum to access more easily the ppu background array enum BgName { - bg1NoPriority = 0, - bg2NoPriority = 1, - bg3NoPriority = 2, - bg4NoPriority = 3 - }; - - enum PpuRegisters { - //! @brief INIDISP Register (F-blank and Brightness) - inidisp = 0x00, - //! @brief OBSEL Register (Object Size and Character Address) - obsel = 0x01, - //! @brief OAMADDL (OAM Address low byte) - oamaddl = 0x02, - //! @brief OAMADDH (OAM Address high bit and Obj Priority) - oamaddh = 0x03, - //! @brief OAMDATA (Data for OAM write) - oamdata = 0x04, - //! @brief BGMODE (BG Mode and Character Size) - bgmode = 0x05, - //! @brief MOSAIC (Screen Pixelation) - mosaic = 0x06, - //! @brief BG1SC (BG1 Tilemap Address and Size) - bg1sc = 0x07, - //! @brief BG2SC (BG2 Tilemap Address and Size) - bg2sc = 0x08, - //! @brief BG3SC (BG3 Tilemap Address and Size) - bg3sc = 0x09, - //! @brief BG4SC (BG4 Tilemap Address and Size) - bg4sc = 0x0A, - //! @brief BG12NBA (BG1 and 2 Chr Address) - bg12nba = 0x0B, - //! @brief BG34NBA (BG3 and 4 Chr Address) - bg34nba = 0x0C, - //! @brief BG1HOFS (BG1 Horizontal Scroll) - //! @brief M7HOFS (Mode 7 BG Horizontal Scroll) - //! @info When bg mode is 7 the register is used as M7HOFS - bg1hofs = 0x0D, - //! @brief BG1VOFS (BG1 Vertical Scroll) - //! @brief M7VOFS (Mode 7 BG Vertical Scroll) - //! @info When bg mode is 7 the register is used as M7VOFS - bg1vofs = 0x0E, - //! @brief BG2HOFS (BG2 Horizontal Scroll) - bg2hofs = 0x0F, - //! @brief BG2VOFS (BG2 Vertical Scroll) - bg2vofs = 0x10, - //! @brief BG3HOFS (BG3 Horizontal Scroll) - bg3hofs = 0x11, - //! @brief BG3VOFS (BG3 Vertical Scroll) - bg3vofs = 0x12, - //! @brief BG4HOFS (BG4 Horizontal Scroll) - bg4hofs = 0x13, - //! @brief BG4VOFS (BG4 Vertical Scroll) - bg4vofs = 0x14, - //! @brief VMAIN (Video Port Control) - vmain = 0x15, - //! @brief VMADDL (VRAM Address low byte) - vmaddl = 0x16, - //! @brief VMADDH (VRAM Address high byte) - vmaddh = 0x17, - //! @brief VMDATAL (VRAM Data Write low byte) - vmdatal = 0x18, - //! @brief VMDATAH (VRAM Data Write high byte) - vmdatah = 0x19, - //! @brief M7SEL (Mode 7 Settings) - m7sel = 0x1A, - //! @brief M7A (Mode 7 Matrix A) also used with $2134/6 - m7a = 0x1B, - //! @brief M7B (Mode 7 Matrix B) also used with $2134/6 - m7b = 0x1C, - //! @brief M7C (Mode 7 Matrix C) - m7c = 0x1D, - //! @brief M7D (Mode 7 Matrix D) - m7d = 0x1E, - //! @brief M7X (Mode 7 Center X) - m7x = 0x1F, - //! @brief M7Y (Mode 7 Center Y) - m7y = 0x20, - //! @brief CGADD (CGRAM Address) - cgadd = 0x21, - //! @brief CGDATA (CGRAM Data write) - cgdata = 0x22, - //! @brief W12SEL (Window Mask Settings for BG1 and BG2) - w12sel = 0x23, - //! @brief W34SEL (Window Mask Settings for BG3 and BG4) - w34sel = 0x24, - //! @brief WOBJSEL (Window Mask Settings for OBJ and Color Window) - wobjsel = 0x25, - //! @brief WH0 (Window 1 Left Position) - wh0 = 0x26, - //! @brief WH1 (Window 1 Right Position) - wh1 = 0x27, - //! @brief WH2 (Window 2 Left Position) - wh2 = 0x28, - //! @brief WH3 (Window 2 Right Position) - wh3 = 0x29, - //! @brief WBGLOG (Window mask logic for BGs) - wbjlog = 0x2A, - //! @brief WOBJLOG (Window mask logic for OBJs and Color Window) - wobjlog = 0x2B, - //! @brief TM (Main Screen Designation) - tm = 0x2C, - //! @brief TS (Subscreen Designation) - ts = 0x2D, - //! @brief TMW (Window Mask Designation for the Main Screen) - tmw = 0x2E, - //! @brief TSW (Window Mask Designation for the Subscreen) - tsw = 0x2F, - //! @brief CGWSEL (Color Addition Select) - cgwsel = 0x30, - //! @brief CGADSUB (Color math designation) - cgadsub = 0x31, - //! @brief COLDATA (Fixed Color Data) - coldata = 0x32, - //! @brief SETINI (Screen Mode/Video Select) - setini = 0x33, - //! @brief MPYL (Multiplication Result low byte) - mpyl = 0x34, - //! @brief MPYM (Multiplication Result middle byte) - mpym = 0x35, - //! @brief MPYH (Multiplication Result high byte) - mpyh = 0x36, - //! @brief SLHV (Software Latch for H/V Counter) - slhv = 0x37, - //! @brief OAMDATAREAD (Data for OAM read) - oamdataread = 0x38, - //! @brief VMDATALREAD (VRAM Data Read low byte) - vmdatalread = 0x39, - //! @brief VMDATAHREAD (VRAM Data Read high byte) - vmdatahread = 0x3A, - //! @brief CGDATAREAD (CGRAM Data read) - cgdataread = 0x3B, - //! @brief OPHCT (Horizontal Scanline Location) - ophct = 0x3C, - //! @brief OPVCT (Vertical Scanline Location) - opvct = 0x3D, - //! @brief STAT77 (PPU Status Flag and Version) - stat77 = 0x3E, - //! @brief STAT78 (PPU Status Flag and Version) - stat78 = 0x3F - }; - - struct Registers { - //! @brief INIDISP Register (F-blank and Brightness) - union { - struct { - //! @brief Store the brightness value (F = max, 0 = off) - uint8_t brightness: 4; - uint8_t _: 3; - //! @brief Store the FBlank status - uint8_t fblank: 1; - }; - uint8_t raw = 0; - } _inidisp; - //! @brief OBSEL Register (Object Size and Character Address) - union { - struct { - //! @brief Stores the location of the first sprite table - uint8_t nameBaseSelect: 3; - //! @brief Stores the offset of the second sprite table - uint8_t nameSelect: 2; - //! @brief Stores the resolution preset of the sprites - uint8_t objectSize: 3; - }; - uint8_t raw = 0; - } _obsel; - //! @brief OAMADD Register (OAM Address and Obj Priority) - union { - struct { - //! @brief Stores the address to write with OAMDATA register - uint16_t oamAddress: 9; - uint16_t _: 6; - //! @brief When Obj Priority activation bit is set, an Obj other than Sprite 0 may be given priority - uint16_t objPriorityActivationBit: 1; - }; - struct { - //! @brief Stores the data written on the OAMADDL register - uint16_t oamaddl: 8; - //! @brief Stores the data written on the OAMADDH register - uint16_t oamaddh: 8; - }; - uint16_t raw = 0; - } _oamadd; - //! @brief OAMDATA Register (Data for OAM write) - uint8_t _oamdata = 0; - //! @brief BGMODE Register (OAM Address and Obj Priority) - union { - struct { - //! @brief Stores the current BG Mode (0 - 7) - uint8_t bgMode: 3; - //! @brief When Mode 1 BG3 priority bit is set the BG3 is draw - uint8_t mode1Bg3PriorityBit: 1; - //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 - uint8_t characterSizeBg1: 1; - //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 - uint8_t characterSizeBg2: 1; - //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 - uint8_t characterSizeBg3: 1; - //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 - uint8_t characterSizeBg4: 1; - }; - uint8_t raw = 0; - } _bgmode; - //! @brief MOSAIC Register (Screen Pixelation) - union { - struct { - //! @brief Apply mosaic to the BG1 - uint8_t affectBg1: 1; - //! @brief Apply mosaic to the BG2 - uint8_t affectBg2: 1; - //! @brief Apply mosaic to the BG3 - uint8_t affectBg3: 1; - //! @brief Apply mosaic to the BG4 - uint8_t affectBg4: 1; - //! @brief Stores the pixel size (0 = 1x1, F = 16x16) - uint8_t pixelSize: 4; - }; - uint8_t raw = 0; - } _mosaic; - //! @brief BGSC Registers (BG Tilemap Address and Size) - union { - struct { - //! @brief When tilemap horizontal mirroring bit is set the tilemap is mirrored horizontally - uint8_t tilemapHorizontalMirroring: 1; - //! @brief When tilemap vertically mirroring bit is set the tilemap is mirrored vertically - uint8_t tilemapVerticalMirroring: 1; - //! @brief Address of the tilemap Address (0, 0) - uint8_t tilemapAddress: 6; - }; - uint8_t raw = 0; - } _bgsc[4]; - //! @brief BGNBA Registers (BG1/2/3/4 Chr Address) - union { - struct { - //! @brief The address let us know where to search for BG1/3 characters - uint8_t baseAddressBg1a3: 4; - //! @brief The address let us know where to search for BG2/4 characters - uint8_t baseAddressBg2a4: 4; - }; - uint8_t raw = 0; - } _bgnba[2]; - //! @brief BGXXOFS Register (BG1/2/3/4 Horizontal and Vertical Scrolls) - union { - struct { - uint16_t offsetBg: 10; - uint16_t _ : 6; - }; - uint16_t raw = 0; - } _bgofs[8]; - //! @brief M7HOFS Register (Mode 7 BG Horizontal Scroll) - //! @brief M7VOFS Register (Mode 7 BG Vertical Scroll) - union { - struct { - uint16_t offsetBg : 13; - uint16_t _ : 3; - }; - uint16_t raw = 0; - } _m7ofs[2]; - //! @brief VMAIN Register (Video Port Control) - union { - struct { - uint8_t incrementAmount: 2; - uint8_t addressRemapping: 2; - uint8_t _ : 3; - uint8_t incrementMode: 1; - }; - uint8_t raw = 0; - } _vmain; - //! @brief Store the real value of the increment Amount (1, 32, 128) instead of 0,1 or 2 - uint8_t _incrementAmount = 1; - //! @brief VMADD Register (VRAM Address) - union { - struct { - uint16_t vmaddl: 8; - uint16_t vmaddh: 8; - }; - uint16_t vmadd = 0; - } _vmadd; - //! @brief VMDATA Register (VRAM Data Write) - union { - struct { - uint16_t vmdatal: 8; - uint16_t vmdatah: 8; - }; - uint16_t vmdata = 0; - } _vmdata; - //! @brief TODO M7SEL Register (Mode 7 Settings) - union { - struct { - uint8_t horizontalMirroring: 1; - uint8_t verticalMirroring: 1; - uint8_t _: 4; - uint8_t emptySpaceFill: 1; - uint8_t playingFieldSize: 1; - }; - uint8_t raw = 0; - } _m7sel; - //! @brief M7A M7B M7C M7C registers, M7A and M7B are also used with ($2134/6) (multiplactions registers) - union { - struct { - uint16_t m7l: 8; - uint16_t m7h: 8; - }; - uint16_t m7 = 0; - } _m7[4]; - // - - //! @brief M7X Register (Mode 7 Center X) - union { // Not sure if it is done correctly - struct { - uint16_t _: 3; - uint16_t value: 13; - }; - uint16_t raw = 0; - } _m7x; - //! @brief M7Y Register (Mode 7 Center Y) - union { // Not sure if it is done correctly - struct { - uint16_t _: 3; - uint16_t value: 13; - }; - uint16_t raw = 0; - } _m7y; - //! @brief CGADD Register (CGRAM Address) - uint8_t _cgadd = 0; - //! @brief CGDATA Register (CGRAM Data write) - union { - struct { - uint16_t red: 5; - uint16_t green: 5; - uint16_t blue: 5; - uint16_t _: 1; - }; - struct { - uint16_t cgdatal: 8; - uint16_t cgdatah: 8; - }; - uint16_t raw = 0; - } _cgdata; - //! @brief This bool is used for writing either the low byte of the data (first call) or the high byte of the data (second call) - //! @info This bool is set to True when writing to $2121 (CGADD) - bool _isLowByte = false; - //! @brief W12SEL - W34SEL Registers (Window Mask Settings for BGs) and WOBJSEL Register (Window Mask Settings for OBJ and Color Window) - union { - struct { - uint8_t enableWindow2ForBg2Bg4Color: 1; - uint8_t window2InversionForBg2Bg4Color: 1; - uint8_t enableWindow1ForBg2Bg4Color: 1; - uint8_t window1InversionForBg2Bg4Color: 1; - uint8_t enableWindow2ForBg1Bg3Obj: 1; - uint8_t window2InversionForBg1Bg3Obj: 1; - uint8_t enableWindow1ForBg1Bg3Obj: 1; - uint8_t window1InversionForBg1Bg3Obj: 1; - }; - uint8_t raw = 0; - } _wsel[3]; - //! @brief WH0 Register (Window 1 Left Position) - //! @brief WH1 Register (Window 1 Right Position) - //! @brief WH2 Register (Window 2 Left Position) - //! @brief WH3 Register (Window 2 Right Position) - uint8_t _wh[4] = {0}; - //! @brief WBGLOG Register (Window mask logic for BGs) - union { - struct { - uint8_t maskLogicBg4: 2; - uint8_t maskLogicBg3: 2; - uint8_t maskLogicBg2: 2; - uint8_t maskLogicBg1: 2; - }; - uint8_t raw = 0; - } _wbglog; - //! @brief WOBJLOG Register (Window mask logic for OBJs and Color Window) - union { - struct { - uint8_t maskLogicObj: 2; - uint8_t maskLogicColor: 2; - uint8_t _: 4; - }; - uint8_t raw = 0; - } _wobjlog; - //! @brief TM - TS Registers (Main & Sub Screen Designation) - union { - struct { - uint8_t enableWindowDisplayBg1: 1; - uint8_t enableWindowDisplayBg2: 1; - uint8_t enableWindowDisplayBg3: 1; - uint8_t enableWindowDisplayBg4: 1; - uint8_t enableWindowDisplayObj: 1; - uint8_t _: 3; - }; - uint8_t raw = 0; - } _t[2]; - //! @brief TMW - TSW Registers (Window Mask Designation for the Main/Sub Screen) - union { - struct { - uint8_t enableWindowMaskingBg1: 1; - uint8_t enableWindowMaskingBg2: 1; - uint8_t enableWindowMaskingBg3: 1; - uint8_t enableWindowMaskingBg4: 1; - uint8_t enableWindowMaskingObj: 1; - uint8_t _: 3; - }; - uint8_t raw = 0; - } _tw[2]; - //! @brief CGWSEL Register (Color Addition Select) - union { - struct { - uint8_t directColorMode: 1; - uint8_t addSubscreen: 1; - uint8_t _: 2; - uint8_t preventColorMath: 2; - uint8_t clipColorToBlackBeforeMath: 2; - }; - uint8_t raw = 0; - } _cgwsel; - //! @brief CGADSUB Register (Color Math designation) - union { - struct { - uint8_t enableColorMathBg1: 1; - uint8_t enableColorMathBg2: 1; - uint8_t enableColorMathBg3: 1; - uint8_t enableColorMathBg4: 1; - uint8_t enableColorMathObj: 1; - uint8_t enableColorMathBackdrop: 1; - uint8_t halfColorMath: 1; - uint8_t addSubtractSelect: 1; - }; - uint8_t raw = 0; - } _cgadsub; - //! @brief COLDATA Register (Fixed Color Data) - union { - struct { - uint8_t colorIntensity: 5; - uint8_t red: 1; - uint8_t green: 1; - uint8_t blue: 1; - }; - uint8_t raw = 0; - } _coldata; - //! @brief SETINI Register (Screen Mode/Video Select) - union { - struct { - uint8_t screenInterlace: 1; - uint8_t objInterlace: 1; - uint8_t overscanMode: 1; - uint8_t enablePseudoHiresMode: 1; - uint8_t _: 2; - uint8_t mode7ExtBg: 1; - uint8_t externalSync: 1; - }; - uint8_t raw = 0; - } _setini; - - // - - //! @brief MPYL - MPYM - MPYH Registers (Multiplication Result) - union { - struct { - uint32_t mpyl: 8; - uint32_t mpym: 8; - uint32_t mpyh: 8; - uint32_t _: 8; - }; - uint32_t mpy = 0; - } _mpy; - //! @brief SLHV - Software Latch for H/V Counter - uint8_t _slhv = 0; - //! @brief OAMDATAREAD - Data for OAM read - uint8_t _oamdataread = 0; - //! @brief VMDATALREAD/VMDATAHREAD - VRAM Data Read low/high byte - union { - struct { - uint16_t vmDataLRead: 8; - uint16_t vmDataHRead: 8; - }; - uint16_t raw = 0; - } _vmdataread; - //! @brief CGRAM Data read - union { - struct { - uint16_t cgDataLRead: 8; - uint16_t cgDataHRead: 8; - }; - uint16_t raw = 0; - } _cgdataread; - //! @brief OPHCT/OPVCT - Horizontal/Vertical Scanline Location - union { - struct { - uint16_t opct: 9; - uint16_t _: 7; - }; - uint16_t raw = 0; - } _opct; - //! @brief STAT77 - PPU Status Flag and Version - union { - struct { - uint8_t chipVersionNumber: 4; - uint8_t _: 1; - uint8_t modeSelect: 1; - uint8_t rangeOverFlag: 1; - uint8_t timeOverFlag: 1; - }; - uint8_t raw = 0; - } _stat77; - //! @brief STAT78 - PPU Status Flag and Version - union { - struct { - uint8_t chipVersionNumber: 4; - uint8_t mode: 1; - uint8_t _: 1; - uint8_t externalLatchFlag: 1; - uint8_t interlaceField: 1; - }; - uint8_t raw = 0; - } _stat78; + Background1 = 0, + Background2, + Background3, + Background4 }; //! @brief The class containing all the registers of the PPU diff --git a/sources/PPU/PPURegisters.hpp b/sources/PPU/PPURegisters.hpp new file mode 100644 index 0000000..d46fd6c --- /dev/null +++ b/sources/PPU/PPURegisters.hpp @@ -0,0 +1,519 @@ +// +// Created by cbihan on 13/07/2021. +// + +#pragma once + + +namespace ComSquare::PPU +{ + enum PpuRegisters { + //! @brief INIDISP Register (F-blank and Brightness) + inidisp = 0x00, + //! @brief OBSEL Register (Object Size and Character Address) + obsel = 0x01, + //! @brief OAMADDL (OAM Address low byte) + oamaddl = 0x02, + //! @brief OAMADDH (OAM Address high bit and Obj Priority) + oamaddh = 0x03, + //! @brief OAMDATA (Data for OAM write) + oamdata = 0x04, + //! @brief BGMODE (BG Mode and Character Size) + bgmode = 0x05, + //! @brief MOSAIC (Screen Pixelation) + mosaic = 0x06, + //! @brief BG1SC (BG1 Tilemap Address and Size) + bg1sc = 0x07, + //! @brief BG2SC (BG2 Tilemap Address and Size) + bg2sc = 0x08, + //! @brief BG3SC (BG3 Tilemap Address and Size) + bg3sc = 0x09, + //! @brief BG4SC (BG4 Tilemap Address and Size) + bg4sc = 0x0A, + //! @brief BG12NBA (BG1 and 2 Chr Address) + bg12nba = 0x0B, + //! @brief BG34NBA (BG3 and 4 Chr Address) + bg34nba = 0x0C, + //! @brief BG1HOFS (BG1 Horizontal Scroll) + //! @brief M7HOFS (Mode 7 BG Horizontal Scroll) + //! @info When bg mode is 7 the register is used as M7HOFS + bg1hofs = 0x0D, + //! @brief BG1VOFS (BG1 Vertical Scroll) + //! @brief M7VOFS (Mode 7 BG Vertical Scroll) + //! @info When bg mode is 7 the register is used as M7VOFS + bg1vofs = 0x0E, + //! @brief BG2HOFS (BG2 Horizontal Scroll) + bg2hofs = 0x0F, + //! @brief BG2VOFS (BG2 Vertical Scroll) + bg2vofs = 0x10, + //! @brief BG3HOFS (BG3 Horizontal Scroll) + bg3hofs = 0x11, + //! @brief BG3VOFS (BG3 Vertical Scroll) + bg3vofs = 0x12, + //! @brief BG4HOFS (BG4 Horizontal Scroll) + bg4hofs = 0x13, + //! @brief BG4VOFS (BG4 Vertical Scroll) + bg4vofs = 0x14, + //! @brief VMAIN (Video Port Control) + vmain = 0x15, + //! @brief VMADDL (VRAM Address low byte) + vmaddl = 0x16, + //! @brief VMADDH (VRAM Address high byte) + vmaddh = 0x17, + //! @brief VMDATAL (VRAM Data Write low byte) + vmdatal = 0x18, + //! @brief VMDATAH (VRAM Data Write high byte) + vmdatah = 0x19, + //! @brief M7SEL (Mode 7 Settings) + m7sel = 0x1A, + //! @brief M7A (Mode 7 Matrix A) also used with $2134/6 + m7a = 0x1B, + //! @brief M7B (Mode 7 Matrix B) also used with $2134/6 + m7b = 0x1C, + //! @brief M7C (Mode 7 Matrix C) + m7c = 0x1D, + //! @brief M7D (Mode 7 Matrix D) + m7d = 0x1E, + //! @brief M7X (Mode 7 Center X) + m7x = 0x1F, + //! @brief M7Y (Mode 7 Center Y) + m7y = 0x20, + //! @brief CGADD (CGRAM Address) + cgadd = 0x21, + //! @brief CGDATA (CGRAM Data write) + cgdata = 0x22, + //! @brief W12SEL (Window Mask Settings for BG1 and BG2) + w12sel = 0x23, + //! @brief W34SEL (Window Mask Settings for BG3 and BG4) + w34sel = 0x24, + //! @brief WOBJSEL (Window Mask Settings for OBJ and Color Window) + wobjsel = 0x25, + //! @brief WH0 (Window 1 Left Position) + wh0 = 0x26, + //! @brief WH1 (Window 1 Right Position) + wh1 = 0x27, + //! @brief WH2 (Window 2 Left Position) + wh2 = 0x28, + //! @brief WH3 (Window 2 Right Position) + wh3 = 0x29, + //! @brief WBGLOG (Window mask logic for BGs) + wbjlog = 0x2A, + //! @brief WOBJLOG (Window mask logic for OBJs and Color Window) + wobjlog = 0x2B, + //! @brief TM (Main Screen Designation) + tm = 0x2C, + //! @brief TS (Subscreen Designation) + ts = 0x2D, + //! @brief TMW (Window Mask Designation for the Main Screen) + tmw = 0x2E, + //! @brief TSW (Window Mask Designation for the Subscreen) + tsw = 0x2F, + //! @brief CGWSEL (Color Addition Select) + cgwsel = 0x30, + //! @brief CGADSUB (Color math designation) + cgadsub = 0x31, + //! @brief COLDATA (Fixed Color Data) + coldata = 0x32, + //! @brief SETINI (Screen Mode/Video Select) + setini = 0x33, + //! @brief MPYL (Multiplication Result low byte) + mpyl = 0x34, + //! @brief MPYM (Multiplication Result middle byte) + mpym = 0x35, + //! @brief MPYH (Multiplication Result high byte) + mpyh = 0x36, + //! @brief SLHV (Software Latch for H/V Counter) + slhv = 0x37, + //! @brief OAMDATAREAD (Data for OAM read) + oamdataread = 0x38, + //! @brief VMDATALREAD (VRAM Data Read low byte) + vmdatalread = 0x39, + //! @brief VMDATAHREAD (VRAM Data Read high byte) + vmdatahread = 0x3A, + //! @brief CGDATAREAD (CGRAM Data read) + cgdataread = 0x3B, + //! @brief OPHCT (Horizontal Scanline Location) + ophct = 0x3C, + //! @brief OPVCT (Vertical Scanline Location) + opvct = 0x3D, + //! @brief STAT77 (PPU Status Flag and Version) + stat77 = 0x3E, + //! @brief STAT78 (PPU Status Flag and Version) + stat78 = 0x3F + }; + + struct Registers { + //! @brief INIDISP Register (F-blank and Brightness) + union { + struct { + //! @brief Store the brightness value (F = max, 0 = off) + uint8_t brightness: 4; + uint8_t _: 3; + //! @brief Store the FBlank status + uint8_t fblank: 1; + }; + uint8_t raw = 0; + } _inidisp; + //! @brief OBSEL Register (Object Size and Character Address) + union { + struct { + //! @brief Stores the location of the first sprite table + uint8_t nameBaseSelect: 3; + //! @brief Stores the offset of the second sprite table + uint8_t nameSelect: 2; + //! @brief Stores the resolution preset of the sprites + uint8_t objectSize: 3; + }; + uint8_t raw = 0; + } _obsel; + //! @brief OAMADD Register (OAM Address and Obj Priority) + union { + struct { + //! @brief Stores the address to write with OAMDATA register + uint16_t oamAddress: 9; + uint16_t _: 6; + //! @brief When Obj Priority activation bit is set, an Obj other than Sprite 0 may be given priority + uint16_t objPriorityActivationBit: 1; + }; + struct { + //! @brief Stores the data written on the OAMADDL register + uint16_t oamaddl: 8; + //! @brief Stores the data written on the OAMADDH register + uint16_t oamaddh: 8; + }; + uint16_t raw = 0; + } _oamadd; + //! @brief OAMDATA Register (Data for OAM write) + uint8_t _oamdata = 0; + //! @brief BGMODE Register (OAM Address and Obj Priority) + union { + struct { + //! @brief Stores the current BG Mode (0 - 7) + uint8_t bgMode: 3; + //! @brief When Mode 1 BG3 priority bit is set the BG3 is draw + uint8_t mode1Bg3PriorityBit: 1; + //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 + uint8_t characterSizeBg1: 1; + //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 + uint8_t characterSizeBg2: 1; + //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 + uint8_t characterSizeBg3: 1; + //! @brief When The bit is set character size will 16x16 otherwise it is 8x8 + uint8_t characterSizeBg4: 1; + }; + uint8_t raw = 0; + } _bgmode; + //! @brief MOSAIC Register (Screen Pixelation) + union { + struct { + //! @brief Apply mosaic to the BG1 + uint8_t affectBg1: 1; + //! @brief Apply mosaic to the BG2 + uint8_t affectBg2: 1; + //! @brief Apply mosaic to the BG3 + uint8_t affectBg3: 1; + //! @brief Apply mosaic to the BG4 + uint8_t affectBg4: 1; + //! @brief Stores the pixel size (0 = 1x1, F = 16x16) + uint8_t pixelSize: 4; + }; + uint8_t raw = 0; + } _mosaic; + //! @brief BGSC Registers (BG Tilemap Address and Size) + union { + struct { + //! @brief When tilemap horizontal mirroring bit is set the tilemap is mirrored horizontally + uint8_t tilemapHorizontalMirroring: 1; + //! @brief When tilemap vertically mirroring bit is set the tilemap is mirrored vertically + uint8_t tilemapVerticalMirroring: 1; + //! @brief Address of the tilemap Address (0, 0) + uint8_t tilemapAddress: 6; + }; + uint8_t raw = 0; + } _bgsc[4]; + //! @brief BGNBA Registers (BG1/2/3/4 Chr Address) + union { + struct { + //! @brief The address let us know where to search for BG1/3 characters + uint8_t baseAddressBg1a3: 4; + //! @brief The address let us know where to search for BG2/4 characters + uint8_t baseAddressBg2a4: 4; + }; + uint8_t raw = 0; + } _bgnba[2]; + //! @brief BGXXOFS Register (BG1/2/3/4 Horizontal and Vertical Scrolls) + union { + struct { + uint16_t offsetBg: 10; + uint16_t _ : 6; + }; + uint16_t raw = 0; + } _bgofs[8]; + //! @brief M7HOFS Register (Mode 7 BG Horizontal Scroll) + //! @brief M7VOFS Register (Mode 7 BG Vertical Scroll) + union { + struct { + uint16_t offsetBg : 13; + uint16_t _ : 3; + }; + uint16_t raw = 0; + } _m7ofs[2]; + //! @brief VMAIN Register (Video Port Control) + union { + struct { + uint8_t incrementAmount: 2; + uint8_t addressRemapping: 2; + uint8_t _ : 3; + uint8_t incrementMode: 1; + }; + uint8_t raw = 0; + } _vmain; + //! @brief Store the real value of the increment Amount (1, 32, 128) instead of 0,1 or 2 + uint8_t _incrementAmount = 1; + //! @brief VMADD Register (VRAM Address) + union { + struct { + uint16_t vmaddl: 8; + uint16_t vmaddh: 8; + }; + uint16_t vmadd = 0; + } _vmadd; + //! @brief VMDATA Register (VRAM Data Write) + union { + struct { + uint16_t vmdatal: 8; + uint16_t vmdatah: 8; + }; + uint16_t vmdata = 0; + } _vmdata; + //! @brief TODO M7SEL Register (Mode 7 Settings) + union { + struct { + uint8_t horizontalMirroring: 1; + uint8_t verticalMirroring: 1; + uint8_t _: 4; + uint8_t emptySpaceFill: 1; + uint8_t playingFieldSize: 1; + }; + uint8_t raw = 0; + } _m7sel; + //! @brief M7A M7B M7C M7C registers, M7A and M7B are also used with ($2134/6) (multiplactions registers) + union { + struct { + uint16_t m7l: 8; + uint16_t m7h: 8; + }; + uint16_t m7 = 0; + } _m7[4]; + // + + //! @brief M7X Register (Mode 7 Center X) + union { // Not sure if it is done correctly + struct { + uint16_t _: 3; + uint16_t value: 13; + }; + uint16_t raw = 0; + } _m7x; + //! @brief M7Y Register (Mode 7 Center Y) + union { // Not sure if it is done correctly + struct { + uint16_t _: 3; + uint16_t value: 13; + }; + uint16_t raw = 0; + } _m7y; + //! @brief CGADD Register (CGRAM Address) + uint8_t _cgadd = 0; + //! @brief CGDATA Register (CGRAM Data write) + union { + struct { + uint16_t red: 5; + uint16_t green: 5; + uint16_t blue: 5; + uint16_t _: 1; + }; + struct { + uint16_t cgdatal: 8; + uint16_t cgdatah: 8; + }; + uint16_t raw = 0; + } _cgdata; + //! @brief This bool is used for writing either the low byte of the data (first call) or the high byte of the data (second call) + //! @info This bool is set to True when writing to $2121 (CGADD) + bool _isLowByte = false; + //! @brief W12SEL - W34SEL Registers (Window Mask Settings for BGs) and WOBJSEL Register (Window Mask Settings for OBJ and Color Window) + union { + struct { + uint8_t enableWindow2ForBg2Bg4Color: 1; + uint8_t window2InversionForBg2Bg4Color: 1; + uint8_t enableWindow1ForBg2Bg4Color: 1; + uint8_t window1InversionForBg2Bg4Color: 1; + uint8_t enableWindow2ForBg1Bg3Obj: 1; + uint8_t window2InversionForBg1Bg3Obj: 1; + uint8_t enableWindow1ForBg1Bg3Obj: 1; + uint8_t window1InversionForBg1Bg3Obj: 1; + }; + uint8_t raw = 0; + } _wsel[3]; + //! @brief WH0 Register (Window 1 Left Position) + //! @brief WH1 Register (Window 1 Right Position) + //! @brief WH2 Register (Window 2 Left Position) + //! @brief WH3 Register (Window 2 Right Position) + uint8_t _wh[4] = {0}; + //! @brief WBGLOG Register (Window mask logic for BGs) + union { + struct { + uint8_t maskLogicBg4: 2; + uint8_t maskLogicBg3: 2; + uint8_t maskLogicBg2: 2; + uint8_t maskLogicBg1: 2; + }; + uint8_t raw = 0; + } _wbglog; + //! @brief WOBJLOG Register (Window mask logic for OBJs and Color Window) + union { + struct { + uint8_t maskLogicObj: 2; + uint8_t maskLogicColor: 2; + uint8_t _: 4; + }; + uint8_t raw = 0; + } _wobjlog; + //! @brief TM - TS Registers (Main & Sub Screen Designation) + union { + struct { + uint8_t enableWindowDisplayBg1: 1; + uint8_t enableWindowDisplayBg2: 1; + uint8_t enableWindowDisplayBg3: 1; + uint8_t enableWindowDisplayBg4: 1; + uint8_t enableWindowDisplayObj: 1; + uint8_t _: 3; + }; + uint8_t raw = 0; + } _t[2]; + //! @brief TMW - TSW Registers (Window Mask Designation for the Main/Sub Screen) + union { + struct { + uint8_t enableWindowMaskingBg1: 1; + uint8_t enableWindowMaskingBg2: 1; + uint8_t enableWindowMaskingBg3: 1; + uint8_t enableWindowMaskingBg4: 1; + uint8_t enableWindowMaskingObj: 1; + uint8_t _: 3; + }; + uint8_t raw = 0; + } _tw[2]; + //! @brief CGWSEL Register (Color Addition Select) + union { + struct { + uint8_t directColorMode: 1; + uint8_t addSubscreen: 1; + uint8_t _: 2; + uint8_t preventColorMath: 2; + uint8_t clipColorToBlackBeforeMath: 2; + }; + uint8_t raw = 0; + } _cgwsel; + //! @brief CGADSUB Register (Color Math designation) + union { + struct { + uint8_t enableColorMathBg1: 1; + uint8_t enableColorMathBg2: 1; + uint8_t enableColorMathBg3: 1; + uint8_t enableColorMathBg4: 1; + uint8_t enableColorMathObj: 1; + uint8_t enableColorMathBackdrop: 1; + uint8_t halfColorMath: 1; + uint8_t addSubtractSelect: 1; + }; + uint8_t raw = 0; + } _cgadsub; + //! @brief COLDATA Register (Fixed Color Data) + union { + struct { + uint8_t colorIntensity: 5; + uint8_t red: 1; + uint8_t green: 1; + uint8_t blue: 1; + }; + uint8_t raw = 0; + } _coldata; + //! @brief SETINI Register (Screen Mode/Video Select) + union { + struct { + uint8_t screenInterlace: 1; + uint8_t objInterlace: 1; + uint8_t overscanMode: 1; + uint8_t enablePseudoHiresMode: 1; + uint8_t _: 2; + uint8_t mode7ExtBg: 1; + uint8_t externalSync: 1; + }; + uint8_t raw = 0; + } _setini; + + // + + //! @brief MPYL - MPYM - MPYH Registers (Multiplication Result) + union { + struct { + uint32_t mpyl: 8; + uint32_t mpym: 8; + uint32_t mpyh: 8; + uint32_t _: 8; + }; + uint32_t mpy = 0; + } _mpy; + //! @brief SLHV - Software Latch for H/V Counter + uint8_t _slhv = 0; + //! @brief OAMDATAREAD - Data for OAM read + uint8_t _oamdataread = 0; + //! @brief VMDATALREAD/VMDATAHREAD - VRAM Data Read low/high byte + union { + struct { + uint16_t vmDataLRead: 8; + uint16_t vmDataHRead: 8; + }; + uint16_t raw = 0; + } _vmdataread; + //! @brief CGRAM Data read + union { + struct { + uint16_t cgDataLRead: 8; + uint16_t cgDataHRead: 8; + }; + uint16_t raw = 0; + } _cgdataread; + //! @brief OPHCT/OPVCT - Horizontal/Vertical Scanline Location + union { + struct { + uint16_t opct: 9; + uint16_t _: 7; + }; + uint16_t raw = 0; + } _opct; + //! @brief STAT77 - PPU Status Flag and Version + union { + struct { + uint8_t chipVersionNumber: 4; + uint8_t _: 1; + uint8_t modeSelect: 1; + uint8_t rangeOverFlag: 1; + uint8_t timeOverFlag: 1; + }; + uint8_t raw = 0; + } _stat77; + //! @brief STAT78 - PPU Status Flag and Version + union { + struct { + uint8_t chipVersionNumber: 4; + uint8_t mode: 1; + uint8_t _: 1; + uint8_t externalLatchFlag: 1; + uint8_t interlaceField: 1; + }; + uint8_t raw = 0; + } _stat78; + }; +} \ No newline at end of file From 2913e9eb2c5dec0fad79541099f8e5038dcec1e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 22:02:17 +0200 Subject: [PATCH 37/41] CMakeLists.txt fix --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddbdcbf..c69d842 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,8 @@ set(SOURCES sources/Models/Logger.hpp sources/PPU/PpuDebug.cpp sources/PPU/PpuDebug.hpp - sources/PPU/PPURegisters.hpp) + sources/PPU/PPURegisters.hpp + ) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) From 9692120626e35db3c38b70d1d9b0b77db7b8f657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 22:18:55 +0200 Subject: [PATCH 38/41] misc fixes --- sources/PPU/Background.cpp | 28 +++++++++------------------- sources/PPU/Background.hpp | 26 +++++++++----------------- sources/PPU/PPU.cpp | 8 ++++---- 3 files changed, 22 insertions(+), 40 deletions(-) diff --git a/sources/PPU/Background.cpp b/sources/PPU/Background.cpp index 08deada..d7cb004 100644 --- a/sources/PPU/Background.cpp +++ b/sources/PPU/Background.cpp @@ -10,22 +10,22 @@ namespace ComSquare::PPU { - Background::Background(ComSquare::PPU::PPU &ppu, int backGroundNumber, bool hasPriority) + Background::Background(ComSquare::PPU::PPU &ppu, int backgroundNumber) : _ppu(ppu), - _tileMapMirroring(ppu.getBackgroundMirroring(backGroundNumber)), - _characterNbPixels(ppu.getCharacterSize(backGroundNumber)), - _bpp(ppu.getBPP(backGroundNumber)), + _tileMapMirroring(ppu.getBackgroundMirroring(backgroundNumber)), + _characterNbPixels(ppu.getCharacterSize(backgroundNumber)), + _bpp(ppu.getBPP(backgroundNumber)), _directColor(false), _highRes(false), - _tileMapStartAddress(ppu.getTileMapStartAddress(backGroundNumber)), - _tilesetAddress(ppu.getTilesetAddress(backGroundNumber)), - _priority(hasPriority), - _bgNumber(backGroundNumber), + _tileMapStartAddress(ppu.getTileMapStartAddress(backgroundNumber)), + _tilesetAddress(ppu.getTilesetAddress(backgroundNumber)), + _bgNumber(backgroundNumber), _tileBuffer({{{0}}}), _vram(ppu.vram), _cgram(ppu.cgram), _tileRenderer(this->_vram, this->_cgram), - buffer({{{0}}}) + buffer({{{0}}}), + tilesPriority({{{false}}}) {} void Background::renderBackground() @@ -155,16 +155,6 @@ namespace ComSquare::PPU return this->_bgNumber; } - void Background::setPriority(bool priority) - { - this->_priority = priority; - } - - bool Background::getPriority() const - { - return this->_priority; - } - bool Background::isPriorityPixel(int y, int x) const { return this->tilesPriority[y / this->_characterNbPixels.y][x / this->_characterNbPixels.x]; diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index 6ec57e7..1687b88 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -8,10 +8,10 @@ #include #include #include "Models/Vector2.hpp" -#include "TileRenderer.hpp" +#include "PPU/TileRenderer.hpp" #include "Ram/Ram.hpp" -#include "PPU.hpp" -#include "PPUUtils.hpp" +#include "PPU/PPU.hpp" +#include "PPU/PPUUtils.hpp" namespace ComSquare::PPU { @@ -35,7 +35,7 @@ namespace ComSquare::PPU //! @brief The tilemap configuration nb of tileMap vertically and horizontally //! @note members are set to true if the tilemap is expended in their direction Vector2 _tileMapMirroring; - //! @brief The number of pixels of a character (x: height, y:width) + //! @brief The number of pixels of a character (x: width, y: height) Vector2 _characterNbPixels; //! @brief The number of bits per pixels to currently look for each pixel int _bpp; @@ -48,8 +48,6 @@ namespace ComSquare::PPU uint16_t _tileMapStartAddress; //! @brief The first address for tileset data uint16_t _tilesetAddress; - //! @brief If pixel from this background should be treated as primarily - bool _priority; //! @brief The bg number (used to get the corresponding scroll) int _bgNumber; //! @brief Buffer if we have tiles that are more than 8x8 @@ -76,11 +74,11 @@ namespace ComSquare::PPU Vector2 backgroundSize; //! @brief The output buffer (pixels are written on it) std::array, 1024> buffer; - + //! @brief The buffer of tile priority level std::array, 64> tilesPriority; - bool isPriorityPixel(int x, int y) const; - + //! @brief Tells if a pixel has high priority + [[nodiscard]] bool isPriorityPixel(int x, int y) const; //! @brief Render a background on his internal buffer void renderBackground(); //! @brief Set the tileMap start address @@ -100,13 +98,7 @@ namespace ComSquare::PPU //! @brief Get the BackGround Number //! @return the current Background number - int getBgNumber() const; - //! @brief set the Background priority - //! @param bgNumber the new Background priority - void setPriority(bool priority); - //! @brief Get the Background priority - //! @return the current Background priority - bool getPriority() const; + [[nodiscard]] int getBgNumber() const; //! @brief Add a bg buffer to another buffer @@ -141,7 +133,7 @@ namespace ComSquare::PPU } //! @brief ctor - Background(PPU &_ppu, int backGroundNumber, bool hasPriority); + Background(PPU &_ppu, int backgroundNumber); //! @brief Default copy ctor Background(const Background &) = default; //! @brief Default destructor diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index b073435..5c2f738 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -21,10 +21,10 @@ namespace ComSquare::PPU cgram(CGRamSize, ComSquare::CGRam, "CGRAM"), _renderer(renderer), _backgrounds{ - Background(*this, 1, false), - Background(*this, 2, false), - Background(*this, 3, false), - Background(*this, 4, false), + Background(*this, 1), + Background(*this, 2), + Background(*this, 3), + Background(*this, 4), }, _mainScreen({{{0}}}), _subScreen({{{0}}}) From f094b57c8753fbc90e85b64067cd1ae2033df39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 22:50:00 +0200 Subject: [PATCH 39/41] using C++ for loops instead of std::for_each when possible --- sources/PPU/Background.hpp | 11 ++++++----- sources/PPU/PPUUtils.hpp | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index 1687b88..c5b1147 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -111,11 +111,12 @@ namespace ComSquare::PPU int i = 0; int j = 0; int pixelLevel; - std::for_each(backgroundSrc.buffer.begin(), backgroundSrc.buffer.end(), [&](auto &sourceRow) { - std::for_each(sourceRow.begin(), sourceRow.end(), [&](auto &pixel) { + + for (const auto &sourceRow : backgroundSrc.buffer) { + for (const auto &pixel : sourceRow) { if (pixel <= 0xFF) { j++; - return; + continue; } pixelLevel = backgroundSrc.isPriorityPixel(i, j) ? levelHigh : levelLow; auto &pixelInitialLevel = pixelDestinationLevelMap[i][j]; @@ -125,10 +126,10 @@ namespace ComSquare::PPU pixelInitialLevel = pixelLevel; } j++; - }); + }; j = 0; i++; - }); + }; } diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 212993b..333f57d 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -88,14 +88,14 @@ namespace ComSquare::PPU::Utils { int i = 0; int j = 0; - std::for_each(bufferSrc.begin(), bufferSrc.end(), [&bufferDest, &i, &j](auto &sourceRow) { - std::for_each(sourceRow.begin(), sourceRow.end(), [&bufferDest, &i, &j](auto &pixel) { + for (const auto &sourceRow : bufferSrc) { + for (const auto &pixel : sourceRow) { if (pixel > 0xFF) bufferDest[i][j] = pixel; j++; - }); + }; j = 0; i++; - }); + }; } } From 5784f864577504d071837c3cd17f9b3cc71383a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 23:03:29 +0200 Subject: [PATCH 40/41] moving inline function definition in header file and using C++ for instead of for_each for screen rendering --- sources/PPU/PPU.cpp | 9 +++++---- sources/PPU/PPU.hpp | 4 ++-- sources/PPU/PPUUtils.cpp | 5 ----- sources/PPU/PPUUtils.hpp | 5 ++++- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 5c2f738..95076ec 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -306,13 +306,14 @@ namespace ComSquare::PPU int i = 0; int j = 0; - std::for_each(this->_screen.begin(), this->_screen.end(), [this, &i, &j](const auto &row) { - std::for_each(row.begin(), row.end(), [this, &i, &j](const auto &pixel) { + + for (const auto &row : this->_screen) { + for (const auto &pixel : row) { this->_renderer.putPixel(i, j++, pixel); - }); + }; j = 0; i++; - }); + }; /* diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 42b0ba0..55567e6 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -57,9 +57,9 @@ namespace ComSquare::PPU Background _backgrounds[4]; //! @brief Main Screen buffer std::array, 1024> _mainScreen; - std::array, 1024> _mainScreenLevelMap; + std::array, 1024> _mainScreenLevelMap; //! @brief Sub Screen buffer - std::array, 1024> _subScreenLevelMap; + std::array, 1024> _subScreenLevelMap; std::array, 1024> _subScreen; //! @brief Final Screen buffer std::array, 1024> _screen; diff --git a/sources/PPU/PPUUtils.cpp b/sources/PPU/PPUUtils.cpp index 0a0d588..b25385a 100644 --- a/sources/PPU/PPUUtils.cpp +++ b/sources/PPU/PPUUtils.cpp @@ -7,11 +7,6 @@ namespace ComSquare::PPU::Utils { - inline uint8_t to8Bit(int color) - { - return static_cast((color << 3) + (color >> 2)); - } - uint32_t CGRAMColorToRGBA(uint16_t CGRAMColor) { uint8_t b = to8Bit(CGRAMColor >> 10); diff --git a/sources/PPU/PPUUtils.hpp b/sources/PPU/PPUUtils.hpp index 333f57d..e6b099d 100644 --- a/sources/PPU/PPUUtils.hpp +++ b/sources/PPU/PPUUtils.hpp @@ -20,7 +20,10 @@ namespace ComSquare::PPU::Utils //! @brief Transform CGRAM color data to 8bits //! @note Used with b, g and r values //! @return The 8 bit value of the color - inline uint8_t to8Bit(int color); + inline uint8_t to8Bit(int color) + { + return static_cast((color << 3) + (color >> 2)); + } //! @brief Transform SNES color code BGR to uint32_t RGBA //! @param CGRAMColor The color of the CGRAM //! @return The CGRAM color to RGBA format From 8d18ca89dcbf2729237c96fda2e066733d47240a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 13 Jul 2021 23:18:32 +0200 Subject: [PATCH 41/41] adding documentation --- sources/PPU/Background.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sources/PPU/Background.hpp b/sources/PPU/Background.hpp index c5b1147..358c271 100644 --- a/sources/PPU/Background.hpp +++ b/sources/PPU/Background.hpp @@ -102,6 +102,13 @@ namespace ComSquare::PPU //! @brief Add a bg buffer to another buffer + //! @tparam levelLow The priority of a low priority pixel (working like z-index CSS property) + //! @tparam levelHigh The priority of a high priority pixel (working like z-index CSS property) + //! @tparam DEST_SIZE_X The Horizontal array size + //! @tparam DEST_SIZE_Y The Vertical array size + //! @param bufferDest The destination buffer (buffer that will be written on) + //! @param pixelDestinationLevelMap The destination buffer level map to use as reference and will be updated if a pixel has an higher level than the actual one + //! @param backgroundSrc The Background to use as a source template static void mergeBackgroundBuffer(std::array, DEST_SIZE_X> &bufferDest, std::array, DEST_SIZE_X> &pixelDestinationLevelMap,