Skip to content

Commit

Permalink
Refactor + basic layout
Browse files Browse the repository at this point in the history
  • Loading branch information
fpotier committed Jul 9, 2024
1 parent e356014 commit f7d8a82
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 84 deletions.
38 changes: 20 additions & 18 deletions chip-8-sdl/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@

#include "app.h"
#include "icons/folder.h"
#include "icons/play.h"
#include "icons/warning.h"
#include "widget/button.h"
#include "widget/chip8_screen.h"
#include "widget/label.h"
#include "widget/panel.h"

static constexpr int font_point_size = 12;

static constexpr int scale_factor = 10;
static constexpr int panel_width = chip8::screen_width * scale_factor;
static constexpr int panel_height = (chip8::screen_height / 8) * scale_factor;
static constexpr int renderer_width = chip8::screen_width * scale_factor;
static constexpr int renderer_height = chip8::screen_height * scale_factor + panel_height;
static constexpr int chip8screen_y = panel_height;
static constexpr int SCALE_FACTOR = 10;
static constexpr int PANEL_WIDTH = chip8::SCREEN_WIDTH * SCALE_FACTOR;
static constexpr int PANEL_HEIGHT = (chip8::SCREEN_HEIGHT / 8) * SCALE_FACTOR;
static constexpr int RENDERER_WIDTH = chip8::SCREEN_WIDTH * SCALE_FACTOR;
static constexpr int RENDERER_HEIGHT = chip8::SCREEN_HEIGHT * SCALE_FACTOR + PANEL_HEIGHT;
static constexpr int CHIP8SCREEN_Y = PANEL_HEIGHT;

app::app(config& conf, std::string const& rom_path, std::vector<uint8_t> const& program)
: m_emulator(program),
Expand All @@ -28,8 +30,8 @@ app::app(config& conf, std::string const& rom_path, std::vector<uint8_t> const&
conf.window_width, conf.window_height, 0) , SDLCleaner())),
m_quit(false),
m_audio_enabled(false),
m_audio_device(0),
m_wav_buffer(nullptr)
m_wav_buffer(nullptr),
m_audio_device(0)
{
sdl_checksuccess(SDL_Init(init_flags), "Failed to initialize the SDL: %s\n");
sdl_checksuccess(TTF_Init(), "Failed to initialize SDL_ttf: %s\n");
Expand All @@ -39,8 +41,8 @@ app::app(config& conf, std::string const& rom_path, std::vector<uint8_t> const&
sdl_nullcheck(m_renderer.get(), "Failed to create the renderer: %s\n");
set_renderer_color(m_renderer, m_conf.bg_color);
sdl_checksuccess(SDL_RenderClear(m_renderer.get()), "Failed to clear the renderer: %s\n");
sdl_checksuccess(SDL_RenderSetLogicalSize(m_renderer.get(), renderer_width, renderer_height),
"Failed to set the renderer's logical scale: %s");
// sdl_checksuccess(SDL_RenderSetLogicalSize(m_renderer.get(), RENDERER_WIDTH, RENDERER_HEIGHT),
// "Failed to set the renderer's logical scale: %s");
sdl_checksuccess(SDL_RenderSetIntegerScale(m_renderer.get(), SDL_TRUE),
"Failed to set integer scaling on the renderer: %s");
if (conf.sound_file)
Expand Down Expand Up @@ -69,14 +71,14 @@ app::app(config& conf, std::string const& rom_path, std::vector<uint8_t> const&
sdl_nullcheck(m_font.get(), fmt::format("Failed to open font file: {}", font_strpath).c_str());
}

panel_ptr p1 = std::make_shared<panel>(m_renderer, 0, 0, panel_width, panel_height, m_conf.fg_color, m_conf.bg_color);
button_ptr b1 = std::make_shared<button>(m_renderer, 1, 2, 32, 32, m_conf.fg_color, m_conf.bg_color, folder_icon, 32, 32);
// label_ptr l1 = std::make_shared<label>(m_renderer, 1, 2, panel_width - 2, panel_height - 3, m_conf.fg_color, m_conf.bg_color, m_rom_path, m_font);
panel_ptr p1 = std::make_unique<panel>(m_renderer, 0, 0, PANEL_WIDTH, PANEL_HEIGHT, m_conf.fg_color, m_conf.bg_color, Layout::Horizontal);
p1->add_child(std::make_unique<button>(m_renderer, 1, 2, 32, 32, m_conf.fg_color, m_conf.bg_color, folder_icon, 32, 32));
p1->add_child(std::make_unique<button>(m_renderer, 1, 2, 32, 32, m_conf.fg_color, m_conf.bg_color, play_icon, 32, 32));
p1->add_child(std::make_unique<button>(m_renderer, 1, 2, 32, 32, m_conf.fg_color, m_conf.bg_color, warning_icon, 32, 32));
// label_ptr l1 = std::make_shared<label>(m_renderer, 1, 2, PANEL_WIDTH - 2, PANEL_HEIGHT - 3, m_conf.fg_color, m_conf.bg_color, m_rom_path, m_font);
// p1->add_child(l1);
p1->add_child(b1);

m_widgets.push_back(p1);
m_widgets.push_back(std::make_shared<chip8_screen>(m_renderer, 0, panel_height, m_conf.fg_color, m_conf.bg_color, m_emulator, scale_factor));
m_widgets.push_back(std::make_unique<chip8_screen>(m_renderer, 0, PANEL_HEIGHT, m_conf.fg_color, m_conf.bg_color, m_emulator, SCALE_FACTOR));
m_widgets.push_back(std::move(p1));
}

app::~app()
Expand Down Expand Up @@ -172,7 +174,7 @@ void app::render()
{
set_renderer_color(m_renderer, m_conf.bg_color);
SDL_RenderClear(m_renderer.get());
for (widget_ptr widget : m_widgets)
for (widget_ptr const& widget : m_widgets)
{
widget->draw();
SDL_SetRenderTarget(m_renderer.get(), NULL);
Expand Down
4 changes: 2 additions & 2 deletions chip-8-sdl/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ struct config
public:
static constexpr uint16_t default_width = 640;
static constexpr uint16_t default_height = 360;
static constexpr uint8_t default_instructions_per_frame = 10;
static constexpr uint16_t default_instructions_per_frame = 10;
static constexpr SDL_Color default_fg_color = SDL_Color { 255, 255, 255, 255 };
static constexpr SDL_Color default_bg_color = SDL_Color { 0, 0, 0, 255 };

uint16_t window_width;
uint16_t window_height;
uint8_t instructions_per_frame;
uint16_t instructions_per_frame;
SDL_Color fg_color;
SDL_Color bg_color;
std::optional<std::filesystem::path> sound_file;
Expand Down
2 changes: 2 additions & 0 deletions chip-8-sdl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <filesystem>
#include <SDL.h>
#include <yaml-cpp/yaml.h>
#include <fmt/core.h>

#include "app.h"
#include "chip8.h"
Expand Down Expand Up @@ -32,6 +33,7 @@ int main(int argc, char** argv)
config conf;
if (result.count("file"))
{
fmt::print("Loading config {}\n", result["file"].as<std::string>());
YAML::Node config_yaml = YAML::LoadFile(result["file"].as<std::string>());
conf = config(config_yaml);
}
Expand Down
2 changes: 1 addition & 1 deletion chip-8-sdl/widget/button.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ class button : public widget
int m_icon_h;
};

using button_ptr = std::shared_ptr<button>;
using button_ptr = std::unique_ptr<button>;
8 changes: 4 additions & 4 deletions chip-8-sdl/widget/chip8_screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ void chip8_screen::draw()

set_renderer_color(m_renderer, m_bg_color);
SDL_RenderClear(m_renderer.get());
std::array<uint8_t, chip8::vram_size> const& emulator_vram = m_emulator.get_vram();
std::array<uint8_t, chip8::VRAM_SIZE> const& emulator_vram = m_emulator.get_vram();
if (m_emulator.vram_dirty)
{
SDL_Rect pixel = SDL_Rect { 0, 0, m_scale_factor, m_scale_factor };
for (std::size_t y = 0; y < chip8::screen_height; y++)
for (std::size_t y = 0; y < chip8::SCREEN_HEIGHT; y++)
{
pixel.y = y * pixel.h;
for (std::size_t x = 0; x < chip8::screen_width; x++)
for (std::size_t x = 0; x < chip8::SCREEN_WIDTH; x++)
{
pixel.x = x * pixel.w;
uint8_t pixel_val = emulator_vram[x + y * chip8::screen_width];
uint8_t pixel_val = emulator_vram[x + y * chip8::SCREEN_WIDTH];
if (pixel_val)
set_renderer_color(m_renderer, m_fg_color);
else
Expand Down
6 changes: 3 additions & 3 deletions chip-8-sdl/widget/chip8_screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
class chip8_screen : public widget
{
public:
chip8_screen(SDLSharedRenderer renderer, int x, int y, SDL_Color fg_color, SDL_Color bg_color, chip8 const& emulator, int scale_factor)
: widget(renderer, x, y, chip8::screen_width * scale_factor, chip8::screen_height * scale_factor, fg_color, bg_color),
m_emulator(emulator), m_scale_factor(scale_factor)
chip8_screen(SDLSharedRenderer renderer, int x, int y, SDL_Color fg_color, SDL_Color bg_color, chip8 const& emulator, int SCALE_FACTOR)
: widget(renderer, x, y, chip8::SCREEN_WIDTH * SCALE_FACTOR, chip8::SCREEN_HEIGHT * SCALE_FACTOR, fg_color, bg_color),
m_emulator(emulator), m_scale_factor(SCALE_FACTOR)
{}
~chip8_screen() override;
void draw() override;
Expand Down
2 changes: 1 addition & 1 deletion chip-8-sdl/widget/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ class label : public widget
bool m_changed;
};

using label_ptr = std::shared_ptr<label>;
using label_ptr = std::unique_ptr<label>;
7 changes: 7 additions & 0 deletions chip-8-sdl/widget/layout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

enum class Layout {
NoLayout,
Horizontal,
Vertical,
};
41 changes: 38 additions & 3 deletions chip-8-sdl/widget/panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,50 @@ void panel::draw()
set_renderer_color(m_renderer, m_fg_color);
SDL_RenderDrawLines(m_renderer.get(), edges.data(), edges.size());

for (widget_ptr widget : m_children)
for (widget_ptr const& widget : m_children)
{
widget->draw();
as_rendering_target();
SDL_RenderCopy(m_renderer.get(), widget->texture(), NULL, widget->rect());
}
}

void panel::add_child(widget_ptr child)
void panel::add_child(widget_ptr&& child)
{
m_children.push_back(child);
m_children.push_back(std::move(child));
apply_layout();
}

void panel::set_layout(Layout l)
{
m_layout = l;
apply_layout();
}

void panel::apply_layout()
{
switch (m_layout) {
case Layout::Horizontal:
{
int next_x = 2;
for (widget_ptr& widget : m_children)
{
widget->x() = next_x;
next_x += widget->w();
}
break;
}
case Layout::Vertical:
{
int next_y = 0;
for (widget_ptr& widget : m_children)
{
widget->y() = next_y;
next_y += widget->h();
}
break;
}
case Layout::NoLayout:
break;
}
}
14 changes: 10 additions & 4 deletions chip-8-sdl/widget/panel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@
#include <vector>

#include "widget.h"
#include "layout.h"

class panel : public widget
{
public:
panel(SDLSharedRenderer renderer, int x, int y, int w, int h, SDL_Color fg_color, SDL_Color bg_color)
panel(SDLSharedRenderer renderer, int x, int y, int w, int h, SDL_Color fg_color, SDL_Color bg_color, Layout layout = Layout::NoLayout)
: widget(renderer, x, y, w, h, fg_color, bg_color),
m_children()
m_children(),
m_layout(layout)
{}
~panel() override;
void draw() override;
void add_child(widget_ptr child);
void add_child(widget_ptr&& child);
void set_layout(Layout layout);
private:
void apply_layout();

std::vector<widget_ptr> m_children;
Layout m_layout = Layout::NoLayout;
};

using panel_ptr = std::shared_ptr<panel>;
using panel_ptr = std::unique_ptr<panel>;
14 changes: 9 additions & 5 deletions chip-8-sdl/widget/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ class widget

SDL_Rect* rect() { return &m_rect; }
SDL_Texture* texture() const { return m_texture.get(); }
int x() { return m_rect.x; }
int y() { return m_rect.y; }
int w() { return m_rect.w; }
int h() { return m_rect.h; }
int x() const { return m_rect.x; }
int& x() { return m_rect.x; }
int y() const { return m_rect.y; }
int& y() { return m_rect.y; }
int w() const { return m_rect.w; }
int& w() { return m_rect.w; }
int h() const { return m_rect.h; }
int& h() { return m_rect.h; }
protected:
SDL_Rect m_rect;
SDLSharedRenderer m_renderer;
Expand All @@ -25,4 +29,4 @@ class widget
SDL_Color m_bg_color;
};

using widget_ptr = std::shared_ptr<widget>;
using widget_ptr = std::unique_ptr<widget>;
39 changes: 19 additions & 20 deletions lib/include/chip8.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ class chip8
friend class chip8_test;

public:
// TODO all caps
static constexpr int ram_size = 4096;
static constexpr int screen_width = 64;
static constexpr int screen_height = 32;
static constexpr int vram_size = screen_width * screen_height;
static constexpr int register_number = 16;
static constexpr int stack_size = 16;
static constexpr int keypad_size = 16;
static constexpr int no_key_pressed = -1;
static constexpr int entry_point = 512;
static constexpr int RAM_SIZE = 4096;
static constexpr int SCREEN_WIDTH = 64;
static constexpr int SCREEN_HEIGHT = 32;
static constexpr int VRAM_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
static constexpr int NB_REGISTER = 16;
static constexpr int STACK_SIZE = 16;
static constexpr int KEYPAD_SIZE = 16;
static constexpr int NO_KEY_PRESSED = -1;
static constexpr int ENTRYPOINT = 0x200;
static constexpr std::array<uint8_t, 80> font
{
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
Expand Down Expand Up @@ -58,23 +57,23 @@ class chip8
void key_pressed(std::size_t key_code);
void key_released(std::size_t key_code);

std::array<uint8_t, register_number> const& get_registers() const { return V; }
std::array<uint8_t, ram_size> const& get_ram() const { return ram; }
std::array<uint8_t, vram_size> const& get_vram() const { return vram; }
std::array<uint16_t, stack_size> const& get_stack() const { return stack; }
std::array<uint8_t, NB_REGISTER> const& get_registers() const { return V; }
std::array<uint8_t, RAM_SIZE> const& get_ram() const { return ram; }
std::array<uint8_t, VRAM_SIZE> const& get_vram() const { return vram; }
std::array<uint16_t, STACK_SIZE> const& get_stack() const { return stack; }
uint16_t get_I() const { return I; }
uint16_t get_ip() const { return ip; }
uint8_t get_sp() const { return sp; }
std::array<bool, keypad_size> get_keypad() const { return keypad; }
std::array<bool, KEYPAD_SIZE> get_keypad() const { return keypad; }
uint8_t get_sound_timer() const { return sound_timer; }
uint8_t get_delay_timer() const { return delay_timer; }

private:
std::array<uint8_t, register_number> V;
std::array<uint8_t, ram_size> ram;
std::array<uint8_t, vram_size> vram;
std::array<uint16_t, stack_size> stack;
std::array<bool, keypad_size> keypad;
std::array<uint8_t, NB_REGISTER> V;
std::array<uint8_t, RAM_SIZE> ram;
std::array<uint8_t, VRAM_SIZE> vram;
std::array<uint16_t, STACK_SIZE> stack;
std::array<bool, KEYPAD_SIZE> keypad;
uint16_t I; // Index register
uint16_t ip; // Instruction pointer
uint8_t sp; // Stack pointer
Expand Down
Loading

0 comments on commit f7d8a82

Please sign in to comment.