diff --git a/sources/Debugger/TileViewer/RAMTileRenderer.cpp b/sources/Debugger/TileViewer/RAMTileRenderer.cpp index 015ccca..4c13a3c 100644 --- a/sources/Debugger/TileViewer/RAMTileRenderer.cpp +++ b/sources/Debugger/TileViewer/RAMTileRenderer.cpp @@ -15,7 +15,7 @@ namespace ComSquare::Debugger _ramOffset(0), _bpp(2), _tileRenderer(ram, cgram), - buffer({{{0}}}) + buffer({{0}}) {} void RAMTileRenderer::render() @@ -24,8 +24,8 @@ namespace ComSquare::Debugger int bufY = 0; int nbTilesDrawn = 0; int resetX = bufX; - for (auto &i : this->buffer) - i.fill(0); + //for (auto &i : this->buffer) + // i.fill(0); uint24_t limit = std::fmin(this->_ram.getSize(), this->_renderSize) + this->_ramOffset; for (uint24_t i = this->_ramOffset; i < limit; i += PPU::Tile::BaseByteSize * this->_bpp, nbTilesDrawn++) { @@ -47,7 +47,7 @@ namespace ComSquare::Debugger for (const auto &raw : this->_tileRenderer.buffer) { for (const auto &pixel : raw) { - buffer[bufX++][bufY] = pixel; + this->buffer[bufX++][bufY] = pixel; } bufY++; bufX = resetX; diff --git a/sources/Debugger/TileViewer/RAMTileRenderer.hpp b/sources/Debugger/TileViewer/RAMTileRenderer.hpp index 7370fe3..5e1792e 100644 --- a/sources/Debugger/TileViewer/RAMTileRenderer.hpp +++ b/sources/Debugger/TileViewer/RAMTileRenderer.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include #include "PPU/TileRenderer.hpp" #include "Ram/Ram.hpp" @@ -27,7 +27,7 @@ namespace ComSquare::Debugger PPU::TileRenderer _tileRenderer; public: //! @brief internal buffer - std::array, 1024> buffer; + std::vector> buffer; //! @brief Set the palette to use for render (index of palette) void setPaletteIndex(int paletteIndex); //! @brief Set the bpp to render graphics diff --git a/sources/Debugger/TileViewer/TileViewer.cpp b/sources/Debugger/TileViewer/TileViewer.cpp index d622b1d..36b401d 100644 --- a/sources/Debugger/TileViewer/TileViewer.cpp +++ b/sources/Debugger/TileViewer/TileViewer.cpp @@ -11,18 +11,21 @@ #include #include "RAMTileRenderer.hpp" #include "PPU/PPU.hpp" +#include "PPU/Tile.hpp" namespace ComSquare::Debugger { TileViewer::TileViewer(SNES &snes, ComSquare::PPU::PPU &ppu) - : _window(new ClosableWindow([&snes] { snes.disableTileViewer(); })), + :_window(new ClosableWindow([&snes] { snes.disableTileViewer(); })), _snes(snes), _ui(), _ppu(ppu), _ramTileRenderer(ppu.vram, ppu.cgram) { this->_ui.setupUi(this->_window); - this->_sfWidget = std::make_unique(this->_ui.widget_sfml); + this->_qtSfmlRenderer(this->_ui.widget_sfml, 30); + this->_renderer = this->_qtSfmlRenderer; + // this->_sfWidget = std::make_unique(this->_ui.widget_sfml); QMainWindow::connect(this->_ui.NbColumns, QOverload::of(&QSpinBox::valueChanged), this, [this](int nb) -> void { this->setNbColumns(nb); }); QMainWindow::connect(this->_ui.ByteSize, QOverload::of(&QSpinBox::valueChanged), this, @@ -109,7 +112,15 @@ namespace ComSquare::Debugger void TileViewer::internalUpdate() { this->_ramTileRenderer.render(); - this->_sfWidget->buffer = this->_ramTileRenderer.buffer; + int i = 0; + int j = 0; + for (const auto &row : this->_ramTileRenderer.buffer) { + for (const auto &pixel : row) { + this->_renderer.putPixel(j++, i, pixel); + } + j = 0; + i++; + } } void TileViewer::setRamOffset(int offset) diff --git a/sources/Debugger/TileViewer/TileViewer.hpp b/sources/Debugger/TileViewer/TileViewer.hpp index e8f7fd8..e172189 100644 --- a/sources/Debugger/TileViewer/TileViewer.hpp +++ b/sources/Debugger/TileViewer/TileViewer.hpp @@ -31,11 +31,16 @@ namespace ComSquare::Debugger //! @brief A reference to the ppu ComSquare::PPU::PPU &_ppu; //! @brief the window - std::unique_ptr _sfWidget; + //std::unique_ptr _sfWidget; //! @brief The ram tile renderer RAMTileRenderer _ramTileRenderer; + //! @brief The instantiation of the renderer (should be passed via argument) + Renderer::QtWidgetSFML _qtSfmlRenderer; + //! @brief Renderer used to display tiles + Renderer::IRenderer &_renderer; //! @brief Change the bpp from the index given by the ui (QT combo box) void _bppChangeUIHandler(int index); + public: //! @brief ctor explicit TileViewer(SNES &snes, ComSquare::PPU::PPU &ppu); diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 95076ec..5105557 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -31,7 +31,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) diff --git a/sources/PPU/TileRenderer.cpp b/sources/PPU/TileRenderer.cpp index 5dfa5f9..5b9301e 100644 --- a/sources/PPU/TileRenderer.cpp +++ b/sources/PPU/TileRenderer.cpp @@ -75,7 +75,6 @@ namespace ComSquare::PPU uint8_t TileRenderer::getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex) { - // TODO unit test this uint16_t result = 0; switch (this->_bpp) { diff --git a/sources/Renderer/IRenderer.hpp b/sources/Renderer/IRenderer.hpp index 72c54bb..2430565 100644 --- a/sources/Renderer/IRenderer.hpp +++ b/sources/Renderer/IRenderer.hpp @@ -20,6 +20,11 @@ namespace ComSquare //! @brief Render the buffer to the window virtual void drawScreen() = 0; + //! @brief Set a size or resize the Renderer drawing size + //! @param height The new height of the renderer in pixels + //! @param width The new width of the renderer in pixels + virtual void setSize(unsigned width, unsigned height) = 0; + //! @brief Set a pixel to the coordinates x, y with the color rgba //! @param x The x position of the window (0, 0 is the top left corner). //! @param y The y position of the window (0, 0 is the top left corner). diff --git a/sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp b/sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp index 25d0805..72fe042 100644 --- a/sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp +++ b/sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp @@ -2,26 +2,31 @@ // Created by cbihan on 08/06/2021. // -#include +#include "PPU/Tile.hpp" #include "QtSfmlTileRenderer.hpp" + namespace ComSquare::Renderer { QtSFMLTileRenderer::QtSFMLTileRenderer(QWidget *parent, int frameRate) - : QtWidgetSFML(parent, {0, 0}, {1025, 1025}, frameRate) + : QtWidgetSFML(parent, {0, 0}, {16 * PPU::Tile::NbPixelsWidth, 18 * PPU::Tile::NbPixelsHeight}, frameRate) { // todo the size of the sfml renderwindow should fill the parent } void QtSFMLTileRenderer::onUpdate() { - this->_window.clear(sf::Color::Black); - for (unsigned long i = 0; i < this->buffer.size(); i++) { - for (unsigned long j = 0; j < this->buffer[i].size(); j++) { - this->putPixel(j, i, this->buffer[i][j]); + int i = 0; + int j = 0; + this->_renderWindow.clear(sf::Color::Black); + for (const auto &row : this->buffer) { + for (const auto &pixel : row) { + this->putPixel(j++, i, pixel); } + i++; + j = 0; } this->drawScreen(); } diff --git a/sources/Renderer/QtRenderer/QtWidgetSFML.cpp b/sources/Renderer/QtRenderer/QtWidgetSFML.cpp index e9011fa..936c12c 100644 --- a/sources/Renderer/QtRenderer/QtWidgetSFML.cpp +++ b/sources/Renderer/QtRenderer/QtWidgetSFML.cpp @@ -29,8 +29,8 @@ namespace ComSquare::Renderer #ifdef Q_WS_X11 XFlush(QX11Info::display()); #endif - this->_window.create(static_cast(this->winId())); - this->_window.setFramerateLimit(60); + this->_renderWindow.create(static_cast(this->winId())); + this->_renderWindow.setFramerateLimit(60); this->_onInit(); this->_timer.setSingleShot(false); @@ -52,4 +52,15 @@ namespace ComSquare::Renderer void QtWidgetSFML::_onInit() {} + + void QtWidgetSFML::setSize(unsigned int width, unsigned int height) + { + SFRenderer::setSize(width, height); + QWidget::resize(static_cast(width), static_cast(height)); + } + + void QtWidgetSFML::onUpdate() + { + this->drawScreen(); + } } \ No newline at end of file diff --git a/sources/Renderer/QtRenderer/QtWidgetSFML.hpp b/sources/Renderer/QtRenderer/QtWidgetSFML.hpp index 14a896a..d35f64b 100644 --- a/sources/Renderer/QtRenderer/QtWidgetSFML.hpp +++ b/sources/Renderer/QtRenderer/QtWidgetSFML.hpp @@ -18,7 +18,12 @@ namespace ComSquare::Renderer Q_OBJECT public slots: //! @brief Function called to update this widget. - virtual void onUpdate() = 0; + virtual void onUpdate(); + + //! @brief Set a size or resize the Renderer drawing size + //! @param height The new height of the renderer in pixels + //! @param width The new width of the renderer in pixels + void setSize(unsigned width, unsigned height) override; private: //! @brief Function called when this widget is created. virtual void _onInit(); diff --git a/sources/Renderer/SFRenderer.cpp b/sources/Renderer/SFRenderer.cpp index 3930b95..dc7239a 100644 --- a/sources/Renderer/SFRenderer.cpp +++ b/sources/Renderer/SFRenderer.cpp @@ -12,21 +12,21 @@ namespace ComSquare::Renderer { SFRenderer::SFRenderer(unsigned int height, unsigned int width) + : _videoMode({width, height, 32}), + _pixelBuffer(new sf::Color[height * width]) { - this->_videoMode = {width, height, 32}; this->_texture.create(width, height); this->_sprite.setTexture(this->_texture); - this->_pixelBuffer = new sf::Color[height * width]; this->_sound.setBuffer(this->_soundBuffer); } void SFRenderer::createWindow(SNES &snes, int maxFPS) { sf::Image icon; - this->_window.create(this->_videoMode, "ComSquare Emulator", sf::Style::Default); + this->_renderWindow.create(this->_videoMode, "ComSquare Emulator", sf::Style::Default); if (icon.loadFromFile("resources/Logo.png")) - this->_window.setIcon(314, 314, icon.getPixelsPtr()); - this->_window.setFramerateLimit(maxFPS); + this->_renderWindow.setIcon(314, 314, icon.getPixelsPtr()); + this->_renderWindow.setFramerateLimit(maxFPS); this->setWindowName(snes.cartridge.header.gameName); while (!this->shouldExit) { @@ -37,20 +37,20 @@ namespace ComSquare::Renderer SFRenderer::~SFRenderer() { - delete [] this->_pixelBuffer; + delete[] this->_pixelBuffer; } void SFRenderer::setWindowName(std::string &newWindowName) { - this->_window.setTitle(newWindowName + " - ComSquare"); + this->_renderWindow.setTitle(newWindowName + " - ComSquare"); } void SFRenderer::drawScreen() { this->_texture.update(reinterpret_cast(this->_pixelBuffer)); this->_sprite.setTexture(this->_texture); - this->_window.draw(this->_sprite); - this->_window.display(); + this->_renderWindow.draw(this->_sprite); + this->_renderWindow.display(); } void SFRenderer::playAudio(std::span samples) @@ -71,12 +71,24 @@ namespace ComSquare::Renderer void SFRenderer::getEvents() { - sf::Event event; - while (this->_window.pollEvent(event)) { + sf::Event event{}; + while (this->_renderWindow.pollEvent(event)) { if (event.type == sf::Event::Closed) { this->shouldExit = true; break; } } } + + void SFRenderer::setSize(unsigned int width, unsigned int height) + { + this->_renderWindow.setSize({width, height}); + this->_videoMode.width = width; + this->_videoMode.height = height; + if (!this->_texture.create(width, height)) { + throw std::runtime_error("sfml texture resize failed"); + } + delete[] this->_pixelBuffer; + this->_pixelBuffer = new sf::Color[height * width]; + } } diff --git a/sources/Renderer/SFRenderer.hpp b/sources/Renderer/SFRenderer.hpp index c0cb08c..910ca1a 100644 --- a/sources/Renderer/SFRenderer.hpp +++ b/sources/Renderer/SFRenderer.hpp @@ -20,13 +20,13 @@ namespace ComSquare::Renderer public: explicit InvalidPixelPosition(const std::string &name, unsigned int x, unsigned int width) : _msg("Trying to place a pixel at an invalid " + name + " (" + std::to_string(x) + ">=" + std::to_string(width) + ")") {} - const char *what() const noexcept override { return this->_msg.c_str(); } + [[nodiscard]] const char *what() const noexcept override { return this->_msg.c_str(); } }; class SFRenderer : public IRenderer { protected: //! @brief The Renderer for the window. - sf::RenderWindow _window; + sf::RenderWindow _renderWindow; //! @brief Video Mode containing the _height and _width of the window. sf::VideoMode _videoMode; //! @brief The image that contain all of the pixels @@ -48,6 +48,10 @@ namespace ComSquare::Renderer void setWindowName(std::string &newWindowName) override; //! @brief Update the screen by printing the buffer. void drawScreen() override; + //! @brief Set a size or resize the Renderer drawing size + //! @param height The new height of the renderer in pixels + //! @param width The new width of the renderer in pixels + void setSize(unsigned width, unsigned height) override; //! @brief Add a pixel to the buffer to the coordinates x, y with the color rgba. //! @param X horizontal index. //! @param Y vertical index. diff --git a/ui/tileView.ui b/ui/tileView.ui index 8e1a55c..a76b3be 100644 --- a/ui/tileView.ui +++ b/ui/tileView.ui @@ -22,7 +22,45 @@ - + + + + 0 + 7 + + + + + 300 + 400 + + + + + 1024 + 1024 + + + + true + + + + + 0 + 0 + 1024 + 1024 + + + + + 1024 + 1024 + + + + @@ -55,14 +93,14 @@ - + SIze (bytes) - + true @@ -93,14 +131,14 @@ - + Format - + 2 bpp @@ -131,7 +169,7 @@ - + ArrowCursor @@ -140,10 +178,11 @@ Columns + - + false @@ -162,14 +201,14 @@ - + Palette Index - + 255