#include "../include/asset_mgr.hpp" #include "include/font_writer.hpp" #include "include/menu.hpp" #include "include/paco.hpp" #include "Overlay/Overlays.hpp" #include #include //#include #include #include #include using namespace JabyEngine; using DigitalButton = Periphery::GenericController::Button; struct XAPlayer { static constexpr auto MaxChannels = 2; uint8_t channel; static XAPlayer create() { return XAPlayer{0}; } void play() { this->channel = 0; Assets::XAAudio::play_fox(); } void stop() { CDXA::stop(); } void change_channel(int8_t step) { this->channel = static_cast((this->channel + step))%MaxChannels; CDXA::set_channel(this->channel); } void push() { CDXA::push_play(); } void pop() { CDXA::pop_play(); } }; struct StateChange { void (*asset_load)(); void (*main)(); static constexpr StateChange empty() { return StateChange{.asset_load = nullptr, .main = nullptr}; } void clear() { this->asset_load = nullptr; this->main = nullptr; } bool contains_state() const { return this->main; } auto operator<=>(const StateChange&) const = default; }; static const Menu::SimpleMenu::Entry MenuEntries[] = { {"Controller Test"}, {"GPU Test"}, {"GTE Test"}, {"Font Cycler"}, {"Screen Center"}, {"BIOS Information"} }; static const auto doener_fish = Make::SPRT( Make::AreaI16(Make::PositionI16(8, GPU::Display::Height - Assets::Main::DoenerFishInfo.size.height), Assets::Main::DoenerFishInfo.size), // v this needs to be nicer! Has to be Make::OffsetPageWithClut(Assets::Main::DoenerFishInfo.tim.get_page_offset_clut4(), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position())), GPU::Color24::Grey() ); static XAPlayer xa = XAPlayer::create(); static object::Paco paco; static Menu::SimpleMenu menu; static StateChange state_changer; static StateChange old_state_changer; namespace Shared { Menu::BackMenu back_menu; JabyEngine::GPU::POLY_G4 background = Make::POLY_G4( Make::AreaI16(0, 0, GPU::Display::Width, GPU::Display::Height), {GPU::Color24::Red(0xA0), GPU::Color24::Green(0xA0), GPU::Color24::Blue(0xA0), GPU::Color24::Black()} ); bool load_test = false; } static void setup() { // Use this size for the doener fish state? // doener_fish.set_rect_size_fast(Make::SizeI16(64, 32)); const auto& controller = Periphery::get_primary_controller_as(); // With this approach we can default load_test to true for debugging reasons if(controller.button.is_down(DigitalButton::R2) && controller.button.is_down(DigitalButton::L2)) { Shared::load_test = true; } Assets::Main::load(); FontWriter::setup(); paco.setup(); Shared::back_menu.setup(&FontWriter::bios_font_writer); menu.setup([](uint32_t selection) { switch(selection) { case 0: state_changer.asset_load = Assets::Overlay::load_controller_test; state_changer.main = ControllerTest::main; break; case 1: state_changer.asset_load = Assets::Overlay::load_gpu_test; state_changer.main = GPUTest::main; break; case 2: state_changer.asset_load = Assets::Overlay::load_gte_test; state_changer.main = GTETest::main; break; case 3: state_changer.asset_load = Assets::Overlay::load_font_cycler; state_changer.main = FontCycler::main; break; case 4: state_changer.asset_load = Assets::Overlay::load_screen_center; state_changer.main = ScreenCenter::main; break; case 5: state_changer.asset_load = Assets::Overlay::load_bios_info; state_changer.main = BIOSInfo::main; break; } },MenuEntries); // TODO: CDDA? // const auto [first_track, last_track] = CDDA::get_tracks(); // CDDA::play(first_track); xa.play(); } namespace NormalScene { static void update() { static const char Title[] = ">> Pool Box <<"; static const char Version[] = "Ver. 0.8.5"; static constexpr auto TitleLength = DefaultFont::Info.estimate_str_render_length(Title); static constexpr auto VersionLength = DefaultFont::Info.estimate_str_render_length(Version); Periphery::query_controller(); const auto& controller = Periphery::get_primary_controller_as(); if(controller.button.went_down(DigitalButton::R1)) { xa.change_channel(1); } if(controller.button.went_down(DigitalButton::L1)) { xa.change_channel(-1); } auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width-TitleLength)/2, 16)); paco.update(); FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Yellow(0xD0), &FontWriter::wiggle); FontWriter::new_font_writer.write(cursor.change_position(Make::PositionI16((GPU::Display::Width-VersionLength)/2, 16 + DefaultFont::Info.get_kern_size().height)), Version, GPU::Color24::Green(0xD0), &FontWriter::wiggle); menu.update(FontWriter::bios_font_writer, cursor, Make::PositionI16(8, 64)); if(Shared::load_test) { // Force state change if we are in the load_test state state_changer.asset_load = Assets::Overlay::load_gpu_test; state_changer.main = GPUTest::main; } } static void render() { GPU::render(Shared::background); FontWriter::new_font_writer.render(); FontWriter::bios_font_writer.render(); paco.render(); GPU::render(doener_fish); } static void run() { update(); GPU::swap_buffers_vsync(1); render(); } } namespace LoadingScene { static void update() { static const char Title[] = "Loading..."; static constexpr auto TitleLength = (sizeof(Title) - 1)*DefaultFont::Info.get_font_size().width; auto cursor = FontWriter::update(JabyEngine::Make::PositionI16((GPU::Display::Width-TitleLength)/2, (GPU::Display::Height-16)/2)); FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Blue(0xD0)); } static void render() { FontWriter::new_font_writer.render(); } static void run() { if(Shared::load_test || old_state_changer != state_changer) { update(); GPU::swap_buffers_vsync(1); render(); GPU::swap_buffers_vsync(1); xa.push(); state_changer.asset_load(); old_state_changer = state_changer; xa.pop(); } state_changer.main(); state_changer.clear(); } } void main() { Periphery::query_controller(); setup(); while(true) { if(state_changer.contains_state()) { LoadingScene::run(); } else { NormalScene::run(); } } }