diff --git a/examples/PoolBox/application/src/Overlay/ScreenCenter/screen_center.cpp b/examples/PoolBox/application/src/Overlay/ScreenCenter/screen_center.cpp index d30f59fb..efcb92fa 100644 --- a/examples/PoolBox/application/src/Overlay/ScreenCenter/screen_center.cpp +++ b/examples/PoolBox/application/src/Overlay/ScreenCenter/screen_center.cpp @@ -1,16 +1,139 @@ #include "../../../include/shared.hpp" #include "include/frame.hpp" +#include #include #include +#include #include namespace ScreenCenter { using namespace JabyEngine; + using GenericButton = Periphery::GenericController::Button; - static const auto frame = Frame::create(); + struct ButtonWatcher { + enum struct State { + WentDown, + DownFor25000ms, + Unkown + }; + + SimpleTimer timer; + + void setup() { + this->timer.reset(); + } + + State check(GenericButton button) { + const auto controller = Periphery::get_primary_controller_as(); + + if(controller.button.went_down(button)) { + this->timer.reset(); + return State::WentDown; + } + + if(controller.button.was_down(button)) { + if(this->timer.is_expired_for(2500_ms)) { + return State::DownFor25000ms; + } + } + + else { + this->timer.reset(); + } + return State::Unkown; + } + }; + + #ifdef JABYENGINE_PAL + static const char TVModeStr[] = "PAL"; + static constexpr uint16_t ScanlinesV = 288; + #else + static const char TVModeStr[] = "NTSC"; + static constexpr uint16_t ScanlinesV = 240; + #endif //JABYENGINE_PAL + + static const auto frame = Frame::create(); + static ButtonWatcher button_watcher[4]; + static void (*update)() = nullptr; + static int16_t offset_x = 0; + static int16_t offset_y = 0; + + namespace PSYQ { + static void set_offset(uint16_t x, uint16_t y) { + x += 78; + y += 43; + + GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + GPU::Display::Width) << 3)); + GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y, y + GPU::Display::Height)); + } + } + + namespace No$PSX { + static void set_offset(uint16_t x, uint16_t y) { + GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange(x, (x + GPU::Display::Width*8))); + GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2))); + } + } + + static void update_interactive(); + + static void update_enter_state() { + static const char IntroductionTest[] = "Press START to begin"; + static constexpr auto IntroductionTestLength = BIOSFont::Info.estimate_str_render_length(IntroductionTest); + static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - IntroductionTestLength)/2, (GPU::Display::Height - 16)/2); + + const auto controller = Periphery::get_primary_controller_as(); + + if(controller.button.went_down(GenericButton::ST)) { + update = update_interactive; + } + + auto cursor = FontWriter::update(CenterPoint); + FontWriter::bios_font_writer.write(cursor, IntroductionTest, GPU::Color24::Red()); + } + + static void update_interactive() { + static const auto handle_button = [](ButtonWatcher& button_state, GenericButton button, int16_t &dst, const int16_t mlp) { + switch(button_state.check(button)) { + case ButtonWatcher::State::WentDown: + case ButtonWatcher::State::DownFor25000ms: + dst += (1*mlp); + break; + } + }; + + static const char*const ModeStr = "TV-Mode: %s\n"; + static const char*const FormularStr = "<>\n"; + static const char OffsetStr[] = "Offset: %i, %i"; + + static constexpr auto CenterLength = FontWriter::BIOSFont::Info.estimate_str_render_length(OffsetStr); + static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - CenterLength)/2, (GPU::Display::Height - 3*16)/2); + + const auto controller = Periphery::get_primary_controller_as(); + + handle_button(button_watcher[0], GenericButton::Left, offset_x, -1); + handle_button(button_watcher[1], GenericButton::Right, offset_x, 1); + handle_button(button_watcher[2], GenericButton::Up, offset_y, -1); + handle_button(button_watcher[3], GenericButton::Down, offset_y, 1); + + auto cursor = FontWriter::update(CenterPoint); + FontWriter::bios_font_writer.write(cursor, ModeStr, TVModeStr); + FontWriter::bios_font_writer.write(cursor, FormularStr); + FontWriter::bios_font_writer.write(cursor, OffsetStr, offset_x, offset_y); + + PSYQ::set_offset(offset_x, offset_y); + } static void setup() { Shared::back_menu.reset(); + + for(auto& button : button_watcher) { + button.setup(); + } + + update = update_enter_state; + offset_x = 0; + offset_y = 0; } static bool update_or_exit() { @@ -19,8 +142,7 @@ namespace ScreenCenter { return true; } - auto cursor = FontWriter::update(Make::PositionI16(8, 8)); - FontWriter::bios_font_writer.write(cursor, "NOTHING TO SEE HERE", GPU::Color24::Red()); + update(); return false; }