Start a control panel for buttons and disassembler output.

master
Zed A. Shaw 1 month ago
parent fc8729930a
commit 4532da48c3
  1. 6
      src/chip8.cpp
  2. 17
      src/chip8.hpp
  3. 1
      src/code_panel.cpp
  4. 1
      src/code_panel.hpp
  5. 16
      src/constants.hpp
  6. 26
      src/control_panel.cpp
  7. 15
      src/control_panel.hpp
  8. 9
      src/display.cpp
  9. 7
      src/display.hpp
  10. 4
      src/main.cpp
  11. 2
      src/meson.build
  12. 19
      src/status_panel.cpp

@ -284,8 +284,8 @@ void Chip8::OP_Dxyn() {
uint8_t height = opcode & 0x00Fu; uint8_t height = opcode & 0x00Fu;
// wrap if going beyond the screen boundaries // wrap if going beyond the screen boundaries
uint8_t xPos = registers[Vx] % VIDEO_WIDTH; uint8_t xPos = registers[Vx] % CHIP8_WIDTH;
uint8_t yPos = registers[Vy] % VIDEO_HEIGHT; uint8_t yPos = registers[Vy] % CHIP8_HEIGHT;
registers[0xF] = 0; registers[0xF] = 0;
@ -295,7 +295,7 @@ void Chip8::OP_Dxyn() {
for(size_t col = 0; col < 8; ++col) { for(size_t col = 0; col < 8; ++col) {
uint8_t spritePixel = spriteByte & (0x80u >> col); uint8_t spritePixel = spriteByte & (0x80u >> col);
size_t pixel_at = (yPos + row) * VIDEO_WIDTH + (xPos + col); size_t pixel_at = (yPos + row) * CHIP8_WIDTH + (xPos + col);
uint32_t* screenPixel = &video[pixel_at]; uint32_t* screenPixel = &video[pixel_at];

@ -6,25 +6,20 @@
#include <chrono> #include <chrono>
#include <random> #include <random>
#include <SFML/Window/Keyboard.hpp> #include <SFML/Window/Keyboard.hpp>
#include "constants.hpp"
const unsigned int START_ADDRESS = 0x200;
const unsigned int FONTSET_SIZE = 80;
const unsigned int FONTSET_START_ADDRESS = 0x50;
const unsigned int VIDEO_WIDTH = 64;
const unsigned int VIDEO_HEIGHT = 32;
class Chip8 { class Chip8 {
public: public:
uint8_t registers[16]{}; uint8_t registers[CHIP8_REGISTERS]{};
uint8_t memory[4096]{}; uint8_t memory[CHIP8_RAM]{};
uint16_t index{}; uint16_t index{};
uint16_t pc{}; uint16_t pc{};
uint16_t stack[16]{}; uint16_t stack[CHIP8_STACK]{};
uint8_t sp{}; uint8_t sp{};
uint8_t delayTimer{}; uint8_t delayTimer{};
uint8_t soundTimer{}; uint8_t soundTimer{};
uint8_t keypad[16]{}; uint8_t keypad[CHIP8_KEYS]{};
uint32_t video[VIDEO_WIDTH * VIDEO_HEIGHT]{}; uint32_t video[CHIP8_WIDTH * CHIP8_HEIGHT]{};
uint16_t opcode; uint16_t opcode;
uint8_t fontset[FONTSET_SIZE] = uint8_t fontset[FONTSET_SIZE] =
{ {

@ -1 +0,0 @@
#include "code_panel.hpp"

@ -1 +0,0 @@
#pragma once

@ -0,0 +1,16 @@
#pragma once
constexpr const int DISPLAY_WIDTH = 1000;
constexpr const int WINDOW_WIDTH = 1280;
constexpr const int WINDOW_HEIGHT = 720;
constexpr const unsigned int START_ADDRESS = 0x200;
constexpr const unsigned int FONTSET_SIZE = 80;
constexpr const unsigned int FONTSET_START_ADDRESS = 0x50;
constexpr const unsigned int CHIP8_WIDTH = 64;
constexpr const unsigned int CHIP8_HEIGHT = 32;
constexpr const size_t CHIP8_REGISTERS = 16;
constexpr const size_t CHIP8_RAM = 4096;
constexpr const size_t CHIP8_STACK = 16;
constexpr const size_t CHIP8_KEYS = 16;

@ -0,0 +1,26 @@
#include "control_panel.hpp"
#include <fmt/xchar.h>
#include "constants.hpp"
ControlPanel::ControlPanel() {
}
void ControlPanel::init(sf::Vector2f size) {
$gui.position(0, size.y, size.x, WINDOW_HEIGHT - size.y);
$gui.layout("[buttons|code]");
for(auto& [name, cell] : $gui.cells()) {
auto id = $gui.entity(name);
$gui.set<guecs::Rectangle>(id, {});
$gui.set<guecs::Text>(id, {guecs::to_wstring(name)});
}
$gui.init();
}
void ControlPanel::render(sf::RenderTarget& window) {
$gui.render(window);
}
void ControlPanel::update(Chip8& vm) {
}

@ -0,0 +1,15 @@
#pragma once
#include <guecs/sfml/components.hpp>
#include <guecs/ui.hpp>
#include "chip8.hpp"
struct ControlPanel {
guecs::UI $gui;
ControlPanel();
void init(sf::Vector2f size);
void render(sf::RenderTarget& window);
void update(Chip8& vm);
};

@ -3,13 +3,14 @@
#include <SFML/System.hpp> #include <SFML/System.hpp>
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
Display::Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size) : Display::Display(sf::RenderWindow& window, sf::Vector2f pos, float width) :
$window(window) $window(window)
{ {
float border_width = 2.0f; float border_width = 2.0f;
$texture.setSmooth(false); $texture.setSmooth(false);
float ratio = (size.x - border_width * 2) / 64.0f; float ratio = (width - border_width * 2) / 64.0f;
// rectangle position doesn't include the border because everyone hates humans // 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 border_pos{pos.x + border_width, pos.y + border_width};
@ -24,6 +25,9 @@ Display::Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size)
$border.setOutlineThickness(border_width); $border.setOutlineThickness(border_width);
$border.setFillColor({0,0,0,255}); $border.setFillColor({0,0,0,255});
size = $border.getLocalBounds().size;
$control.init(size);
$status.init(); $status.init();
} }
@ -51,6 +55,7 @@ void Display::render() {
$window.draw($border); $window.draw($border);
$window.draw($texture_sprite); $window.draw($texture_sprite);
$status.render($window); $status.render($window);
$control.render($window);
$window.display(); $window.display();
} }

@ -5,15 +5,18 @@
#include <SFML/Graphics/RectangleShape.hpp> #include <SFML/Graphics/RectangleShape.hpp>
#include "chip8.hpp" #include "chip8.hpp"
#include "status_panel.hpp" #include "status_panel.hpp"
#include "control_panel.hpp"
struct Display { struct Display {
sf::Vector2f size{0,0};
sf::RenderWindow& $window; sf::RenderWindow& $window;
sf::Texture $texture{sf::Vector2u{VIDEO_WIDTH, VIDEO_HEIGHT}}; sf::Texture $texture{sf::Vector2u{CHIP8_WIDTH, CHIP8_HEIGHT}};
sf::Sprite $texture_sprite{$texture}; sf::Sprite $texture_sprite{$texture};
sf::RectangleShape $border; sf::RectangleShape $border;
StatusPanel $status; StatusPanel $status;
ControlPanel $control;
Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size); Display(sf::RenderWindow& window, sf::Vector2f pos, float width);
void handle_inputs(Chip8& vm); void handle_inputs(Chip8& vm);
void update(Chip8& vm); void update(Chip8& vm);

@ -21,7 +21,7 @@ int main(int argc, char* argv[]) {
Chip8 chip8; Chip8 chip8;
chip8.LoadROM(romFilename); chip8.LoadROM(romFilename);
int videoPitch = sizeof(chip8.video[0]) * VIDEO_WIDTH; int videoPitch = sizeof(chip8.video[0]) * CHIP8_WIDTH;
sfml::Backend backend; sfml::Backend backend;
guecs::init(&backend); guecs::init(&backend);
@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {
window.setFramerateLimit(framerate); window.setFramerateLimit(framerate);
window.setVerticalSyncEnabled(false); window.setVerticalSyncEnabled(false);
Display display{window, {0, 0}, {1000, 1000}}; Display display{window, {0, 0}, 1000};
Stats cycle_stats; Stats cycle_stats;
Stats render_stats; Stats render_stats;
Stats update_stats; Stats update_stats;

@ -5,5 +5,5 @@ sources = files(
'stats.cpp', 'stats.cpp',
'display.cpp', 'display.cpp',
'status_panel.cpp', 'status_panel.cpp',
'code_panel.cpp', 'control_panel.cpp',
) )

@ -1,8 +1,9 @@
#include "status_panel.hpp" #include "status_panel.hpp"
#include <fmt/xchar.h> #include <fmt/xchar.h>
#include "constants.hpp"
StatusPanel::StatusPanel() { StatusPanel::StatusPanel() {
$gui.position(1000, 0, 1280 - 1000, 720); $gui.position(DISPLAY_WIDTH, 0, WINDOW_WIDTH - DISPLAY_WIDTH, WINDOW_HEIGHT);
$gui.layout( $gui.layout(
"[N|Reg|Stk|Key]" "[N|Reg|Stk|Key]"
"[x0|r0|s0|k0]" "[x0|r0|s0|k0]"
@ -20,7 +21,9 @@ StatusPanel::StatusPanel() {
"[xC|r12|s12|k12]" "[xC|r12|s12|k12]"
"[xD|r13|s13|k13]" "[xD|r13|s13|k13]"
"[xE|r14|s14|k14]" "[xE|r14|s14|k14]"
"[xF|r15|s15|k15]"); "[xF|r15|s15|k15]"
"[PC|I|SP|DT|ST]"
"[pc|i|sp|dt|st]");
} }
void StatusPanel::init() { void StatusPanel::init() {
@ -38,15 +41,21 @@ void StatusPanel::render(sf::RenderTarget& window) {
} }
void StatusPanel::update(Chip8& vm) { void StatusPanel::update(Chip8& vm) {
for(size_t i = 0; i < 16; i++) { for(size_t i = 0; i < CHIP8_REGISTERS; i++) {
$gui.show_text(fmt::format("r{}", i), fmt::format(L"{}", vm.registers[i])); $gui.show_text(fmt::format("r{}", i), fmt::format(L"{}", vm.registers[i]));
} }
for(size_t i = 0; i < 16; i++) { for(size_t i = 0; i < CHIP8_STACK; i++) {
$gui.show_text(fmt::format("s{}", i), fmt::format(L"{}", vm.stack[i])); $gui.show_text(fmt::format("s{}", i), fmt::format(L"{}", vm.stack[i]));
} }
for(size_t i = 0; i < 16; i++) { for(size_t i = 0; i < CHIP8_KEYS; i++) {
$gui.show_text(fmt::format("k{}", i), fmt::format(L"{}", vm.keypad[i])); $gui.show_text(fmt::format("k{}", i), fmt::format(L"{}", vm.keypad[i]));
} }
$gui.show_text("pc", fmt::format(L"{}", vm.pc));
$gui.show_text("i", fmt::format(L"{}", vm.index));
$gui.show_text("sp", fmt::format(L"{}", vm.sp));
$gui.show_text("dt", fmt::format(L"{}", vm.delayTimer));
$gui.show_text("st", fmt::format(L"{}", vm.soundTimer));
} }

Loading…
Cancel
Save