summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2025-01-13 23:42:17 +0100
committerHannes Schulze <haschu0103@outlook.de>2025-01-13 23:42:17 +0100
commit5734a139d3f218972b5ebaff0e51167770352bcf (patch)
treeadae3fee4a9cca191bd6e5903067964841da99bf
parenta2edbedb520f2ada936c00308cc6dfd75717b0d8 (diff)
finish ui
-rw-r--r--src/nes/CMakeLists.txt8
-rw-r--r--src/nes/controller.cc6
-rw-r--r--src/nes/controller.hh23
-rw-r--r--src/nes/cpu.cc6
-rw-r--r--src/nes/cpu.hh15
-rw-r--r--src/nes/nes.cc5
-rw-r--r--src/nes/nes.hh14
-rw-r--r--src/nes/ppu.cc6
-rw-r--r--src/nes/ppu.hh15
-rw-r--r--src/nes/util/CMakeLists.txt1
-rw-r--r--src/nes/util/button-mask.hh43
-rw-r--r--src/scene.mm79
12 files changed, 219 insertions, 2 deletions
diff --git a/src/nes/CMakeLists.txt b/src/nes/CMakeLists.txt
index c217219..59f213d 100644
--- a/src/nes/CMakeLists.txt
+++ b/src/nes/CMakeLists.txt
@@ -8,4 +8,10 @@ target_sources(
cartridge.hh
cartridge.cc
display.hh
- display.cc) \ No newline at end of file
+ display.cc
+ controller.hh
+ controller.cc
+ cpu.hh
+ cpu.cc
+ ppu.hh
+ ppu.cc) \ No newline at end of file
diff --git a/src/nes/controller.cc b/src/nes/controller.cc
new file mode 100644
index 0000000..f0d7728
--- /dev/null
+++ b/src/nes/controller.cc
@@ -0,0 +1,6 @@
+#include "nes/controller.hh"
+
+namespace nes
+{
+
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/controller.hh b/src/nes/controller.hh
new file mode 100644
index 0000000..0489b20
--- /dev/null
+++ b/src/nes/controller.hh
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "nes/util/button-mask.hh"
+
+namespace nes
+{
+ class controller
+ {
+ button_mask pressed_;
+
+ public:
+ explicit controller() = default;
+
+ controller(controller const&) = delete;
+ controller(controller&&) = delete;
+ auto operator=(controller const&) -> controller& = delete;
+ auto operator=(controller&&) -> controller& = delete;
+
+ auto get_pressed() const -> button_mask { return pressed_;}
+ auto get_pressed() -> button_mask& { return pressed_; }
+ auto set_pressed(button_mask const value) -> void { pressed_ = value; }
+ };
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/cpu.cc b/src/nes/cpu.cc
new file mode 100644
index 0000000..fb0f8d2
--- /dev/null
+++ b/src/nes/cpu.cc
@@ -0,0 +1,6 @@
+#include "nes/cpu.hh"
+
+namespace nes
+{
+
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/cpu.hh b/src/nes/cpu.hh
new file mode 100644
index 0000000..972b307
--- /dev/null
+++ b/src/nes/cpu.hh
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace nes
+{
+ class cpu
+ {
+ public:
+ explicit cpu() = default;
+
+ cpu(cpu const&) = delete;
+ cpu(cpu&&) = delete;
+ auto operator=(cpu const&) -> cpu& = delete;
+ auto operator=(cpu&&) -> cpu& = delete;
+ };
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/nes.cc b/src/nes/nes.cc
index 63175aa..2a44ced 100644
--- a/src/nes/nes.cc
+++ b/src/nes/nes.cc
@@ -18,4 +18,9 @@ namespace nes
display.clear(rgb::from_hex(0xFF0000));
display.switch_buffers();
}
+
+ auto nes::step(std::uint64_t delta_ms) -> void
+ {
+ std::cout << "Step: " << delta_ms << "ms\n";
+ }
} // namespace nes \ No newline at end of file
diff --git a/src/nes/nes.hh b/src/nes/nes.hh
index 924ddd4..d3baf2a 100644
--- a/src/nes/nes.hh
+++ b/src/nes/nes.hh
@@ -1,6 +1,9 @@
#pragma once
#include "nes/cartridge.hh"
+#include "nes/controller.hh"
+#include "nes/cpu.hh"
+#include "nes/ppu.hh"
namespace nes
{
@@ -11,6 +14,10 @@ namespace nes
{
cartridge cartridge_;
display& display_;
+ controller controller_1_;
+ controller controller_2_;
+ cpu cpu_;
+ ppu ppu_;
public:
explicit nes(cartridge, display&);
@@ -19,5 +26,12 @@ namespace nes
nes(nes&&) = delete;
auto operator=(nes const&) -> nes& = delete;
auto operator=(nes&&) -> nes& = delete;
+
+ auto get_controller_1() const -> controller const& { return controller_1_; }
+ auto get_controller_1() -> controller& { return controller_1_; }
+ auto get_controller_2() const -> controller const& { return controller_2_; }
+ auto get_controller_2() -> controller& { return controller_2_; }
+
+ auto step(std::uint64_t delta_ms) -> void;
};
} // namespace nes \ No newline at end of file
diff --git a/src/nes/ppu.cc b/src/nes/ppu.cc
new file mode 100644
index 0000000..8ec6243
--- /dev/null
+++ b/src/nes/ppu.cc
@@ -0,0 +1,6 @@
+#include "nes/ppu.hh"
+
+namespace nes
+{
+
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/ppu.hh b/src/nes/ppu.hh
new file mode 100644
index 0000000..0f541ac
--- /dev/null
+++ b/src/nes/ppu.hh
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace nes
+{
+ class ppu
+ {
+ public:
+ explicit ppu() = default;
+
+ ppu(ppu const&) = delete;
+ ppu(ppu&&) = delete;
+ auto operator=(ppu const&) -> ppu& = delete;
+ auto operator=(ppu&&) -> ppu& = delete;
+ };
+} // namespace nes \ No newline at end of file
diff --git a/src/nes/util/CMakeLists.txt b/src/nes/util/CMakeLists.txt
index 1d30125..f78a26f 100644
--- a/src/nes/util/CMakeLists.txt
+++ b/src/nes/util/CMakeLists.txt
@@ -2,4 +2,5 @@ target_sources(
nes
PRIVATE
address.hh
+ button-mask.hh
rgb.hh) \ No newline at end of file
diff --git a/src/nes/util/button-mask.hh b/src/nes/util/button-mask.hh
new file mode 100644
index 0000000..b010b9e
--- /dev/null
+++ b/src/nes/util/button-mask.hh
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <cstdint>
+
+namespace nes
+{
+ class button_mask
+ {
+ std::uint8_t raw_value_{ 0 };
+
+ public:
+ constexpr explicit button_mask() = default;
+
+ static constexpr auto from_raw_value(std::uint8_t const raw_value) -> button_mask
+ {
+ return button_mask{ raw_value };
+ }
+
+ constexpr auto add(button_mask const other) -> void { raw_value_ |= other.raw_value_; }
+ constexpr auto remove(button_mask const other) -> void { raw_value_ ^= other.raw_value_; }
+ constexpr auto contains(button_mask const other) const -> bool { return (raw_value_ & other.raw_value_) == other.raw_value_; }
+ constexpr auto is_empty() const -> bool { return raw_value_ == 0; }
+ constexpr auto get_raw_value() const -> std::uint8_t { return raw_value_; }
+
+ private:
+ constexpr explicit button_mask(std::uint8_t const raw_value)
+ : raw_value_{ raw_value }
+ {
+ }
+ };
+
+ namespace buttons
+ {
+ static constexpr auto a = button_mask::from_raw_value(1 << 0);
+ static constexpr auto b = button_mask::from_raw_value(1 << 1);
+ static constexpr auto select = button_mask::from_raw_value(1 << 2);
+ static constexpr auto start = button_mask::from_raw_value(1 << 3);
+ static constexpr auto up = button_mask::from_raw_value(1 << 4);
+ static constexpr auto down = button_mask::from_raw_value(1 << 5);
+ static constexpr auto left = button_mask::from_raw_value(1 << 6);
+ static constexpr auto right = button_mask::from_raw_value(1 << 7);
+ } // namespace buttons
+} // namespace nes \ No newline at end of file
diff --git a/src/scene.mm b/src/scene.mm
index 1dbcecd..bb461ab 100644
--- a/src/scene.mm
+++ b/src/scene.mm
@@ -3,6 +3,7 @@
#import "nes/display.hh"
#import "nes/util/rgb.hh"
#import <memory>
+#import <optional>
namespace
{
@@ -68,6 +69,7 @@ namespace
{
std::unique_ptr<display_impl> display_;
std::unique_ptr<nes::nes> nes_;
+ std::optional<NSTimeInterval> last_time_;
}
- (instancetype)initWithFilePath:(NSString*)filePath
@@ -90,9 +92,84 @@ namespace
return self;
}
+- (void)keyDown:(NSEvent*)event
+{
+ auto& controller_1 = self->nes_->get_controller_1();
+
+ switch ([event keyCode])
+ {
+ case 0x7e: // up arrow
+ controller_1.get_pressed().add(nes::buttons::up);
+ break;
+ case 0x7d: // down arrow
+ controller_1.get_pressed().add(nes::buttons::down);
+ break;
+ case 0x7b: // left arrow
+ controller_1.get_pressed().add(nes::buttons::left);
+ break;
+ case 0x7c: // right arrow
+ controller_1.get_pressed().add(nes::buttons::right);
+ break;
+ case 0x6: // "Z"
+ controller_1.get_pressed().add(nes::buttons::a);
+ break;
+ case 0x7: // "X"
+ controller_1.get_pressed().add(nes::buttons::b);
+ break;
+ case 0x24: // return
+ controller_1.get_pressed().add(nes::buttons::start);
+ break;
+ case 0x31: // space
+ controller_1.get_pressed().add(nes::buttons::select);
+ break;
+ default:
+ [super keyDown:event];
+ break;
+ }
+}
+
+- (void)keyUp:(NSEvent*)event
+{
+ auto& controller_1 = self->nes_->get_controller_1();
+
+ switch ([event keyCode])
+ {
+ case 0x7e: // up arrow
+ controller_1.get_pressed().remove(nes::buttons::up);
+ break;
+ case 0x7d: // down arrow
+ controller_1.get_pressed().remove(nes::buttons::down);
+ break;
+ case 0x7b: // left arrow
+ controller_1.get_pressed().remove(nes::buttons::left);
+ break;
+ case 0x7c: // right arrow
+ controller_1.get_pressed().remove(nes::buttons::right);
+ break;
+ case 0x6: // "Z"
+ controller_1.get_pressed().remove(nes::buttons::a);
+ break;
+ case 0x7: // "X"
+ controller_1.get_pressed().remove(nes::buttons::b);
+ break;
+ case 0x24: // return
+ controller_1.get_pressed().remove(nes::buttons::start);
+ break;
+ case 0x31: // space
+ controller_1.get_pressed().remove(nes::buttons::select);
+ break;
+ default:
+ [super keyUp:event];
+ break;
+ }
+}
+
- (void)update:(NSTimeInterval)currentTime
{
- [super update:currentTime];
+ auto const last_time = self->last_time_.value_or(currentTime);
+ last_time_ = currentTime;
+ auto const delta_ms = static_cast<std::uint64_t>((currentTime - last_time) * 1000.);
+ self->nes_->step(delta_ms);
}
@end \ No newline at end of file