Move the graphics stuff out of main.

master
Zed A. Shaw 2 months ago
parent 5dc45a75a6
commit 5efa8be1c4
  1. 4
      Makefile
  2. 5
      src/chip8.cpp
  3. 2
      src/chip8.hpp
  4. 55
      src/display.cpp
  5. 20
      src/display.hpp
  6. 65
      src/main.cpp
  7. 1
      src/meson.build

@ -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

@ -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) {

@ -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] =
{

@ -0,0 +1,55 @@
#include "display.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/System.hpp>
#include <SFML/Audio.hpp>
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<sf::Event::Closed>()) {
window.close();
}
if(const auto* key = event->getIf<sf::Event::KeyPressed>()) {
vm.handle_keyboard(key->scancode, true);
} else if(const auto* key = event->getIf<sf::Event::KeyReleased>()) {
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();
}

@ -0,0 +1,20 @@
#pragma once
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#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();
};

@ -1,74 +1,11 @@
#define _USE_MATH_DEFINES
#include <math.h>
#include <fmt/core.h>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#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<sf::Event::Closed>()) {
window.close();
}
if(const auto* key = event->getIf<sf::Event::KeyPressed>()) {
vm.handle_keyboard(key->scancode, true);
} else if(const auto* key = event->getIf<sf::Event::KeyReleased>()) {
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) {

@ -3,4 +3,5 @@ sources = files(
'dbc.cpp',
'chip8.cpp',
'stats.cpp',
'display.cpp',
)

Loading…
Cancel
Save