diff --git a/Makefile b/Makefile index f0e3ce0..2225045 100644 --- a/Makefile +++ b/Makefile @@ -15,13 +15,13 @@ debug_build: meson compile -j 4 -C builddir run: build - ./builddir/b8rk.exe 1 120 ./roms/tetris.ch8 + ./builddir/b8rk.exe 1 120 ./roms/pong.ch8 debug: build gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe debug_run: build - gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/b8rk.exe 1 120 ./roms/tetris.ch8 + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/b8rk.exe 1 120 ./roms/pong.ch8 clean: meson compile --clean -C builddir diff --git a/src/chip8.cpp b/src/chip8.cpp index d8e41ba..8671051 100644 --- a/src/chip8.cpp +++ b/src/chip8.cpp @@ -294,7 +294,10 @@ void Chip8::OP_Dxyn() { for(size_t col = 0; col < 8; ++col) { uint8_t spritePixel = spriteByte & (0x80u >> col); - uint32_t* screenPixel = &video[(yPos + row) * VIDEO_WIDTH + (xPos + col)]; + + size_t pixel_at = (yPos + row) * VIDEO_WIDTH + (xPos + col); + + uint32_t* screenPixel = &video[pixel_at]; // Sprite pixel is on if(spritePixel) { diff --git a/src/chip8.hpp b/src/chip8.hpp index d5ad3ec..def9cf2 100644 --- a/src/chip8.hpp +++ b/src/chip8.hpp @@ -24,7 +24,7 @@ class Chip8 { uint8_t delayTimer{}; uint8_t soundTimer{}; uint8_t keypad[16]{}; - uint32_t video[64 * 32]{}; + uint32_t video[VIDEO_WIDTH * VIDEO_HEIGHT]{}; uint16_t opcode; uint8_t fontset[FONTSET_SIZE] = { diff --git a/src/display.cpp b/src/display.cpp new file mode 100644 index 0000000..054ae50 --- /dev/null +++ b/src/display.cpp @@ -0,0 +1,55 @@ +#include "display.hpp" +#include +#include +#include + +Display::Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size) : + window(window) +{ + float border_width = 2.0f; + texture.setSmooth(false); + + float ratio = (size.x - border_width * 2) / 64.0f; + // rectangle position doesn't include the border because everyone hates humans + sf::Vector2f border_pos{pos.x + border_width, pos.y + border_width}; + + sf::Vector2f scale{ratio, ratio}; + // have to move in one more time for the border we just moved in for the border + texture_sprite.setPosition({border_pos.x + border_width, border_pos.y + border_width}); + texture_sprite.setScale(scale); + + border.setPosition(border_pos); + border.setSize({64 * ratio, 32 * ratio}); + border.setOutlineColor({30,20,50,255}); + border.setOutlineThickness(border_width); + border.setFillColor({0,0,0,255}); +} + +void Display::handle_inputs(Chip8& vm) { + while (const auto event = window.pollEvent()) { + if(event->is()) { + window.close(); + } + + if(const auto* key = event->getIf()) { + vm.handle_keyboard(key->scancode, true); + } else if(const auto* key = event->getIf()) { + vm.handle_keyboard(key->scancode, false); + } + } +} + +void Display::update(Chip8& vm) { + handle_inputs(vm); + texture.update((uint8_t *)(vm.video), {64, 32}, {0,0}); +} + +void Display::render() { + window.draw(border); + window.draw(texture_sprite); + window.display(); +} + +bool Display::active() { + return window.isOpen(); +} diff --git a/src/display.hpp b/src/display.hpp new file mode 100644 index 0000000..4eed9ee --- /dev/null +++ b/src/display.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include +#include +#include "chip8.hpp" + +struct Display { + sf::RenderWindow& window; + sf::Texture texture{sf::Vector2u{64,32}}; + sf::Sprite texture_sprite{texture}; + sf::RectangleShape border; + + Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size); + + void handle_inputs(Chip8& vm); + void update(Chip8& vm); + void render(); + bool active(); +}; diff --git a/src/main.cpp b/src/main.cpp index 8082bd8..fe0d9b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,74 +1,11 @@ #define _USE_MATH_DEFINES #include #include -#include -#include #include -#include -#include -#include -#include #include "dbc.hpp" #include "chip8.hpp" #include "stats.hpp" - -struct Display { - sf::RenderWindow& window; - sf::Texture texture{sf::Vector2u{64,32}}; - sf::Sprite texture_sprite{texture}; - sf::RectangleShape border; - - Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size) : - window(window) - { - float border_width = 2.0f; - texture.setSmooth(false); - - float ratio = (size.x - border_width * 2) / 64.0f; - // rectangle position doesn't include the border because everyone hates humans - sf::Vector2f border_pos{pos.x + border_width, pos.y + border_width}; - - sf::Vector2f scale{ratio, ratio}; - // have to move in one more time for the border we just moved in for the border - texture_sprite.setPosition({border_pos.x + border_width, border_pos.y + border_width}); - texture_sprite.setScale(scale); - - border.setPosition(border_pos); - border.setSize({64 * ratio, 32 * ratio}); - border.setOutlineColor({30,20,50,255}); - border.setOutlineThickness(border_width); - border.setFillColor({0,0,0,255}); - } - - void handle_inputs(Chip8& vm) { - while (const auto event = window.pollEvent()) { - if(event->is()) { - window.close(); - } - - if(const auto* key = event->getIf()) { - vm.handle_keyboard(key->scancode, true); - } else if(const auto* key = event->getIf()) { - vm.handle_keyboard(key->scancode, false); - } - } - } - - void update(Chip8& vm) { - handle_inputs(vm); - texture.update((uint8_t *)(vm.video), {64, 32}, {0,0}); - } - - void render() { - window.draw(border); - window.draw(texture_sprite); - window.display(); - } - - bool active() { - return window.isOpen(); - } -}; +#include "display.hpp" int main(int argc, char* argv[]) { if(argc != 4) { diff --git a/src/meson.build b/src/meson.build index acdd7f0..6d3db8c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,4 +3,5 @@ sources = files( 'dbc.cpp', 'chip8.cpp', 'stats.cpp', + 'display.cpp', )