srctree

Johan parent 47503e97 b8fcd72d cfd1d059
Merge pull request #355 from johnor/pixel

Return an optional pixel from Ppu::execute()
core/CMakeLists.txt added: 55, removed: 26, total 29
@@ -15,6 +15,7 @@ add_library(${PROJECT_NAME}
include/nes/core/mmu_factory.h
include/nes/core/nes_controller_factory.h
include/nes/core/opcode.h
include/nes/core/pixel.h
include/nes/core/ppu_factory.h
include/nes/core/ppu_registers.h
include/nes/core/rom_factory.h
 
core/include/nes/core/ippu.h added: 55, removed: 26, total 29
@@ -2,7 +2,9 @@
 
#include <cstdint>
#include <functional>
#include <optional>
 
#include "nes/core/pixel.h"
#include "ppu_registers.h"
 
namespace n_e_s::core {
@@ -14,7 +16,7 @@ public:
virtual uint8_t read_byte(uint16_t addr) = 0;
virtual void write_byte(uint16_t addr, uint8_t byte) = 0;
 
virtual void execute() = 0;
virtual std::optional<Pixel> execute() = 0;
 
virtual void set_nmi_handler(const std::function<void()> &nmi_handler) = 0;
 
 
filename was Deleted added: 55, removed: 26, total 29
@@ -0,0 +1,13 @@
#pragma once
 
#include <cstdint>
 
namespace n_e_s::core {
 
struct Pixel {
uint8_t x;
uint8_t y;
uint32_t color;
};
 
} // namespace n_e_s::core
 
core/src/ppu.cpp added: 55, removed: 26, total 29
@@ -125,7 +125,7 @@ void Ppu::write_byte(uint16_t addr, uint8_t byte) {
}
} // namespace n_e_s::core
 
void Ppu::execute() {
std::optional<Pixel> Ppu::execute() {
if (is_pre_render_scanline()) {
execute_pre_render_scanline();
} else if (is_visible_scanline()) {
@@ -137,6 +137,7 @@ void Ppu::execute() {
}
 
update_counters();
return {};
}
 
void Ppu::set_nmi_handler(const std::function<void()> &on_nmi) {
 
core/src/ppu.h added: 55, removed: 26, total 29
@@ -14,7 +14,7 @@ public:
uint8_t read_byte(uint16_t addr) override;
void write_byte(uint16_t addr, uint8_t byte) override;
 
void execute() override;
std::optional<Pixel> execute() override;
 
void set_nmi_handler(const std::function<void()> &on_nmi) override;
 
 
core/test/src/test_ppu.cpp added: 55, removed: 26, total 29
@@ -25,7 +25,7 @@ public:
 
void step_execution(uint32_t cycles) {
for (uint32_t i = 0; i < cycles; ++i) {
ppu->execute();
EXPECT_FALSE(ppu->execute().has_value());
}
}
 
@@ -456,7 +456,8 @@ TEST_F(PpuTest, visible_two_sub_cycles) {
}
 
for (int i = 0; i < 17; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
 
EXPECT_EQ(expected, registers);
@@ -497,7 +498,8 @@ TEST_F(PpuTest, visible_scanline) {
}
 
for (int i = 0; i <= 256; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -505,14 +507,15 @@ TEST_F(PpuTest, visible_scanline) {
expected.vram_addr = PpuVram(0b001'00'00000'00000);
expected.cycle = 258;
 
ppu->execute(); // Cycle 257
EXPECT_FALSE(ppu->execute().has_value()); // Cycle 257
EXPECT_EQ(expected, registers);
 
// Cycle 258-320
// During cycle 280-304 the ppu is idle
expected.cycle = 321;
for (int i = 258; i <= 320; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -534,7 +537,8 @@ TEST_F(PpuTest, visible_scanline) {
EXPECT_CALL(mmu, read_byte(0x03 * 16u + 8u + 1u)).WillOnce(Return(0x99));
 
for (int i = 321; i <= 336; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -544,7 +548,8 @@ TEST_F(PpuTest, visible_scanline) {
expected.cycle = 0;
EXPECT_CALL(mmu, read_byte(0x2000 + 2)).Times(2).WillRepeatedly(Return(2));
for (int i = 337; i <= 340; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
}
@@ -593,7 +598,8 @@ TEST_F(PpuTest, pre_render_two_sub_cycles) {
}
 
for (int i = 0; i < 17; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
 
EXPECT_EQ(expected, registers);
@@ -634,7 +640,8 @@ TEST_F(PpuTest, pre_render_scanline) {
}
 
for (int i = 0; i <= 256; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -642,7 +649,7 @@ TEST_F(PpuTest, pre_render_scanline) {
expected.vram_addr = PpuVram(0b001'00'00000'00000);
expected.cycle = 258;
 
ppu->execute(); // Cycle 257
EXPECT_FALSE(ppu->execute().has_value()); // Cycle 257
EXPECT_EQ(expected, registers);
 
// Cycle 258-320
@@ -650,7 +657,8 @@ TEST_F(PpuTest, pre_render_scanline) {
expected.vram_addr = PpuVram(0b000'00'00000'00000);
expected.cycle = 321;
for (int i = 258; i <= 320; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -672,7 +680,8 @@ TEST_F(PpuTest, pre_render_scanline) {
EXPECT_CALL(mmu, read_byte(0x03 * 16u + 8u)).WillOnce(Return(0x99));
 
for (int i = 321; i <= 336; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
 
@@ -682,7 +691,8 @@ TEST_F(PpuTest, pre_render_scanline) {
expected.cycle = 0;
EXPECT_CALL(mmu, read_byte(0x2000 + 2)).Times(2).WillRepeatedly(Return(2));
for (int i = 337; i <= 340; ++i) {
ppu->execute();
const auto pixel = ppu->execute();
EXPECT_FALSE(pixel.has_value());
}
EXPECT_EQ(expected, registers);
}
 
core/test_utils/include/nes/core/test/fake_ppu.h added: 55, removed: 26, total 29
@@ -9,7 +9,9 @@ class FakePpu : public IPpu {
return 0;
}
void write_byte(uint16_t, uint8_t) override {}
void execute() override {}
std::optional<Pixel> execute() override {
return {};
}
void set_nmi_handler(const std::function<void()> &) override {}
 
uint16_t scanline() const override {
 
core/test_utils/include/nes/core/test/mock_ppu.h added: 55, removed: 26, total 29
@@ -11,7 +11,7 @@ public:
MOCK_METHOD(uint8_t, read_byte, (uint16_t addr), (override));
MOCK_METHOD(void, write_byte, (uint16_t addr, uint8_t byte), (override));
 
MOCK_METHOD(void, execute, (), (override));
MOCK_METHOD(std::optional<Pixel>, execute, (), (override));
 
MOCK_METHOD(void,
set_nmi_handler,