302 lines
9.7 KiB
C++
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();
|
|
}
|
|
}
|
|
} |