summaryrefslogtreecommitdiff
path: root/lib/nes/app/ui
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nes/app/ui')
-rw-r--r--lib/nes/app/ui/CMakeLists.txt6
-rw-r--r--lib/nes/app/ui/screen-confirm-quit.cc68
-rw-r--r--lib/nes/app/ui/screen-confirm-quit.hh24
-rw-r--r--lib/nes/app/ui/screen-error.cc7
-rw-r--r--lib/nes/app/ui/screen-error.hh7
-rw-r--r--lib/nes/app/ui/screen-freeze.cc33
-rw-r--r--lib/nes/app/ui/screen-freeze.hh25
7 files changed, 164 insertions, 6 deletions
diff --git a/lib/nes/app/ui/CMakeLists.txt b/lib/nes/app/ui/CMakeLists.txt
index de42744..37720c1 100644
--- a/lib/nes/app/ui/CMakeLists.txt
+++ b/lib/nes/app/ui/CMakeLists.txt
@@ -7,5 +7,9 @@ target_sources(
screen-title.cc
screen-browser.hh
screen-browser.cc
+ screen-freeze.hh
+ screen-freeze.cc
screen-error.hh
- screen-error.cc) \ No newline at end of file
+ screen-error.cc
+ screen-confirm-quit.hh
+ screen-confirm-quit.cc) \ No newline at end of file
diff --git a/lib/nes/app/ui/screen-confirm-quit.cc b/lib/nes/app/ui/screen-confirm-quit.cc
new file mode 100644
index 0000000..3c7a337
--- /dev/null
+++ b/lib/nes/app/ui/screen-confirm-quit.cc
@@ -0,0 +1,68 @@
+#include "nes/app/ui/screen-confirm-quit.hh"
+#include "nes/app/graphics/renderer.hh"
+#include "nes/app/graphics/color.hh"
+#include "nes/app/input/input-device-keyboard.hh"
+
+namespace nes::app
+{
+ screen_confirm_quit::screen_confirm_quit(input_device_keyboard& keyboard)
+ : keyboard_{ keyboard }
+ {
+ }
+
+ auto screen_confirm_quit::render(renderer& renderer) -> void
+ {
+ renderer.render_rect(2, 8, 28, 10, color::background_secondary);
+ renderer.render_border(2, 8, 28, 10, color::foreground_primary);
+
+ auto const attrs = text_attributes{}
+ .set_alignment(text_alignment::center)
+ .set_ellipsize_mode(ellipsize_mode::end)
+ .set_max_width(26);
+ renderer.render_text(16, 10, "Are you sure?", color::foreground_primary, attrs);
+ renderer.render_text(16, 12, "All progress is lost.", color::foreground_primary, attrs);
+ if (confirm_)
+ {
+ renderer.render_text(10, 15, "Cancel", color::foreground_secondary);
+ renderer.render_text(18, 15, "> OK <", color::accent_primary);
+ }
+ else
+ {
+ renderer.render_text(8, 15, "> Cancel <", color::accent_primary);
+ renderer.render_text(20, 15, "OK", color::foreground_secondary);
+ }
+ }
+
+ auto screen_confirm_quit::process_events() -> action
+ {
+ while (auto const event = keyboard_.poll_event())
+ {
+ // Use key-up so the enter key is not immediately captured by the game.
+ if (event == input_event::key_up(key::enter))
+ {
+ if (confirm_)
+ {
+ return action::confirm_quit();
+ }
+ else
+ {
+ return action::cancel_quit();
+ }
+ }
+ else if (event == input_event::key_down(key::space))
+ {
+ confirm_ = !confirm_;
+ }
+ else if (event == input_event::key_down(key::arrow_left))
+ {
+ confirm_ = false;
+ }
+ else if (event == input_event::key_down(key::arrow_right))
+ {
+ confirm_ = true;
+ }
+ }
+
+ return action{};
+ }
+} // namespace nes::app \ No newline at end of file
diff --git a/lib/nes/app/ui/screen-confirm-quit.hh b/lib/nes/app/ui/screen-confirm-quit.hh
new file mode 100644
index 0000000..c176f4b
--- /dev/null
+++ b/lib/nes/app/ui/screen-confirm-quit.hh
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "nes/app/ui/screen.hh"
+
+namespace nes::app
+{
+ class input_device_keyboard;
+
+ /// A popup asking the user if they really want to quit the game.
+ class screen_confirm_quit final : public screen
+ {
+ input_device_keyboard& keyboard_;
+ bool confirm_{ false };
+
+ public:
+ explicit screen_confirm_quit(input_device_keyboard&);
+
+ auto get_confirm() const -> bool { return confirm_; }
+ auto set_confirm(bool const v) -> void { confirm_ = v; }
+
+ auto render(renderer&) -> void override;
+ auto process_events() -> action override;
+ };
+} // namespace nes::app \ No newline at end of file
diff --git a/lib/nes/app/ui/screen-error.cc b/lib/nes/app/ui/screen-error.cc
index 67a3244..9375012 100644
--- a/lib/nes/app/ui/screen-error.cc
+++ b/lib/nes/app/ui/screen-error.cc
@@ -12,8 +12,8 @@ namespace nes::app
auto screen_error::render(renderer& renderer) -> void
{
- // TODO: Nicer box
- renderer.render_rect(2, 9, 28, 5, color::background_secondary);
+ renderer.render_rect(2, 8, 28, 10, color::background_secondary);
+ renderer.render_border(2, 8, 28, 10, color::foreground_primary);
auto const attrs = text_attributes{}
.set_alignment(text_alignment::center)
@@ -21,6 +21,7 @@ namespace nes::app
.set_max_width(26);
renderer.render_text_format(16, 10, color::foreground_primary, attrs, "{}:", message_);
renderer.render_text(16, 12, to_string(error_), color::foreground_primary, attrs);
+ renderer.render_text(16, 15, "> OK <", color::accent_primary, attrs);
}
auto screen_error::process_events() -> action
@@ -29,7 +30,7 @@ namespace nes::app
{
if (event == input_event::key_down(key::enter))
{
- return action::close_popup();
+ return action_;
}
}
diff --git a/lib/nes/app/ui/screen-error.hh b/lib/nes/app/ui/screen-error.hh
index ec877e1..4559942 100644
--- a/lib/nes/app/ui/screen-error.hh
+++ b/lib/nes/app/ui/screen-error.hh
@@ -12,14 +12,17 @@ namespace nes::app
input_device_keyboard& keyboard_;
std::string_view message_;
status error_{ status::success };
+ action action_{};
public:
explicit screen_error(input_device_keyboard&);
auto get_message() const -> std::string_view { return message_; }
auto get_error() const -> status { return error_; }
- auto set_message(std::string_view const v) { message_ = v; }
- auto set_error(status const v) { error_ = v; }
+ auto get_action() const -> action { return action_; }
+ auto set_message(std::string_view const v) -> void { message_ = v; }
+ auto set_error(status const v) -> void { error_ = v; }
+ auto set_action(action const& v) -> void { action_ = v; }
auto render(renderer&) -> void override;
auto process_events() -> action override;
diff --git a/lib/nes/app/ui/screen-freeze.cc b/lib/nes/app/ui/screen-freeze.cc
new file mode 100644
index 0000000..60410dd
--- /dev/null
+++ b/lib/nes/app/ui/screen-freeze.cc
@@ -0,0 +1,33 @@
+#include "nes/app/ui/screen-freeze.hh"
+#include "nes/app/graphics/renderer.hh"
+
+namespace nes::app
+{
+ auto screen_freeze::freeze(display const& disp) -> void
+ {
+ for (auto y = u32{ 0 }; y < display::height; ++y)
+ {
+ for (auto x = u32{ 0 }; x < display::width; ++x)
+ {
+ frozen_data_[y * display::width + x] = disp.get(x, y);
+ }
+ }
+ }
+
+ auto screen_freeze::render(renderer& renderer) -> void
+ {
+ auto& disp = renderer.get_display();
+ for (auto y = u32{ 0 }; y < display::height; ++y)
+ {
+ for (auto x = u32{ 0 }; x < display::width; ++x)
+ {
+ disp.set(x, y, frozen_data_[y * display::width + x]);
+ }
+ }
+ }
+
+ auto screen_freeze::process_events() -> action
+ {
+ return action{};
+ }
+} // namespace nes::app \ No newline at end of file
diff --git a/lib/nes/app/ui/screen-freeze.hh b/lib/nes/app/ui/screen-freeze.hh
new file mode 100644
index 0000000..fe67aad
--- /dev/null
+++ b/lib/nes/app/ui/screen-freeze.hh
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "nes/app/ui/screen.hh"
+#include "nes/common/rgb.hh"
+#include "nes/common/display.hh"
+
+namespace nes::app
+{
+ /// Freeze screen which preserves the display buffer at a certain state.
+ ///
+ /// This is usually used to preserve the image from the console when the game should not continue.
+ class screen_freeze final : public screen
+ {
+ rgb frozen_data_[display::width * display::height]{};
+
+ public:
+ explicit screen_freeze() = default;
+
+ auto render(renderer&) -> void override;
+ auto process_events() -> action override;
+
+ /// Update the image shown to the back buffer of the given display.
+ auto freeze(display const&) -> void;
+ };
+} // namespace nes::app \ No newline at end of file