mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-31 17:33:07 +00:00
general cleanup can not work with 4bpp going to check
This commit is contained in:
+1
-1
@@ -242,7 +242,7 @@ add_executable(ComSquare
|
||||
sources/Renderer/QtRenderer/QtRenderSfml.hpp
|
||||
sources/Debugger/TileViewer/TileViewer.cpp
|
||||
sources/Debugger/TileViewer/TileViewer.hpp
|
||||
sources/Debugger/TileViewer/TileRenderer.cpp sources/Debugger/TileViewer/TileRenderer.hpp sources/PPU/Tile.hpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.hpp sources/PPU/TileRenderer.cpp sources/PPU/TileRenderer.hpp)
|
||||
sources/Debugger/TileViewer/RAMTileRenderer.cpp sources/Debugger/TileViewer/RAMTileRenderer.hpp sources/PPU/Tile.hpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.cpp sources/Renderer/QtRenderer/QtSfmlTileRenderer.hpp sources/PPU/TileRenderer.cpp sources/PPU/TileRenderer.hpp)
|
||||
|
||||
include_directories(ComSquare sources)
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Created by cbihan on 24/05/2021.
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include "RAMTileRenderer.hpp"
|
||||
#include "PPU/PPU.hpp"
|
||||
#include "PPU/Tile.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
RAMTileRenderer::RAMTileRenderer()
|
||||
: _ram(nullptr),
|
||||
_renderSize(0x5000),
|
||||
_nbColumns(16),
|
||||
_ramOffset(0),
|
||||
_bpp(2),
|
||||
buffer({{{0}}})
|
||||
{
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setRam(std::shared_ptr<Ram::Ram> ram)
|
||||
{
|
||||
this->_ram = ram;
|
||||
this->_tileRenderer.setRam(ram);
|
||||
}
|
||||
|
||||
void RAMTileRenderer::render()
|
||||
{
|
||||
int bufX = 0;
|
||||
int bufY = 0;
|
||||
int nbTilesDrawn = 0;
|
||||
int resetX = bufX;
|
||||
for (auto &i : buffer)
|
||||
i.fill(0);
|
||||
uint24_t limit = fmin(this->_ram->getSize(), this->_renderSize) + this->_ramOffset;
|
||||
|
||||
for (uint24_t i = this->_ramOffset; i < limit; i += PPU::Tile::BaseByteSize * this->_bpp, nbTilesDrawn++) {
|
||||
if (bufX > 1024 || bufY > 1024)
|
||||
break;
|
||||
|
||||
this->_tileRenderer.render(i);
|
||||
if (nbTilesDrawn) {
|
||||
resetX += PPU::Tile::NbPixelsWidth;
|
||||
bufX = resetX;
|
||||
bufY -= PPU::Tile::NbPixelsHeight;
|
||||
}
|
||||
if (nbTilesDrawn && nbTilesDrawn % this->_nbColumns == 0) {
|
||||
nbTilesDrawn = 0;
|
||||
resetX = 0;
|
||||
bufX = resetX;
|
||||
bufY += PPU::Tile::NbPixelsHeight;
|
||||
}
|
||||
|
||||
for (const auto &raw : this->_tileRenderer.buffer) {
|
||||
for (const auto &pixel : raw) {
|
||||
buffer[bufX++][bufY] = pixel;
|
||||
}
|
||||
bufY++;
|
||||
bufX = resetX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setPaletteIndex(int paletteIndex)
|
||||
{
|
||||
this->_tileRenderer.setPaletteIndex(paletteIndex);
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setBpp(int bpp)
|
||||
{
|
||||
this->_tileRenderer.setBpp(bpp);
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setCgram(std::shared_ptr<Ram::Ram> ram)
|
||||
{
|
||||
this->_tileRenderer.setCgram(ram);
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setRenderSize(int size)
|
||||
{
|
||||
this->_renderSize = size;
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setNbColumns(int nbColumns)
|
||||
{
|
||||
this->_nbColumns = nbColumns;
|
||||
}
|
||||
|
||||
int RAMTileRenderer::getBpp() const
|
||||
{
|
||||
return this->_tileRenderer.getBpp();
|
||||
}
|
||||
|
||||
int RAMTileRenderer::getPaletteIndex() const
|
||||
{
|
||||
return this->_tileRenderer.getPaletteIndex();
|
||||
}
|
||||
|
||||
int RAMTileRenderer::getNbColumns() const
|
||||
{
|
||||
return this->_nbColumns;
|
||||
}
|
||||
|
||||
void RAMTileRenderer::setRamOffset(int offset)
|
||||
{
|
||||
this->_ramOffset = offset;
|
||||
}
|
||||
}
|
||||
+14
-14
@@ -5,26 +5,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "PPU/TileRenderer.hpp"
|
||||
#include "Ram/Ram.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
class TileRenderer {
|
||||
class RAMTileRenderer {
|
||||
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 _paletteIndex;
|
||||
//! @brief The size to render in the ram
|
||||
int _renderSize;
|
||||
//! @brief The number of tile columns to display
|
||||
int _nbColumns;
|
||||
//! @brief Bytes to skip from the start of the ram
|
||||
int _ramOffset;
|
||||
//! @brief The actual bpp to render
|
||||
int _bpp;
|
||||
//! @brief The class tha actually render the tile
|
||||
PPU::TileRenderer _tileRenderer;
|
||||
public:
|
||||
//! @brief internal buffer
|
||||
std::array<std::array<uint32_t, 1024>, 1024> buffer;
|
||||
@@ -48,15 +47,16 @@ namespace ComSquare::Debugger
|
||||
int getPaletteIndex() const;
|
||||
//! @brief Get the numbr of maximum tile columns to render
|
||||
int getNbColumns() const;
|
||||
uint8_t getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex);
|
||||
std::vector<uint16_t> getPalette(int nbPalette);
|
||||
uint8_t read2BPPValue(uint16_t tileRowAddress, uint8_t pixelIndex);
|
||||
//! @brief render the selected ram
|
||||
void render();
|
||||
TileRenderer();
|
||||
TileRenderer(const TileRenderer &) = default;
|
||||
~TileRenderer() = default;
|
||||
TileRenderer &operator=(const TileRenderer &) = default;
|
||||
//! @brief ctor
|
||||
RAMTileRenderer();
|
||||
//! @brief copy ctor
|
||||
RAMTileRenderer(const RAMTileRenderer &) = default;
|
||||
//! @brief dtor
|
||||
~RAMTileRenderer() = default;
|
||||
//! @brief assignment operator
|
||||
RAMTileRenderer &operator=(const RAMTileRenderer &) = default;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
//
|
||||
// Created by cbihan on 24/05/2021.
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include "TileRenderer.hpp"
|
||||
#include "PPU/PPU.hpp"
|
||||
#include "PPU/Tile.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
TileRenderer::TileRenderer()
|
||||
: _ram(nullptr),
|
||||
_cgram(nullptr),
|
||||
_bpp(2),
|
||||
_paletteIndex(0),
|
||||
_renderSize(0x5000),
|
||||
_nbColumns(16),
|
||||
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->_paletteIndex);
|
||||
int bufX = 0;
|
||||
int bufY = 0;
|
||||
int nbTilesDrawn = 0;
|
||||
int resetX = bufX;
|
||||
int it = 0;
|
||||
for (auto &i : buffer)
|
||||
i.fill(0);
|
||||
|
||||
for (uint24_t i = this->_ramOffset; i < fmin(this->_ram->getSize(), this->_renderSize) + this->_ramOffset; i += 2, it++) {
|
||||
if (bufX > 1024 || bufY > 1024)
|
||||
break;
|
||||
if (it && it % 8 == 0) {
|
||||
resetX += PPU::Tile::NbPixelsWidth;
|
||||
bufX = resetX;
|
||||
bufY -= PPU::Tile::NbPixelsHeight;
|
||||
i += (this->_bpp - 2) * 0x8;
|
||||
nbTilesDrawn++;
|
||||
}
|
||||
if (nbTilesDrawn && nbTilesDrawn % this->_nbColumns == 0) {
|
||||
nbTilesDrawn = 0;
|
||||
resetX = 0;
|
||||
bufX = resetX;
|
||||
bufY += PPU::Tile::NbPixelsHeight;
|
||||
}
|
||||
for (int j = 0; j < 8; j++) {
|
||||
colorReference = this->getPixelReferenceFromTileRow(i, j);
|
||||
color = PPU::getRealColor(palette[colorReference]);
|
||||
buffer[bufX++][bufY] = color;
|
||||
}
|
||||
bufY++;
|
||||
bufX = resetX;
|
||||
}
|
||||
}
|
||||
|
||||
void TileRenderer::setPaletteIndex(int paletteIndex)
|
||||
{
|
||||
this->_paletteIndex = paletteIndex;
|
||||
}
|
||||
|
||||
void TileRenderer::setBpp(int bpp)
|
||||
{
|
||||
this->_bpp = bpp;
|
||||
}
|
||||
|
||||
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);
|
||||
uint8_t shift = 8 - 1U - pixelIndex;
|
||||
|
||||
return ((highByte & (1U << shift)) | ((lowByte & (1U << shift)) << 1U)) >> shift;
|
||||
}
|
||||
|
||||
uint8_t TileRenderer::getPixelReferenceFromTileRow(uint16_t tileRowAddress, uint8_t pixelIndex)
|
||||
{
|
||||
// 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;
|
||||
FALLTHROUGH
|
||||
case 4:
|
||||
result += this->read2BPPValue(tileRowAddress + TileByteSizeRow, pixelIndex) << 2;
|
||||
FALLTHROUGH
|
||||
case 2:
|
||||
result += this->read2BPPValue(tileRowAddress, pixelIndex);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<uint16_t> TileRenderer::getPalette(int nbPalette)
|
||||
{
|
||||
uint16_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;
|
||||
}
|
||||
|
||||
void TileRenderer::setCgram(std::shared_ptr<Ram::Ram> ram)
|
||||
{
|
||||
this->_cgram = std::move(ram);
|
||||
}
|
||||
|
||||
void TileRenderer::setRenderSize(int size)
|
||||
{
|
||||
this->_renderSize = size;
|
||||
}
|
||||
|
||||
void TileRenderer::setNbColumns(int nbColumns)
|
||||
{
|
||||
this->_nbColumns = nbColumns;
|
||||
}
|
||||
|
||||
int TileRenderer::getBpp() const
|
||||
{
|
||||
return this->_bpp;
|
||||
}
|
||||
|
||||
int TileRenderer::getPaletteIndex() const
|
||||
{
|
||||
return this->_paletteIndex;
|
||||
}
|
||||
|
||||
int TileRenderer::getNbColumns() const
|
||||
{
|
||||
return this->_nbColumns;
|
||||
}
|
||||
|
||||
void TileRenderer::setRamOffset(int offset)
|
||||
{
|
||||
this->_ramOffset = offset;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace ComSquare::Renderer
|
||||
#include <iostream>
|
||||
#include <QtWidgets/QTableWidget>
|
||||
#include "Utility/Utility.hpp"
|
||||
#include "TileRenderer.hpp"
|
||||
#include "RAMTileRenderer.hpp"
|
||||
#include "PPU/PPU.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace ComSquare::PPU
|
||||
#include "Renderer/QtRenderer/QtSfmlTileRenderer.hpp"
|
||||
#include "../../../ui/ui_tileView.h"
|
||||
#include "Ram/Ram.hpp"
|
||||
#include "TileRenderer.hpp"
|
||||
#include "RAMTileRenderer.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
@@ -37,7 +37,7 @@ namespace ComSquare::Debugger
|
||||
//! @brief the window
|
||||
std::unique_ptr<Renderer::QtSFMLTileRenderer> _sfWidget;
|
||||
//! @brief The tile renderer
|
||||
TileRenderer _tileRenderer;
|
||||
RAMTileRenderer _tileRenderer;
|
||||
//! @brief Change the bpp from the index given by the ui (QT combo box)
|
||||
void _bppChangeUIHandler(int index);
|
||||
public:
|
||||
|
||||
+13
-12
@@ -23,12 +23,13 @@ namespace ComSquare::PPU
|
||||
_tilesetAddress(ppu.getTilesetAddress(backGroundNumber)),
|
||||
_priority(hasPriority),
|
||||
_bgNumber(backGroundNumber),
|
||||
_tileBuffer({{{0}}}),
|
||||
_vram(ppu.vram),
|
||||
_cgram(ppu.cgram),
|
||||
buffer({{{0}}})
|
||||
{
|
||||
this->tileRenderer.setRam(this->_vram);
|
||||
this->tileRenderer.setCgram(this->_cgram);
|
||||
this->_tileRenderer.setRam(this->_vram);
|
||||
this->_tileRenderer.setCgram(this->_cgram);
|
||||
}
|
||||
|
||||
void Background::renderBackground()
|
||||
@@ -53,7 +54,6 @@ namespace ComSquare::PPU
|
||||
|
||||
void Background::drawBgTile(uint16_t data, Vector2<int> pos)
|
||||
{
|
||||
uint16_t graphicAddress;
|
||||
union TileMapData tileData;
|
||||
|
||||
tileData.raw = data;
|
||||
@@ -61,18 +61,19 @@ namespace ComSquare::PPU
|
||||
if (tileData.tilePriority != this->_priority)
|
||||
return;
|
||||
|
||||
uint16_t graphicAddress;
|
||||
Vector2i tileOffset = {0, 0};
|
||||
// X horizontal
|
||||
// Y vertical
|
||||
|
||||
this->tileRenderer.setPaletteIndex(tileData.palette);
|
||||
this->_tileRenderer.setPaletteIndex(tileData.palette);
|
||||
for (int i = 0; i < this->_characterNbPixels.y; i += 8) {
|
||||
for (int j = 0; j < this->_characterNbPixels.x; j += 8) {
|
||||
graphicAddress = this->_tilesetAddress +
|
||||
((tileData.posY + tileOffset.y) * NbTilePerRow * this->_bpp * TileBaseByteSize) +
|
||||
((tileData.posX + tileOffset.x) * this->_bpp * TileBaseByteSize);
|
||||
this->tileRenderer.render(graphicAddress);
|
||||
merge2DArray(this->tileBuffer, this->tileRenderer.buffer, {j, i});
|
||||
((tileData.posY + tileOffset.y) * NbTilePerRow * this->_bpp * Tile::BaseByteSize) +
|
||||
((tileData.posX + tileOffset.x) * this->_bpp * Tile::BaseByteSize);
|
||||
this->_tileRenderer.render(graphicAddress);
|
||||
merge2DArray(this->_tileBuffer, this->_tileRenderer.buffer, {j, i});
|
||||
tileOffset.x += 1;
|
||||
}
|
||||
tileOffset.x = 0;
|
||||
@@ -81,12 +82,12 @@ namespace ComSquare::PPU
|
||||
|
||||
// todo check why i need to invert vertical and horizontal flips
|
||||
if (tileData.verticalFlip)
|
||||
HFlipArray(this->tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y});
|
||||
HFlipArray(this->_tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y});
|
||||
if (tileData.horizontalFlip)
|
||||
VFlipArray(this->tileBuffer, {this->_characterNbPixels.x, this->_characterNbPixels.y});
|
||||
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++) {
|
||||
this->buffer[pos.x][pos.y] = this->tileBuffer[i][j];
|
||||
this->buffer[pos.x][pos.y] = this->_tileBuffer[i][j];
|
||||
pos.x++;
|
||||
}
|
||||
pos.x -= this->_characterNbPixels.x;
|
||||
@@ -203,7 +204,7 @@ namespace ComSquare::PPU
|
||||
this->_bpp = bpp;
|
||||
else
|
||||
this->_bpp = 2;
|
||||
this->tileRenderer.setBpp(this->_bpp);
|
||||
this->_tileRenderer.setBpp(this->_bpp);
|
||||
}
|
||||
|
||||
void Background::setTilemaps(Vector2<int> tileMaps)
|
||||
|
||||
@@ -17,16 +17,10 @@ namespace ComSquare::PPU
|
||||
class PPU;
|
||||
class Background {
|
||||
private:
|
||||
TileRenderer tileRenderer;
|
||||
std::array<std::array<uint32_t, 16>, 16> tileBuffer = {{{0}}};
|
||||
|
||||
//! @brief The number of character a TileMap has in width
|
||||
static constexpr int NbCharacterWidth = 32;
|
||||
//! @brief The number of character a TileMap has in height
|
||||
static constexpr int NbCharacterHeight = 32;
|
||||
//! @brief The number of bytes used by a range of pixels (1 pixel per byte)
|
||||
//! @note Used like: bpp * TileBaseByteSize to get the size of byte of 1 row of pixels
|
||||
static constexpr unsigned TileBaseByteSize = 8;
|
||||
//! @brief The number of rows in one line of VRAM
|
||||
//! @note If you're lost by this description, open a tile viewer in an emulator, and set the number of tiles in width to 16 graphics
|
||||
static constexpr unsigned NbTilePerRow = 16;
|
||||
@@ -55,6 +49,10 @@ namespace ComSquare::PPU
|
||||
bool _priority;
|
||||
//! @brief The bg number (used to get the corresponding scroll)
|
||||
int _bgNumber;
|
||||
//! @brief Class that actually render a tile
|
||||
TileRenderer _tileRenderer;
|
||||
//! @brief Buffer if we have tiles that are more than 8x8
|
||||
std::array<std::array<uint32_t, 16>, 16> _tileBuffer;
|
||||
//! @brief the access to vram
|
||||
std::shared_ptr<Ram::Ram> _vram;
|
||||
//! @brief The access to cgram
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
#include "Exceptions/InvalidAddress.hpp"
|
||||
#include "Ram/Ram.hpp"
|
||||
#include "Models/Vector2.hpp"
|
||||
#include "Debugger/TileViewer/TileRenderer.hpp"
|
||||
#include "Debugger/TileViewer/RAMTileRenderer.hpp"
|
||||
#include <random>
|
||||
|
||||
namespace ComSquare::PPU
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
#include "Models/Vector2.hpp"
|
||||
#include "Background.hpp"
|
||||
#include "PPUUtils.hpp"
|
||||
#include "Debugger/TileViewer/TileRenderer.hpp"
|
||||
#include "Debugger/TileViewer/RAMTileRenderer.hpp"
|
||||
|
||||
#define FALLTHROUGH __attribute__((fallthrough));
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace ComSquare::PPU
|
||||
static constexpr int NbPixelsWidth = 8;
|
||||
//! @brief The number of pixel a base tile can have in height
|
||||
static constexpr int NbPixelsHeight = 8;
|
||||
//! @brief A base tile size in byte is 0x8
|
||||
//! @note Used like: bpp * BaseByteSize to get the byte size of 1 tile
|
||||
static constexpr int BaseByteSize = 0x8;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <array>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include "QtWidgetSFML.hpp"
|
||||
#include "Debugger/TileViewer/TileRenderer.hpp"
|
||||
#include "Debugger/TileViewer/RAMTileRenderer.hpp"
|
||||
|
||||
namespace ComSquare::Renderer
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user