jabyengine/examples/PoolBox/application/src/application.cpp

302 lines
9.7 KiB
C++

#include "../include/asset_mgr.hpp"
#include "include/font_writer.hpp"
#include "include/menu.hpp"
#include "include/paco.hpp"
#include "Overlay/Overlays.hpp"
#include <FontWriter/fonts.hpp>
#include <FontWriter/font_writer.hpp>
#include <PSX/Audio/CDDA.hpp>
#include <PSX/Audio/CDXA.hpp>
#include <PSX/Periphery/periphery.hpp>
#include <stdio.hpp>
using namespace JabyEngine;
using DigitalButton = Periphery::GenericController::Button;
struct CDPlayer {
static constexpr auto MaxChannels = 2;
uint8_t channel;
bool is_xa;
static constexpr CDPlayer create() {
return CDPlayer{.channel = 0, .is_xa = true};
}
void play() {
if(this->is_xa) {
Assets::XAAudio::play_mix();
}
else {
const auto [first_track, last_track] = CDDA::get_tracks();
CDDA::play(first_track);
}
}
void stop() {
if(this->is_xa) {
CDXA::stop();
}
else {
CDDA::stop();
}
}
void change_channel(int8_t step) {
if(this->is_xa) {
this->channel = static_cast<uint8_t>((this->channel + step))%MaxChannels;
CDXA::set_channel(this->channel);
}
}
void change_audio() {
CDPlayer::stop();
this->is_xa = !this->is_xa;
CDPlayer::play();
}
void push() {
if(this->is_xa) {
CDXA::push_play();
}
else {
CDDA::push_play();
}
}
void pop() {
if(this->is_xa) {
CDXA::pop_play();
}
else {
CDDA::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 CDPlayer cd_player = CDPlayer::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));
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);
cd_player.play();
}
namespace NormalScene {
static void update() {
static const char Title[] = ">> Pool Box <<";
static const char Version[] = "Ver. 0.9.0";
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<JabyEngine::Periphery::GenericController>();
if(controller.is_connected()) {
if(controller.button.went_down(DigitalButton::SEL)) {
cd_player.change_audio();
}
if(controller.button.went_down(DigitalButton::R1)) {
cd_player.change_channel(1);
}
if(controller.button.went_down(DigitalButton::L1)) {
cd_player.change_channel(-1);
}
// Trigger load test
if(controller.button.is_down(DigitalButton::R2) && controller.button.is_down(DigitalButton::L2) && controller.button.is_down(DigitalButton::ST)) {
Shared::load_test = true;
}
}
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));
cursor.change_position(Make::PositionI16(doener_fish.position.x + doener_fish.size.width, GPU::Display::Height - 32));
FontWriter::bios_font_writer.write(cursor, "Audio:\n%s", cd_player.is_xa ? "CD-XA" : "CD-DA");
if(Shared::load_test) {
// Force state change if we are in the load_test state
state_changer.asset_load = Assets::Overlay::load_large_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 SimpleTimer<uint8_t> jaby_timer;
static uint8_t jaby_frame_offset;
static void update() {
jaby_timer.reset();
jaby_frame_offset = 0;
}
static void vsync_render() {
static constexpr auto StartPosition = Make::PositionI16(24, 64);
const auto load_font = Make::SPRT(
Make::AreaI16(StartPosition.move(Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0), Assets::Main::JabyLoader::FontFrame.size),
Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4().move(Assets::Main::JabyLoader::FontFrame.position.x, Assets::Main::JabyLoader::FontFrame.position.y), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())),
GPU::Color24::Grey()
);
auto jaby_sprt = Make::SPRT(
Make::AreaI16(StartPosition, Assets::Main::JabyLoader::JabyFrame.size),
Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4(), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())),
GPU::Color24::Grey()
);
if(jaby_timer.is_expired_for(500_ms)) {
jaby_frame_offset = jaby_frame_offset ? 0 : 32;
jaby_timer.reset();
}
jaby_sprt.tex_offset.add(jaby_frame_offset, 0);
GPU::swap_buffers();
GPU::render(jaby_sprt);
GPU::render(load_font);
jaby_sprt.position.move(Assets::Main::JabyLoader::FontFrame.size.width + Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0);
GPU::render(jaby_sprt);
}
static void run() {
if(Shared::load_test || old_state_changer != state_changer) {
GPU::set_vsync_callback(vsync_render);
cd_player.push();
state_changer.asset_load();
old_state_changer = state_changer;
cd_player.pop();
GPU::set_vsync_callback(nullptr);
}
state_changer.main();
state_changer.clear();
}
}
void main() {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
setup();
while(true) {
if(state_changer.contains_state()) {
LoadingScene::run();
}
else {
NormalScene::run();
}
}
}