Merge branch 'catch' of github.com:AnonymusRaccoon/ComSquare into PPU

# Conflicts:
#	CMakeLists.txt
#	sources/PPU/Background.cpp
#	sources/PPU/Background.hpp
#	sources/PPU/PPU.hpp
This commit is contained in:
Clément Le Bihan
2021-07-08 01:07:19 +02:00
119 changed files with 7356 additions and 7324 deletions
+19 -24
View File
@@ -5,32 +5,28 @@
#include "PPUUtils.hpp"
#include "PPU.hpp"
#include "Background.hpp"
#include <cmath>
#include "Tile.hpp"
#include "PPUUtils.hpp"
#include "Models/Vector2.hpp"
namespace ComSquare::PPU
{
Background::Background(ComSquare::PPU::PPU &ppu, int backGroundNumber, bool hasPriority):
_ppu(ppu),
_tileMapMirroring(ppu.getBackgroundMirroring(backGroundNumber)),
_characterNbPixels(ppu.getCharacterSize(backGroundNumber)),
_bpp(ppu.getBPP(backGroundNumber)),
_directColor(false),
_highRes(false),
_tileMapStartAddress(ppu.getTileMapStartAddress(backGroundNumber)),
_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);
}
Background::Background(ComSquare::PPU::PPU &ppu, int backGroundNumber, bool hasPriority)
: _ppu(ppu),
_tileMapMirroring(ppu.getBackgroundMirroring(backGroundNumber)),
_characterNbPixels(ppu.getCharacterSize(backGroundNumber)),
_bpp(ppu.getBPP(backGroundNumber)),
_directColor(false),
_highRes(false),
_tileMapStartAddress(ppu.getTileMapStartAddress(backGroundNumber)),
_tilesetAddress(ppu.getTilesetAddress(backGroundNumber)),
_priority(hasPriority),
_bgNumber(backGroundNumber),
_tileBuffer({{{0}}}),
_vram(ppu.vram),
_cgram(ppu.cgram),
_tileRenderer(this->_vram, this->_cgram),
buffer({{{0}}})
{}
void Background::renderBackground()
{
@@ -105,14 +101,13 @@ namespace ComSquare::PPU
void Background::_drawBasicTileMap(uint16_t baseAddress, Vector2<int> offset)
{
uint16_t tileMapValue = 0;
Vector2<int> pos(0, 0);
uint16_t vramAddress = baseAddress;
while (vramAddress < baseAddress + TileMapByteSize) {
// TODO function to read 2 bytes (LSB order or bits reversed)
tileMapValue = this->_vram->read(vramAddress);
tileMapValue += this->_vram->read(vramAddress + 1) << 8U;
uint16_t tileMapValue = this->_vram.read(vramAddress);
tileMapValue += this->_vram.read(vramAddress + 1) << 8U;
this->_drawTile(tileMapValue, {(offset.x * NbCharacterWidth) + pos.x,
(offset.y * NbCharacterHeight) + pos.y});
vramAddress += 2;
+11 -11
View File
@@ -4,20 +4,21 @@
#pragma once
#include <stdint-gcc.h>
#include <array>
#include <vector>
#include <iostream>
#include "../Models/Vector2.hpp"
#include "Models/Vector2.hpp"
#include "TileRenderer.hpp"
#include "../Ram/Ram.hpp"
#include "Ram/Ram.hpp"
#include "PPU.hpp"
#include "PPUUtils.hpp"
namespace ComSquare::PPU
{
class PPU;
class Background {
class Background
{
private:
//! @brief The number of character a TileMap has in width
static constexpr int NbCharacterWidth = 32;
@@ -29,9 +30,8 @@ namespace ComSquare::PPU
//! @brief The size of a TileMap in memory
static constexpr unsigned short TileMapByteSize = 0x800;
//! @brief the ppu used to get registers values (ex: bg scroll)
ComSquare::PPU::PPU &_ppu;
PPU &_ppu;
//! @brief The tilemap configuration nb of tileMap vertically and horizontally
//! @note members are set to true if the tilemap is expended in their direction
Vector2<bool> _tileMapMirroring;
@@ -52,14 +52,14 @@ 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;
Ram::Ram &_vram;
//! @brief The access to cgram
std::shared_ptr<Ram::Ram> _cgram;
Ram::Ram &_cgram;
//! @brief Class that actually render a tile
TileRenderer _tileRenderer;
//! @brief Draw a tile on the screen at x y pos
//! @param data The VRAM value to be interpreted as a Utils::TileData
//! @param indexOffset The index offset of the Tile (ranging from 0 to 63)
@@ -142,7 +142,7 @@ namespace ComSquare::PPU
}
//! @brief ctor
Background(ComSquare::PPU::PPU &_ppu, int backGroundNumber, bool hasPriority);
Background(PPU &_ppu, int backGroundNumber, bool hasPriority);
//! @brief Default copy ctor
Background(const Background &) = default;
//! @brief Default destructor
+15 -22
View File
@@ -5,9 +5,7 @@
#include <iostream>
#include <bitset>
#include "PPU.hpp"
#include "Exceptions/NotImplementedException.hpp"
#include "Exceptions/InvalidAddress.hpp"
#include "Ram/Ram.hpp"
#include "Models/Vector2.hpp"
namespace ComSquare::PPU::Utils::Debug {
@@ -17,9 +15,9 @@ namespace ComSquare::PPU::Utils::Debug {
namespace ComSquare::PPU
{
PPU::PPU(Renderer::IRenderer &renderer):
vram(new Ram::Ram(VramSize, ComSquare::VRam, "VRAM")),
oamram(new Ram::Ram(OAMRamSize, ComSquare::OAMRam, "OAMRAM")),
cgram(new Ram::Ram(CGRamSize, ComSquare::CGRam, "CGRAM")),
vram(VramSize, ComSquare::VRam, "VRAM"),
oamram(OAMRamSize, ComSquare::OAMRam, "OAMRAM"),
cgram(CGRamSize, ComSquare::CGRam, "CGRAM"),
_renderer(renderer),
_backgrounds{
Background(*this, 1, false),
@@ -32,7 +30,7 @@ namespace ComSquare::PPU
{
this->_registers._isLowByte = true;
//Utils::Debug::populateEnvironment(*this, 0);
Utils::Debug::populateEnvironment(*this, 1);
}
uint8_t PPU::read(uint24_t addr)
@@ -68,7 +66,7 @@ namespace ComSquare::PPU
return returnValue;
}
case PpuRegisters::cgdataread: {
return this->cgram->read(this->_registers._cgadd++);
return this->cgram.read(this->_registers._cgadd++);
}
case PpuRegisters::ophct:
case PpuRegisters::opvct:
@@ -101,7 +99,7 @@ namespace ComSquare::PPU
//throw InvalidAddress("oamdata", addr);
//std::cout << "oamdata" << std::endl;
// the oamAddress have to be calculated if fblank or not (not implemented)
oamram->write(this->_registers._oamadd.oamAddress, this->_registers._oamdata);
oamram.write(this->_registers._oamadd.oamAddress, this->_registers._oamdata);
this->_registers._oamadd.oamAddress++;
break;
case PpuRegisters::bgmode:
@@ -180,7 +178,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatal" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatal = data;
this->vram->write(this->getVramAddress(), data);
this->vram.write(this->getVramAddress(), data);
}
if (!this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -189,7 +187,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatah" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatah = data;
this->vram->write(this->getVramAddress() + 1, data);
this->vram.write(this->getVramAddress() + 1, data);
}
if (this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -217,9 +215,9 @@ namespace ComSquare::PPU
}
else {
this->_registers._cgdata.cgdatah = data;
this->cgram->write(this->_registers._cgadd, this->_registers._cgdata.cgdatal);
this->cgram.write(this->_registers._cgadd, this->_registers._cgdata.cgdatal);
this->_registers._cgadd++;
this->cgram->write(this->_registers._cgadd, this->_registers._cgdata.cgdatah);
this->cgram.write(this->_registers._cgadd, this->_registers._cgdata.cgdatah);
this->_registers._cgadd++;
}
this->_registers._isLowByte = !this->_registers._isLowByte;
@@ -479,14 +477,9 @@ namespace ComSquare::PPU
return Ppu;
}
bool PPU::isDebugger() const
{
return false;
}
uint16_t PPU::cgramRead(uint16_t addr)
{
return this->cgram->read(addr);
return this->cgram.read(addr);
}
int PPU::getBPP(int bgNumber) const
@@ -563,8 +556,8 @@ namespace ComSquare::PPU
_background.renderBackground();
}
// TODO make a function getDefaultBgColor
colorPalette = this->cgram->read(0);
colorPalette += this->cgram->read(1) << 8U;
colorPalette = this->cgram.read(0);
colorPalette += this->cgram.read(1) << 8U;
uint32_t color = Utils::getRealColor(colorPalette);
for (auto &row : this->_subScreen)
@@ -678,8 +671,8 @@ namespace ComSquare::PPU
void PPU::updateVramReadBuffer()
{
this->_vramReadBuffer = this->vram->read(this->getVramAddress());
this->_vramReadBuffer += this->vram->read(this->getVramAddress() + 1) << 8;
this->_vramReadBuffer = this->vram.read(this->getVramAddress());
this->_vramReadBuffer += this->vram.read(this->getVramAddress() + 1) << 8;
}
Vector2<int> PPU::getBgScroll(int bgNumber) const
+24 -24
View File
@@ -2,8 +2,7 @@
// Created by cbihan on 1/27/20.
//
#ifndef COMSQUARE_PPU_HPP
#define COMSQUARE_PPU_HPP
#pragma once
#include <cstdint>
#include "Memory/AMemory.hpp"
@@ -14,13 +13,17 @@
#include <algorithm>
#include "Background.hpp"
#include "PPUUtils.hpp"
#ifdef DEBUGGER_ENABLED
#include "Debugger/TileViewer/RAMTileRenderer.hpp"
#endif
#define FALLTHROUGH __attribute__((fallthrough));
namespace ComSquare::PPU::Utils {
namespace ComSquare::PPU::Utils
{
struct PpuState;
};
}
namespace ComSquare::PPU
{
@@ -552,10 +555,10 @@ namespace ComSquare::PPU
class PPU : public Memory::AMemory {
public:
//! @brief Rams
std::shared_ptr<Ram::Ram> vram;
std::shared_ptr<Ram::Ram> oamram;
std::shared_ptr<Ram::Ram> cgram;
//private:
Ram::Ram vram;
Ram::Ram oamram;
Ram::Ram cgram;
private:
//! @brief Init ppuRegisters
Registers _registers{};
Renderer::IRenderer &_renderer;
@@ -592,46 +595,43 @@ namespace ComSquare::PPU
//! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
void write(uint24_t addr, uint8_t data) override;
//! @brief Get the name of this accessor (used for debug purpose)
std::string getName() const override;
[[nodiscard]] std::string getName() const override;
//! @brief Get the component of this accessor (used for debug purpose)
Component getComponent() const override;
[[nodiscard]] Component getComponent() const override;
//! @brief Get the size of the data. This size can be lower than the mapped data.
//! @return The number of bytes inside this memory.
uint24_t getSize() const override;
[[nodiscard]] uint24_t getSize() const override;
//! @brief Update the PPU of n cycles.
//! @param The number of cycles to update.
virtual void update(unsigned cycles);
//! @brief Give the Vram Address with the right Address remapping
uint16_t getVramAddress() const;
[[nodiscard]] uint16_t getVramAddress() const;
//! @brief Give the name of the Address register (used for debug)
std::string getValueName(uint24_t addr) const;
//! @brief Return true if the CPU is overloaded with debugging features.
virtual bool isDebugger() const;
[[nodiscard]] std::string getValueName(uint24_t addr) const override;
//! @brief Allow others components to read the CGRAM
uint16_t cgramRead(uint16_t addr);
//! @brief get the bpp depending of the bgNumber and the Bgmode
int getBPP(int bgNumber) const;
[[nodiscard]] int getBPP(int bgNumber) const;
//! @brief Give the correct character size depending of the bgMode
Vector2<int> getCharacterSize(int bgNumber) const;
[[nodiscard]] Vector2<int> getCharacterSize(int bgNumber) const;
//! @brief Give the address where the tilemap starts
uint16_t getTileMapStartAddress(int bgNumber) const;
[[nodiscard]] uint16_t getTileMapStartAddress(int bgNumber) const;
//! @brief Give the address to find the correct tileset for a given x and y
uint16_t getTilesetAddress(int bgNumber) const;
[[nodiscard]] uint16_t getTilesetAddress(int bgNumber) const;
//! @brief Tells if the tilemap is expanded for the x and y directions
Vector2<bool> getBackgroundMirroring(int bgNumber) const;
[[nodiscard]] Vector2<bool> getBackgroundMirroring(int bgNumber) const;
//! @brief Render the Main and sub screen correctly
void renderMainAndSubScreen();
//! @brief Add a bg to the sub and/or main screen
void addToMainSubScreen(Background &bg, const Vector2<int> &level);
//! @brief Get the current background Mode
int getBgMode() const;
[[nodiscard]] int getBgMode() const;
//! @brief update the Vram buffer
void updateVramReadBuffer();
//! @brief update the Vram buffer
Vector2<int> getBgScroll(int bgNumber) const;
[[nodiscard]] Vector2<int> getBgScroll(int bgNumber) const;
//! @brief Allow to look the value of each write register (used by Register debugger)
const Registers &getWriteRegisters() const;
[[nodiscard]] const Registers &getWriteRegisters() const;
};
}
#endif //COMSQUARE_PPU_HPP
+1 -3
View File
@@ -2,8 +2,7 @@
// Created by cbihan on 1/27/20.
//
#ifndef COMSQUARE_PPU_UTILS_HPP
#define COMSQUARE_PPU_UTILS_HPP
#pragma once
#include <stdint-gcc.h>
#include <cstddef>
@@ -95,4 +94,3 @@ namespace ComSquare::PPU::Utils
});
}
}
#endif //COMSQUARE_PPU_UTILS_HPP
+31 -30
View File
@@ -7,19 +7,19 @@
namespace ComSquare::PPU::Utils::Debug
{
void populateCgramTicTacToe(const std::shared_ptr<Ram::Ram> &cgram)
void populateCgramTicTacToe(Ram::Ram &cgram)
{
//colors for the cgram
cgram->write(2, 0xE0);
cgram->write(3, 0x7F);
cgram->write(4, 0x1F); // 0x1F
cgram->write(6, 0xFF);
cgram->write(7, 0x03);
cgram->write(66, 0xE0);
cgram->write(67, 0x7F);
cgram.write(2, 0xE0);
cgram.write(3, 0x7F);
cgram.write(4, 0x1F); // 0x1F
cgram.write(6, 0xFF);
cgram.write(7, 0x03);
cgram.write(66, 0xE0);
cgram.write(67, 0x7F);
}
void populateVramTicTacToe(const std::shared_ptr<Ram::Ram> &vram)
void populateVramTicTacToe(Ram::Ram &vram)
{
int vram_test[] = {
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -54,37 +54,37 @@ namespace ComSquare::PPU::Utils::Debug
00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x0f,00,0x1f,00,0x3f,00, -1
};
for (int i = 0; vram_test[i] != -1; i++) {
vram->write(i, vram_test[i]);
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};
for (int i = 0; vram_test_2[i] != -1; i++) {
vram->write(i + 0x8000, vram_test_2[i]);
vram.write(i + 0x8000, vram_test_2[i]);
}
int vram_test_3[] = {8, 00, 02, 00, 0x8, 00, 02, 00, 0x8, 00, 00, 00, 00, 00, 00, -1};
for (int i = 0; vram_test_3[i] != -1; i++) {
vram->write(i + 0x8080, vram_test_3[i]);
vram.write(i + 0x8080, vram_test_3[i]);
}
int vram_test_4[] = {8, 00, 02, 00, 0x0A, 00, 02, 00, 0x0A, 00, 00, 00, 00, 00, 00, -1};
for (int i = 0; vram_test_4[i] != -1; i++) {
vram->write(i + 0x8100, vram_test_4[i]);
vram.write(i + 0x8100, vram_test_4[i]);
}
vram->write(0x8040, 04);
vram->write(0x8042, 06);
vram->write(0x8044, 04);
vram->write(0x8046, 06);
vram->write(0x8048, 04);
vram.write(0x8040, 04);
vram.write(0x8042, 06);
vram.write(0x8044, 04);
vram.write(0x8046, 06);
vram.write(0x8048, 04);
vram->write(0x80C0, 04);
vram->write(0x80C2, 06);
vram->write(0x80C4, 04);
vram->write(0x80C6, 06);
vram->write(0x80C8, 04);
vram.write(0x80C0, 04);
vram.write(0x80C2, 06);
vram.write(0x80C4, 04);
vram.write(0x80C6, 06);
vram.write(0x80C8, 04);
vram->write(0xC000, 0x0C);
vram.write(0xC000, 0x0C);
}
void populateCgramAladin(const std::shared_ptr<Ram::Ram> &cgram)
void populateCgramAladin(Ram::Ram &cgram)
{
int cgram_dump[] = {
0xCE, 0x69, 0xDF, 0x63, 0xDE, 0x16, 0x8B, 0x00, 0x00, 0x00, 0xBF, 0x67, 0x98, 0x42, 0x0E, 0x15, 0x00, 0x00,
@@ -118,11 +118,11 @@ namespace ComSquare::PPU::Utils::Debug
0xC9, 0x0C, 0xD2, 0x25, 0xA5, 0x14, 0x00, 0x00, -1
};
for (int i = 0; cgram_dump[i] != -1; i++) {
cgram->write(i, cgram_dump[i]);
cgram.write(i, cgram_dump[i]);
}
}
void populateVramAladin(const std::shared_ptr<Ram::Ram> &vram)
void populateVramAladin(Ram::Ram &vram)
{
static int vram_dump[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -3768,7 +3768,7 @@ namespace ComSquare::PPU::Utils::Debug
0x24, 0x7D, 0x1A, 0x79, 0x16, 0x31, 0x18, 0x39, 0x17, 0x17, 0x0D, 0x0D, 0x07, 0x07, 0x01, 0x01, -1
};
for (int i = 0; vram_dump[i] != -1; i++) {
vram->write(i, vram_dump[i]);
vram.write(i, vram_dump[i]);
}
}
@@ -3858,7 +3858,8 @@ namespace ComSquare::PPU::Utils::Debug
ppu._registers._t[0].enableWindowDisplayBg2 = true;
}
void populateVram(std::shared_ptr<Ram::Ram> vram, int dumpNumber) {
void populateVram(Ram::Ram &vram, int dumpNumber)
{
switch (dumpNumber)
{
case 0: return populateVramTicTacToe(vram);
@@ -3868,7 +3869,7 @@ namespace ComSquare::PPU::Utils::Debug
}
}
void populateCgram(std::shared_ptr<Ram::Ram> cgram, int dumpNumber)
void populateCgram(Ram::Ram &cgram, int dumpNumber)
{
switch (dumpNumber)
{
+2
View File
@@ -5,6 +5,8 @@
#pragma once
#include "Ram/Ram.hpp"
#define private public
#include "PPU.hpp"
+8 -18
View File
@@ -11,20 +11,15 @@
namespace ComSquare::PPU
{
TileRenderer::TileRenderer()
: _ram(nullptr),
_cgram(nullptr),
TileRenderer::TileRenderer(Ram::Ram &vram, Ram::Ram &cgram)
: _ram(vram),
_cgram(cgram),
_bpp(2),
_paletteIndex(0),
buffer({{{0}}})
{
}
void TileRenderer::setRam(std::shared_ptr<Ram::Ram> ram)
{
this->_ram = std::move(ram);
}
void TileRenderer::render(uint16_t tileAddress)
{
std::vector<uint16_t> palette = this->getPalette(this->_paletteIndex);
@@ -71,9 +66,9 @@ namespace ComSquare::PPU
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);
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;
@@ -108,18 +103,13 @@ namespace ComSquare::PPU
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;
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);
}
int TileRenderer::getBpp() const
{
return this->_bpp;
+8 -8
View File
@@ -15,9 +15,9 @@ namespace ComSquare::PPU
static constexpr int TileByteSizeRow = 16;
//! @brief ram to render
std::shared_ptr<Ram::Ram> _ram;
Ram::Ram &_ram;
//! @brief cgram to access the colors
std::shared_ptr<Ram::Ram> _cgram;
Ram::Ram &_cgram;
//! @brief The bpp to use while rendering
int _bpp;
//! @brief The palette number to use while rendering
@@ -28,12 +28,8 @@ namespace ComSquare::PPU
std::array<std::array<uint32_t, 8>, 8> buffer;
//! @brief Set the palette to use for render (index of palette)
void setPaletteIndex(int paletteIndex);
//! @brief Set the ram to look for color references
void setCgram(std::shared_ptr<Ram::Ram> ram);
//! @brief Set the bpp to render graphics
void setBpp(int bpp);
//! @brief The ram to render
void setRam(std::shared_ptr<Ram::Ram> ram);
//! @brief Get the current bpp
int getBpp() const;
//! @brief Get the index of the current palette used
@@ -58,9 +54,13 @@ namespace ComSquare::PPU
//! @brief render the tile (8x8) at the tileAddress
//! @param tileAddress The address of the tile to render
void render(uint16_t tileAddress);
TileRenderer();
TileRenderer(Ram::Ram &vram, Ram::Ram &cgram);
//! @brief A tile renderer is copy constructable.
TileRenderer(const TileRenderer &) = default;
//! @brief A default destructor
~TileRenderer() = default;
TileRenderer &operator=(const TileRenderer &) = default;
//! @brief A tile render is not assignable.
TileRenderer &operator=(const TileRenderer &) = delete;
};
}