diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 54e8542..7b412da 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -260,7 +260,7 @@ namespace ComSquare::PPU this->_renderer.putPixel(x, y, pixelTmp); } } - renderBackground(1, {0, 0}, 4, false); + renderBackground(1, {8, 8}, 4, false); this->_renderer.drawScreen(); } @@ -420,23 +420,27 @@ namespace ComSquare::PPU return this->cgram->read_internal(addr); } - void PPU::renderBackground(int bgNumber, std::vector characterSize, int bpp, bool priority) + void PPU::renderBackground(int bgNumber, Vector2 characterSize, int bpp, bool priority) { - int nbCharactersHeight = (this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring) ? 64 : 32; - int nbCharactersWidth = (this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring) ? 64 : 32; + int nbCharactersHeight = (this->_registers._bgsc[bgNumber - 1].tilemapVerticalMirroring) ? 2 : 1; + int nbCharactersWidth = (this->_registers._bgsc[bgNumber - 1].tilemapHorizontalMirroring) ? 2 : 1; uint16_t vramAddress = this->_registers._bgsc[bgNumber - 1].tilemapAddress << 1U; - int size = 8; - uint16_t tileMapValue; + Vector2 offset(0, 0); + // find an efficient way to render tilemap in order with correct offset and vramaddresses: + for (int i = 0; i < nbCharactersWidth ; i++) { + drawBasicTileMap(vramAddress, bgNumber, bpp, characterSize, offset); + vramAddress += 0x800; + offset.x += 32 * characterSize.x; + } + if (nbCharactersWidth == 1 && nbCharactersHeight == 2) { + vramAddress += 0x800; + nbCharactersHeight = 1; + offset.x = 0; + } + for (int i = 0; i < nbCharactersHeight ; i++) { + drawBasicTileMap(vramAddress, bgNumber, bpp, characterSize, offset); + vramAddress += 0x800; - if (this->_registers._bgmode.raw & (1U << (bgNumber + 3U))) - size = 16; - for (int i = 0; i < nbCharactersHeight; i++) { - for (int j = 0; j < nbCharactersWidth; j++) { - tileMapValue = this->vram->read_internal(vramAddress); - tileMapValue += this->vram->read_internal(vramAddress + 1) << 8U; - vramAddress += 2; - drawBgTile(tileMapValue, {i * size, j * size}, bgNumber, bpp, size); - } } } @@ -450,7 +454,7 @@ namespace ComSquare::PPU return baseAddress + (x * 16 * step) + (y * step); } - void PPU::drawBgTile(uint16_t data, Vector2 pos, int bg, int bpp, int size) + void PPU::drawBgTile(uint16_t data, Vector2 pos, int bg, int bpp, Vector2 characterSize) { uint16_t graphicAddress; union TileMapData tileData; @@ -463,8 +467,8 @@ namespace ComSquare::PPU tileData.raw = data; graphicAddress = this->getGraphicVramAddress(tileData.posX, tileData.posY, bg, bpp); // loop on all pixels of the tile 8x8 6x16 16x8 8x16 - for (int i = 0; i < size; i++) { - for (int j = 0; j < size; j++) { + for (int i = 0; i < characterSize.y; i++) { + for (int j = 0; j < characterSize.x; j++) { palette = getPalette(tileData.palette); reference = getTilePixelReference(graphicAddress, bpp, index); color = getRealColor(palette[reference]); @@ -477,7 +481,7 @@ namespace ComSquare::PPU } } index = 0; - pos.x -= size; + pos.x -= characterSize.x; pos.y++; } } @@ -528,4 +532,21 @@ namespace ComSquare::PPU } return 0; } + + void PPU::drawBasicTileMap(uint16_t baseAddress, int bgNumber, int bpp, Vector2 characterSize, Vector2 offset) + { + uint16_t tileMapValue = 0; + Vector2 pos(0,0); + uint16_t vramAddress = baseAddress; + + for (int j = baseAddress; j < (0x800 / 2) + baseAddress; j++) { + tileMapValue = this->vram->read_internal(vramAddress); + tileMapValue += this->vram->read_internal(vramAddress + 1) << 8U; + vramAddress += 2; + drawBgTile(tileMapValue, {((pos.x - pos.y * 32) * characterSize.x) + offset.x, (pos.y * characterSize.y) + offset.x}, bgNumber, bpp, characterSize); + pos.x++; + if (j % 32 == 0) + pos.y++; + } + } } \ No newline at end of file diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 7c8bd82..13dee70 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -589,17 +589,19 @@ namespace ComSquare::PPU //! @brief Allow others components to read the CGRAM (Debuggers) uint16_t cgramRead(uint16_t addr); //! @brief Render a background on the screen - void renderBackground(int bgNumber, std::vector characterSize, int bpp, bool priority); + void renderBackground(int bgNumber, Vector2 characterSize, int bpp, bool priority); //! @brief Get the correct Vram address for a gien x and y uint16_t getGraphicVramAddress(int x, int y, int bg, int bpp); //! @brief Draw a tile on the screen at x y pos - void drawBgTile(uint16_t data, Vector2 pos, int bg, int bpp, int size); + void drawBgTile(uint16_t data, Vector2 pos, int bg, int bpp, Vector2 characterSize); //! @brief Get a palette from the number of the palette (0 - 7) std::vector getPalette(int nbPalette); //! @brief Transform SNES color code BGR to uint32_t RGB uint32_t getRealColor(uint16_t color); //! @brief Get the color reference of a nb pixel tile uint8_t getTilePixelReference(uint16_t addr, int bpp, int nb); + //! @brief draw a tilemap 32x32 starting at baseAddress + void drawBasicTileMap(uint16_t baseAddress, int bgNumber, int bpp, Vector2 characterSize, Vector2 offset); }; } #endif //COMSQUARE_PPU_HPP