starting to implement true TileRenderer

This commit is contained in:
Clément Le Bihan
2021-05-24 00:28:08 +02:00
parent 4e42c4774a
commit 4024b51c9f
8 changed files with 194 additions and 77 deletions

View File

@@ -237,9 +237,12 @@ add_executable(ComSquare
sources/APU/DSP/Timer.cpp
sources/APU/DSP/BRR.cpp
sources/PPU/PPUUtils.cpp
sources/Debugger/TileViewer.cpp
sources/Debugger/TileViewer.hpp
ui/tileView.ui sources/Renderer/QtRenderer/QtRenderSfml.cpp sources/Renderer/QtRenderer/QtRenderSfml.hpp)
ui/tileView.ui
sources/Renderer/QtRenderer/QtRenderSfml.cpp
sources/Renderer/QtRenderer/QtRenderSfml.hpp
sources/Debugger/TileViewer/TileViewer.cpp
sources/Debugger/TileViewer/TileViewer.hpp
)
include_directories(ComSquare sources)

View File

@@ -1,57 +0,0 @@
//
// Created by cbihan on 5/7/21.
//
namespace ComSquare::Renderer
{
class QtFullSFML;
}
#include "../Renderer/QtRenderer/QtSFML.hpp"
#include "TileViewer.hpp"
#include "../SNES.hpp"
#include <QColor>
#include <string>
#include <iostream>
#include <QtWidgets/QTableWidget>
#include "../Utility/Utility.hpp"
namespace ComSquare::Debugger
{
TileViewer::TileViewer(SNES &snes, ComSquare::PPU::PPU &ppu)
: _window(new ClosableWindow<TileViewer>(*this, &TileViewer::disableViewer)),
_snes(snes),
_ui(),
_ppu(ppu)
{
this->_window->setContextMenuPolicy(Qt::NoContextMenu);
this->_window->setAttribute(Qt::WA_QuitOnClose, false);
this->_window->setAttribute(Qt::WA_DeleteOnClose);
this->_ui.setupUi(this->_window);
this->_sfWidget = std::make_unique<Renderer::QtSFML>(this->_ui.tab);
this->_window->show();
QEvent::registerEventType();
}
void TileViewer::disableViewer()
{
this->_snes.disableTileViewerDebugging();
}
void TileViewer::focus()
{
this->_window->activateWindow();
}
bool TileViewer::isDebugger()
{
return true;
}
uint16_t TileViewer::read(uint8_t addr)
{
return this->_ppu.cgramRead(addr);
}
}

View File

@@ -0,0 +1,142 @@
//
// Created by cbihan on 5/7/21.
//
namespace ComSquare::Renderer
{
class QtFullSFML;
}
#include "Renderer/QtRenderer/QtSFML.hpp"
#include "TileViewer.hpp"
#include "SNES.hpp"
#include <QColor>
#include <string>
#include <iostream>
#include <QtWidgets/QTableWidget>
#include <utility>
#include <complex>
#include "Utility/Utility.hpp"
#include "PPU/PPU.hpp"
namespace ComSquare::Debugger
{
TileViewer::TileViewer(SNES &snes, ComSquare::PPU::PPU &ppu)
: _window(new ClosableWindow<TileViewer>(*this, &TileViewer::disableViewer)),
_snes(snes),
_ui(),
_ppu(ppu)
{
this->_window->setContextMenuPolicy(Qt::NoContextMenu);
this->_window->setAttribute(Qt::WA_QuitOnClose, false);
this->_window->setAttribute(Qt::WA_DeleteOnClose);
this->_ui.setupUi(this->_window);
this->_sfWidget = std::make_unique<Renderer::QtSFML>(this->_ui.tab);
this->_window->show();
QEvent::registerEventType();
}
void TileViewer::disableViewer()
{
this->_snes.disableTileViewerDebugging();
}
void TileViewer::focus()
{
this->_window->activateWindow();
}
bool TileViewer::isDebugger()
{
return true;
}
uint16_t TileViewer::read(uint8_t addr)
{
return this->_ppu.cgramRead(addr);
}
TileRenderer::TileRenderer()
: _ram(nullptr),
_cgram(nullptr),
_bpp(2),
_palette(0),
buffer({{{0}}})
{
}
void TileRenderer::setRam(std::shared_ptr<Ram::Ram> ram)
{
this->_ram = std::move(ram);
}
void TileRenderer::render()
{
uint8_t colorReference;
uint24_t color;
std::vector<uint16_t> palette = this->getPalette(this->_palette);
int bufX = 0;
int bufY = 0;
for (uint24_t i = 0; i < this->_ram->getSize(); i += this->_bpp) {
for (int j = 0; j < 8; j ++) {
colorReference = this->getPixelReferenceFromTileRow(i, j);
color = PPU::getRealColor(palette[colorReference]);
buffer[bufY++][bufX++] = color;
}
}
}
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<uint16_t> 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<uint16_t> 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;
}
}

View File

@@ -7,14 +7,42 @@
#include <QtCore/QSortFilterProxyModel>
#include <QEvent>
#include <QMouseEvent>
#include <array>
#include "PPU/PPU.hpp"
#include "ClosableWindow.hpp"
#include "../Renderer/QtRenderer/QtSFML.hpp"
#include "../../ui/ui_tileView.h"
#include "Renderer/QtRenderer/QtSFML.hpp"
#include "ui/ui_tileView.h"
#include "Ram/Ram.hpp"
namespace ComSquare::Debugger
{
class TileRenderer {
private:
//! @brief ram to render
std::shared_ptr<Ram::Ram> _ram;
//! @brief cgram to access the colors
std::shared_ptr<Ram::Ram> _cgram;
//! @brief The bpp to use while rendering
int _bpp,
//! @brief The palette number to use while rendering
int _palette;
public:
//! @brief internal buffer
std::array<std::array<uint32_t, 500>, 1024> buffer;
void setPalette(int palette);
void setBpp(int bpp);
void setRam(std::shared_ptr<Ram::Ram> ram);
uint8_t getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex);
std::vector<uint16_t> getPalette(int nbPalette);
//! @brief render the selected ram
void render();
TileRenderer();
TileRenderer(const TileRenderer &) = default;
~TileRenderer() = default;
TileRenderer &operator=(const TileRenderer &) = default;
};
//! @brief window that allow the user to view all data going through the memory bus.
class TileViewer : public QObject {
private:

View File

@@ -121,10 +121,10 @@ namespace ComSquare::PPU
return this->getPixelReferenceFromTileRow(tileAddress, column);
}
uint8_t Background::getPixelReferenceFromTileRow(uint16_t tileAddress, uint8_t pixelIndex)
uint8_t Background::getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex)
{
uint8_t highByte = this->_vram->read(tileAddress % VRAMSIZE);
uint8_t lowByte = this->_vram->read((tileAddress + 1) % VRAMSIZE);
uint8_t highByte = this->_vram->read(tileRowAddress % VRAMSIZE);
uint8_t lowByte = this->_vram->read((tileRowAddress + 1) % VRAMSIZE);
uint8_t secondHighByte;
uint8_t secondLowByte;
uint16_t result = 0;
@@ -134,8 +134,8 @@ namespace ComSquare::PPU
case 8:
return highByte;
case 4:
secondHighByte = this->_vram->read((tileAddress + 16) % VRAMSIZE);
secondLowByte = this->_vram->read((tileAddress + 17) % VRAMSIZE);
secondHighByte = this->_vram->read((tileRowAddress + 16) % VRAMSIZE);
secondLowByte = this->_vram->read((tileRowAddress + 17) % VRAMSIZE);
result = ((secondHighByte & (1U << shift)) | ((secondLowByte & (1U << shift)) << 1U));
result = (shift - 2 >= 0) ? result >> (shift - 2) : result << ((shift - 2) * -1);
FALLTHROUGH

View File

@@ -70,10 +70,10 @@ namespace ComSquare::PPU
//! @return The array of color of the palette
std::vector<uint16_t> getPalette(int nbPalette);
//! @brief Get the color reference of a pixel from the address of the row
//! @param tileAddress The address of the line of pixel
//! @param tileRowAddress The address of the line of pixel
//! @param pixelIndex The index of the pixel (0 - 7)
//! @return The color Reference
uint8_t getPixelReferenceFromTileRow(uint16_t tileAddress, uint8_t pixelIndex);
uint8_t getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex);
//! @brief Get the color pixel reference from the tile address
//! @param tileAddress The starting address of the tile
//! @param pixelIndex The index of the pixel (0 - 255)

View File

@@ -41,7 +41,7 @@ namespace ComSquare::PPU
this->cgram->write(7, 0x03);
this->cgram->write(66, 0xE0);
this->cgram->write(67, 0x7F);
/*
//tiles
int vram_test[] = {
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -74,17 +74,17 @@ namespace ComSquare::PPU
00,0x03,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0c,0x00,0x18,0x00,0xf0,0x00,0xe0,
00,0x00,0x00,0x00,0x80,0x00,0xc0,0x00,0xe0,0x00,0xf0,0x00,0xf8,0x00,0xfc,0x00,
00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x0f,00,0x1f,00,0x3f,00, -1
};
/*int *cgram_test = get_dump_cgram();
}; */
int *cgram_test = get_dump_cgram();
for (int i = 0; cgram_test[i] != -1; i++) {
this->cgram->write(i, cgram_test[i]);
}*/
}
// int *vram_test = get_dump_vram();
int *vram_test = get_dump_vram();
for (int i = 0; vram_test[i] != -1; i++) {
this->vram->write(i, vram_test[i]);
}
int vram_test_2[] = {8, 00, 02, 00, 0x0A, 00, 02, 00, 0x0A, 00, 00, 00, 00, 00, 00, -1};
/* int vram_test_2[] = {8, 00, 02, 00, 0x0A, 00, 02, 00, 0x0A, 00, 00, 00, 00, 00, 00, -1};
for (int i = 0; vram_test_2[i] != -1; i++) {
this->vram->write(i + 0x8000, vram_test_2[i]);
}
@@ -143,8 +143,8 @@ namespace ComSquare::PPU
//this->_registers._bgofs[3].raw = 0x03DF;
this->_registers._t[0].enableWindowDisplayBg1 = true;
this->_registers._t[0].enableWindowDisplayBg2 = true;
*/
/*
//registers aladin
this->_registers._bgmode.bgMode = 1;
@@ -199,7 +199,7 @@ namespace ComSquare::PPU
this->_registers._t[0].enableWindowDisplayBg2 = true;
this->_registers._t[0].enableWindowDisplayBg3 = true;
*/
}
uint8_t PPU::read(uint24_t addr)

View File

@@ -569,6 +569,7 @@ namespace ComSquare::PPU
uint16_t _vramReadBuffer = 0;
//! @brief Struct that contain all necessary vars for the use of the registers
struct PpuState _ppuState;
public:
explicit PPU(Renderer::IRenderer &renderer);