// // Created by cbihan on 24/05/2021. // #include #include "TileRenderer.hpp" #include "PPU/PPU.hpp" namespace ComSquare::Debugger { TileRenderer::TileRenderer() : _ram(nullptr), _cgram(nullptr), _bpp(2), _palette(0), buffer({{{0}}}) { } void TileRenderer::setRam(std::shared_ptr ram) { this->_ram = std::move(ram); } void TileRenderer::render() { uint8_t colorReference; uint24_t color; std::vector palette = this->getPalette(this->_palette); int bufX = 0; int bufY = 0; int nbTilesDrawn = 0; int resetX = 0; for (uint24_t i = 0; i < this->_ram->getSize(); i += this->_bpp) { if (bufX >= 1024 || bufY >= 1024) break; for (int j = 0; j < 8; j++) { colorReference = this->getPixelReferenceFromTileRow(i, j); color = PPU::getRealColor(palette[colorReference]); buffer[bufY][bufX++] = color; } bufY++; bufX = resetX; } } void TileRenderer::setPalette(int palette) { this->_palette = palette; } void TileRenderer::setBpp(int bpp) { this->_bpp = bpp; } uint8_t TileRenderer::getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex) { size_t size = this->_ram->getSize(); uint8_t highByte = this->_ram->read(tileRowAddress % size); uint8_t lowByte = this->_ram->read((tileRowAddress + 1) % size); uint8_t secondHighByte; uint8_t secondLowByte; uint16_t result = 0; uint8_t shift = 8 - 1U - pixelIndex; switch (this->_bpp) { case 8: return highByte; case 4: secondHighByte = this->_ram->read((tileRowAddress + 16) % size); secondLowByte = this->_ram->read((tileRowAddress + 17) % size); result = ((secondHighByte & (1U << shift)) | ((secondLowByte & (1U << shift)) << 1U)); result = (shift - 2 >= 0) ? result >> (shift - 2) : result << ((shift - 2) * -1); FALLTHROUGH case 2: result += ((highByte & (1U << shift)) | ((lowByte & (1U << shift)) << 1U)) >> shift; default: break; } return result; } std::vector TileRenderer::getPalette(int nbPalette) { uint8_t nbColors = std::pow(2, this->_bpp); uint16_t addr = nbPalette * this->_bpp * this->_bpp * 2; // 2 because it's 2 addr for 1 color std::vector palette(nbColors); for (int i = 0; i < nbColors; i++) { palette[i] = this->_cgram->read(addr); palette[i] += this->_cgram->read(addr + 1) << 8U; addr += 2; } return palette; } void TileRenderer::setCgram(std::shared_ptr ram) { this->_cgram = std::move(ram); } }