Added volume sliders

This commit is contained in:
KiritoDv
2023-09-18 03:39:47 -06:00
parent 0a44ed6fa5
commit 48258f6a18
18 changed files with 999 additions and 165 deletions
+38 -38
View File
@@ -1,118 +1,118 @@
#pragma once
#include "align_asset_macro.h"
#define dgBank00 "__OTR__sound/banks/us/00_bank"
#define dgBank00 "__OTR__sound/banks/00_bank"
static const ALIGN_ASSET(2) char gBank00[] = dgBank00;
#define dgBank01 "__OTR__sound/banks/us/01_bank"
#define dgBank01 "__OTR__sound/banks/01_bank"
static const ALIGN_ASSET(2) char gBank01[] = dgBank01;
#define dgBank02 "__OTR__sound/banks/us/02_bank"
#define dgBank02 "__OTR__sound/banks/02_bank"
static const ALIGN_ASSET(2) char gBank02[] = dgBank02;
#define dgBank03 "__OTR__sound/banks/us/03_bank"
#define dgBank03 "__OTR__sound/banks/03_bank"
static const ALIGN_ASSET(2) char gBank03[] = dgBank03;
#define dgBank04 "__OTR__sound/banks/us/04_bank"
#define dgBank04 "__OTR__sound/banks/04_bank"
static const ALIGN_ASSET(2) char gBank04[] = dgBank04;
#define dgBank05 "__OTR__sound/banks/us/05_bank"
#define dgBank05 "__OTR__sound/banks/05_bank"
static const ALIGN_ASSET(2) char gBank05[] = dgBank05;
#define dgBank06 "__OTR__sound/banks/us/06_bank"
#define dgBank06 "__OTR__sound/banks/06_bank"
static const ALIGN_ASSET(2) char gBank06[] = dgBank06;
#define dgBank07 "__OTR__sound/banks/us/07_bank"
#define dgBank07 "__OTR__sound/banks/07_bank"
static const ALIGN_ASSET(2) char gBank07[] = dgBank07;
#define dgBank08 "__OTR__sound/banks/us/08_bank"
#define dgBank08 "__OTR__sound/banks/08_bank"
static const ALIGN_ASSET(2) char gBank08[] = dgBank08;
#define dgBank09 "__OTR__sound/banks/us/09_bank"
#define dgBank09 "__OTR__sound/banks/09_bank"
static const ALIGN_ASSET(2) char gBank09[] = dgBank09;
#define dgBank0A "__OTR__sound/banks/us/0A_bank"
#define dgBank0A "__OTR__sound/banks/0A_bank"
static const ALIGN_ASSET(2) char gBank0A[] = dgBank0A;
#define dgBank0B "__OTR__sound/banks/us/0B_bank"
#define dgBank0B "__OTR__sound/banks/0B_bank"
static const ALIGN_ASSET(2) char gBank0B[] = dgBank0B;
#define dgBank0C "__OTR__sound/banks/us/0C_bank"
#define dgBank0C "__OTR__sound/banks/0C_bank"
static const ALIGN_ASSET(2) char gBank0C[] = dgBank0C;
#define dgBank0D "__OTR__sound/banks/us/0D_bank"
#define dgBank0D "__OTR__sound/banks/0D_bank"
static const ALIGN_ASSET(2) char gBank0D[] = dgBank0D;
#define dgBank0E "__OTR__sound/banks/us/0E_bank"
#define dgBank0E "__OTR__sound/banks/0E_bank"
static const ALIGN_ASSET(2) char gBank0E[] = dgBank0E;
#define dgBank0F "__OTR__sound/banks/us/0F_bank"
#define dgBank0F "__OTR__sound/banks/0F_bank"
static const ALIGN_ASSET(2) char gBank0F[] = dgBank0F;
#define dgBank10 "__OTR__sound/banks/us/10_bank"
#define dgBank10 "__OTR__sound/banks/10_bank"
static const ALIGN_ASSET(2) char gBank10[] = dgBank10;
#define dgBank11 "__OTR__sound/banks/us/11_bank"
#define dgBank11 "__OTR__sound/banks/11_bank"
static const ALIGN_ASSET(2) char gBank11[] = dgBank11;
#define dgBank12 "__OTR__sound/banks/us/12_bank"
#define dgBank12 "__OTR__sound/banks/12_bank"
static const ALIGN_ASSET(2) char gBank12[] = dgBank12;
#define dgBank13 "__OTR__sound/banks/us/13_bank"
#define dgBank13 "__OTR__sound/banks/13_bank"
static const ALIGN_ASSET(2) char gBank13[] = dgBank13;
#define dgBank14 "__OTR__sound/banks/us/14_bank"
#define dgBank14 "__OTR__sound/banks/14_bank"
static const ALIGN_ASSET(2) char gBank14[] = dgBank14;
#define dgBank15 "__OTR__sound/banks/us/15_bank"
#define dgBank15 "__OTR__sound/banks/15_bank"
static const ALIGN_ASSET(2) char gBank15[] = dgBank15;
#define dgBank16 "__OTR__sound/banks/us/16_bank"
#define dgBank16 "__OTR__sound/banks/16_bank"
static const ALIGN_ASSET(2) char gBank16[] = dgBank16;
#define dgBank17 "__OTR__sound/banks/us/17_bank"
#define dgBank17 "__OTR__sound/banks/17_bank"
static const ALIGN_ASSET(2) char gBank17[] = dgBank17;
#define dgBank18 "__OTR__sound/banks/us/18_bank"
#define dgBank18 "__OTR__sound/banks/18_bank"
static const ALIGN_ASSET(2) char gBank18[] = dgBank18;
#define dgBank19 "__OTR__sound/banks/us/19_bank"
#define dgBank19 "__OTR__sound/banks/19_bank"
static const ALIGN_ASSET(2) char gBank19[] = dgBank19;
#define dgBank1A "__OTR__sound/banks/us/1A_bank"
#define dgBank1A "__OTR__sound/banks/1A_bank"
static const ALIGN_ASSET(2) char gBank1A[] = dgBank1A;
#define dgBank1B "__OTR__sound/banks/us/1B_bank"
#define dgBank1B "__OTR__sound/banks/1B_bank"
static const ALIGN_ASSET(2) char gBank1B[] = dgBank1B;
#define dgBank1C "__OTR__sound/banks/us/1C_bank"
#define dgBank1C "__OTR__sound/banks/1C_bank"
static const ALIGN_ASSET(2) char gBank1C[] = dgBank1C;
#define dgBank1D "__OTR__sound/banks/us/1D_bank"
#define dgBank1D "__OTR__sound/banks/1D_bank"
static const ALIGN_ASSET(2) char gBank1D[] = dgBank1D;
#define dgBank1E "__OTR__sound/banks/us/1E_bank"
#define dgBank1E "__OTR__sound/banks/1E_bank"
static const ALIGN_ASSET(2) char gBank1E[] = dgBank1E;
#define dgBank1F "__OTR__sound/banks/us/1F_bank"
#define dgBank1F "__OTR__sound/banks/1F_bank"
static const ALIGN_ASSET(2) char gBank1F[] = dgBank1F;
#define dgBank20 "__OTR__sound/banks/us/20_bank"
#define dgBank20 "__OTR__sound/banks/20_bank"
static const ALIGN_ASSET(2) char gBank20[] = dgBank20;
#define dgBank21 "__OTR__sound/banks/us/21_bank"
#define dgBank21 "__OTR__sound/banks/21_bank"
static const ALIGN_ASSET(2) char gBank21[] = dgBank21;
#define dgBank22 "__OTR__sound/banks/us/22_bank"
#define dgBank22 "__OTR__sound/banks/22_bank"
static const ALIGN_ASSET(2) char gBank22[] = dgBank22;
#define dgBank23 "__OTR__sound/banks/us/23_bank"
#define dgBank23 "__OTR__sound/banks/23_bank"
static const ALIGN_ASSET(2) char gBank23[] = dgBank23;
#define dgBank24 "__OTR__sound/banks/us/24_bank"
#define dgBank24 "__OTR__sound/banks/24_bank"
static const ALIGN_ASSET(2) char gBank24[] = dgBank24;
#define dgBank25 "__OTR__sound/banks/us/25_bank"
#define dgBank25 "__OTR__sound/banks/25_bank"
static const ALIGN_ASSET(2) char gBank25[] = dgBank25;
static const char* gBankTable[] = {
+35 -35
View File
@@ -1,109 +1,109 @@
#pragma once
#include "align_asset_macro.h"
#define dgSequence00 "__OTR__sound/sequences/us/00_sound_player"
#define dgSequence00 "__OTR__sound/sequences/00_sound_player"
static const ALIGN_ASSET(2) char gSequence00[] = dgSequence00;
#define dgSequence01 "__OTR__sound/sequences/us/01_cutscene_collect_star"
#define dgSequence01 "__OTR__sound/sequences/01_cutscene_collect_star"
static const ALIGN_ASSET(2) char gSequence01[] = dgSequence01;
#define dgSequence02 "__OTR__sound/sequences/us/02_menu_title_screen"
#define dgSequence02 "__OTR__sound/sequences/02_menu_title_screen"
static const ALIGN_ASSET(2) char gSequence02[] = dgSequence02;
#define dgSequence03 "__OTR__sound/sequences/us/03_level_grass"
#define dgSequence03 "__OTR__sound/sequences/03_level_grass"
static const ALIGN_ASSET(2) char gSequence03[] = dgSequence03;
#define dgSequence04 "__OTR__sound/sequences/us/04_level_inside_castle"
#define dgSequence04 "__OTR__sound/sequences/04_level_inside_castle"
static const ALIGN_ASSET(2) char gSequence04[] = dgSequence04;
#define dgSequence05 "__OTR__sound/sequences/us/05_level_water"
#define dgSequence05 "__OTR__sound/sequences/05_level_water"
static const ALIGN_ASSET(2) char gSequence05[] = dgSequence05;
#define dgSequence06 "__OTR__sound/sequences/us/06_level_hot"
#define dgSequence06 "__OTR__sound/sequences/06_level_hot"
static const ALIGN_ASSET(2) char gSequence06[] = dgSequence06;
#define dgSequence07 "__OTR__sound/sequences/us/07_level_boss_koopa"
#define dgSequence07 "__OTR__sound/sequences/07_level_boss_koopa"
static const ALIGN_ASSET(2) char gSequence07[] = dgSequence07;
#define dgSequence08 "__OTR__sound/sequences/us/08_level_snow"
#define dgSequence08 "__OTR__sound/sequences/08_level_snow"
static const ALIGN_ASSET(2) char gSequence08[] = dgSequence08;
#define dgSequence09 "__OTR__sound/sequences/us/09_level_slide"
#define dgSequence09 "__OTR__sound/sequences/09_level_slide"
static const ALIGN_ASSET(2) char gSequence09[] = dgSequence09;
#define dgSequence0A "__OTR__sound/sequences/us/0A_level_spooky"
#define dgSequence0A "__OTR__sound/sequences/0A_level_spooky"
static const ALIGN_ASSET(2) char gSequence0A[] = dgSequence0A;
#define dgSequence0B "__OTR__sound/sequences/us/0B_event_piranha_plant"
#define dgSequence0B "__OTR__sound/sequences/0B_event_piranha_plant"
static const ALIGN_ASSET(2) char gSequence0B[] = dgSequence0B;
#define dgSequence0C "__OTR__sound/sequences/us/0C_level_underground"
#define dgSequence0C "__OTR__sound/sequences/0C_level_underground"
static const ALIGN_ASSET(2) char gSequence0C[] = dgSequence0C;
#define dgSequence0D "__OTR__sound/sequences/us/0D_menu_star_select"
#define dgSequence0D "__OTR__sound/sequences/0D_menu_star_select"
static const ALIGN_ASSET(2) char gSequence0D[] = dgSequence0D;
#define dgSequence0E "__OTR__sound/sequences/us/0E_event_powerup"
#define dgSequence0E "__OTR__sound/sequences/0E_event_powerup"
static const ALIGN_ASSET(2) char gSequence0E[] = dgSequence0E;
#define dgSequence0F "__OTR__sound/sequences/us/0F_event_metal_cap"
#define dgSequence0F "__OTR__sound/sequences/0F_event_metal_cap"
static const ALIGN_ASSET(2) char gSequence0F[] = dgSequence0F;
#define dgSequence10 "__OTR__sound/sequences/us/10_event_koopa_message"
#define dgSequence10 "__OTR__sound/sequences/10_event_koopa_message"
static const ALIGN_ASSET(2) char gSequence10[] = dgSequence10;
#define dgSequence11 "__OTR__sound/sequences/us/11_level_koopa_road"
#define dgSequence11 "__OTR__sound/sequences/11_level_koopa_road"
static const ALIGN_ASSET(2) char gSequence11[] = dgSequence11;
#define dgSequence12 "__OTR__sound/sequences/us/12_event_high_score"
#define dgSequence12 "__OTR__sound/sequences/12_event_high_score"
static const ALIGN_ASSET(2) char gSequence12[] = dgSequence12;
#define dgSequence13 "__OTR__sound/sequences/us/13_event_merry_go_round"
#define dgSequence13 "__OTR__sound/sequences/13_event_merry_go_round"
static const ALIGN_ASSET(2) char gSequence13[] = dgSequence13;
#define dgSequence14 "__OTR__sound/sequences/us/14_event_race"
#define dgSequence14 "__OTR__sound/sequences/14_event_race"
static const ALIGN_ASSET(2) char gSequence14[] = dgSequence14;
#define dgSequence15 "__OTR__sound/sequences/us/15_cutscene_star_spawn"
#define dgSequence15 "__OTR__sound/sequences/15_cutscene_star_spawn"
static const ALIGN_ASSET(2) char gSequence15[] = dgSequence15;
#define dgSequence16 "__OTR__sound/sequences/us/16_event_boss"
#define dgSequence16 "__OTR__sound/sequences/16_event_boss"
static const ALIGN_ASSET(2) char gSequence16[] = dgSequence16;
#define dgSequence17 "__OTR__sound/sequences/us/17_cutscene_collect_key"
#define dgSequence17 "__OTR__sound/sequences/17_cutscene_collect_key"
static const ALIGN_ASSET(2) char gSequence17[] = dgSequence17;
#define dgSequence18 "__OTR__sound/sequences/us/18_event_endless_stairs"
#define dgSequence18 "__OTR__sound/sequences/18_event_endless_stairs"
static const ALIGN_ASSET(2) char gSequence18[] = dgSequence18;
#define dgSequence19 "__OTR__sound/sequences/us/19_level_boss_koopa_final"
#define dgSequence19 "__OTR__sound/sequences/19_level_boss_koopa_final"
static const ALIGN_ASSET(2) char gSequence19[] = dgSequence19;
#define dgSequence1A "__OTR__sound/sequences/us/1A_cutscene_credits"
#define dgSequence1A "__OTR__sound/sequences/1A_cutscene_credits"
static const ALIGN_ASSET(2) char gSequence1A[] = dgSequence1A;
#define dgSequence1B "__OTR__sound/sequences/us/1B_event_solve_puzzle"
#define dgSequence1B "__OTR__sound/sequences/1B_event_solve_puzzle"
static const ALIGN_ASSET(2) char gSequence1B[] = dgSequence1B;
#define dgSequence1C "__OTR__sound/sequences/us/1C_event_toad_message"
#define dgSequence1C "__OTR__sound/sequences/1C_event_toad_message"
static const ALIGN_ASSET(2) char gSequence1C[] = dgSequence1C;
#define dgSequence1D "__OTR__sound/sequences/us/1D_event_peach_message"
#define dgSequence1D "__OTR__sound/sequences/1D_event_peach_message"
static const ALIGN_ASSET(2) char gSequence1D[] = dgSequence1D;
#define dgSequence1E "__OTR__sound/sequences/us/1E_cutscene_intro"
#define dgSequence1E "__OTR__sound/sequences/1E_cutscene_intro"
static const ALIGN_ASSET(2) char gSequence1E[] = dgSequence1E;
#define dgSequence1F "__OTR__sound/sequences/us/1F_cutscene_victory"
#define dgSequence1F "__OTR__sound/sequences/1F_cutscene_victory"
static const ALIGN_ASSET(2) char gSequence1F[] = dgSequence1F;
#define dgSequence20 "__OTR__sound/sequences/us/20_cutscene_ending"
#define dgSequence20 "__OTR__sound/sequences/20_cutscene_ending"
static const ALIGN_ASSET(2) char gSequence20[] = dgSequence20;
#define dgSequence21 "__OTR__sound/sequences/us/21_menu_file_select"
#define dgSequence21 "__OTR__sound/sequences/21_menu_file_select"
static const ALIGN_ASSET(2) char gSequence21[] = dgSequence21;
#define dgSequence22 "__OTR__sound/sequences/us/22_cutscene_lakitu"
#define dgSequence22 "__OTR__sound/sequences/22_cutscene_lakitu"
static const ALIGN_ASSET(2) char gSequence22[] = dgSequence22;
static const char* gSequenceTable[] = {
+2 -2
View File
@@ -63,7 +63,7 @@ static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) {
f32 panFromChannel;
s32 i;
channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume;
channelVolume = (seqChannel->volume * (seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume)) * seqChannel->seqPlayer->gameVolume;
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) {
channelVolume *= seqChannel->seqPlayer->muteVolumeScale;
}
@@ -73,7 +73,7 @@ static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) {
for (i = 0; i < 4; i++) {
struct SequenceChannelLayer *layer = seqChannel->layers[i];
if (layer != NULL && layer->enabled && layer->note != NULL) {
if (layer != NULL && layer->enabled && layer->note != NULL || (layer != NULL && seqChannel->seqPlayer->recalculateVolume)) {
layer->noteFreqScale = layer->freqScale * seqChannel->freqScale;
layer->noteVelocity = layer->velocitySquare * channelVolume;
layer->notePan = (layer->pan * panLayerWeight) + panFromChannel;
+5
View File
@@ -2575,6 +2575,11 @@ void audio_set_sound_mode(u8 soundMode) {
gSoundMode = soundMode;
}
void audio_set_player_volume(u8 player, f32 volume) {
gSequencePlayers[player].gameVolume = volume;
gSequencePlayers[player].recalculateVolume = TRUE;
}
#if defined(VERSION_JP) || defined(VERSION_US)
void unused_80321460(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s32 arg3) {
}
+1
View File
@@ -60,6 +60,7 @@ void play_race_fanfare(void);
void play_toads_jingle(void);
void sound_reset(u8 presetId);
void audio_set_sound_mode(u8 arg0);
void audio_set_player_volume(u8 player, f32 volume);
void create_next_audio_buffer(s16 *samples, u32 num_samples);
void audio_init(void); // in load.c
+1 -2
View File
@@ -259,9 +259,7 @@ struct SequencePlayer {
/*0x000, 0x000*/ u8 muted : 1;
/*0x000, 0x000*/ u8 seqDmaInProgress : 1;
/*0x000, 0x000*/ u8 bankDmaInProgress : 1;
#if defined(VERSION_EU) || defined(VERSION_SH)
/* 0x000*/ u8 recalculateVolume : 1;
#endif
#ifdef VERSION_SH
/* 0x000*/ u8 unkSh: 1;
#endif
@@ -324,6 +322,7 @@ struct SequencePlayer {
#endif
/*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr;
/*0x13C, 0x144*/ ssize_t bankDmaRemaining;
f32 gameVolume;
}; // size = 0x140, 0x148 on EU, 0x14C on SH
struct AdsrSettings {
+5
View File
@@ -551,6 +551,11 @@ void audio_init() {
gSequenceCount = sizeof(gSequenceTable) / sizeof(gSequenceTable[0]);
init_sequence_players();
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
// Should probably contain the sizes of the data banks, but those aren't
// easily accessible from here.
eu_stubbed_printf_0("---------- Init Completed. ------------\n");
+1 -1
View File
@@ -444,7 +444,7 @@ void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state) {
}
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state) {
int16_t tmp[16];
int16_t tmp[32];
int16_t *in_initial = BUF_S16(rspa.in);
int16_t *in = in_initial;
int16_t *out = BUF_S16(rspa.out);
+4
View File
@@ -1490,6 +1490,10 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverb
if (note->targetVolRight == 0) {
note->targetVolRight++;
}
float master_vol = CVarGetFloat("gGameMasterVolume", 1.0f);
note->targetVolLeft *= master_vol;
note->targetVolRight *= master_vol;
if (note->reverbVol != reverbVol) {
note->reverbVol = reverbVol;
note->reverbVolShifted = reverbVol << 8;
+94 -14
View File
@@ -1,5 +1,5 @@
#include "Engine.h"
#include "ImguiUI.h"
#include "ui/ImguiUI.h"
#include "port/importer/AnimationFactory.h"
#include "port/importer/AudioBankFactory.h"
#include "port/importer/AudioSampleFactory.h"
@@ -7,12 +7,15 @@
#include "audio/internal.h"
#include "banks_table.h"
#include "sequences_table.h"
#include "audio/GameAudio.h"
#include "ZAPDUtils/Utils/StringHelper.h"
#include <iostream>
#include <Fast3D/gfx_pc.h>
#include <Fast3D/gfx_rendering_api.h>
extern "C" {
#include "audio/external.h"
}
GameEngine* GameEngine::Instance;
GameEngine::GameEngine(){
@@ -42,6 +45,7 @@ GameEngine::GameEngine(){
this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Bank, "Bank", std::make_shared<CubeOS::AudioBankFactory>());
this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Sample, "Sample", std::make_shared<CubeOS::AudioSampleFactory>());
this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Sequence, "Sequence", std::make_shared<CubeOS::AudioSequenceFactory>());
GameEngine::AudioInit();
}
void GameEngine::Create(){
@@ -49,6 +53,11 @@ void GameEngine::Create(){
GameUI::SetupGuiElements();
}
void GameEngine::Destroy(){
GameEngine::AudioExit();
this->context = nullptr;
}
void GameEngine::StartFrame() const{
this->context->GetWindow()->StartFrame();
}
@@ -62,26 +71,97 @@ void GameEngine::ProcessFrame(void (*run_one_game_iter)()) const {
this->context->GetWindow()->MainLoop(run_one_game_iter);
}
extern "C" uint32_t GameEngine_GetSampleRate() {
auto audio = LUS::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (audio == nullptr) {
return 0;
}
// Audio
if (!audio->IsInitialized()) {
return 0;
}
void GameEngine::HandleAudioThread(){
while (audio.running) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing && audio.running) {
audio.cv_to_thread.wait(Lock);
}
return audio->GetSampleRate();
if (!audio.running) {
break;
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
int samples_left = AudioPlayerBuffered();
u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
}
AudioPlayerPlayFrame((u8 *) audio_buffer, 2 * num_audio_samples * 4);
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}
void GameEngine::StartAudioFrame(){
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.processing = true;
}
audio.cv_to_thread.notify_one();
}
void GameEngine::EndAudioFrame(){
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) {
audio.cv_from_thread.wait(Lock);
}
}
}
void GameEngine::AudioInit() {
LUS::Context::GetInstance()->GetResourceManager()->LoadDirectory("sound");
if (!audio.running) {
audio.running = true;
audio.thread = std::thread(GameEngine::HandleAudioThread);
}
}
void GameEngine::AudioExit() {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.running = false;
}
audio.cv_to_thread.notify_all();
// Wait until the audio thread quit
audio.thread.join();
}
extern "C" uint32_t GameEngine_GetSampleRate() {
auto player = LUS::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (player == nullptr) {
return 0;
}
if (!player->IsInitialized()) {
return 0;
}
return player->GetSampleRate();
}
// End
extern "C" float GameEngine_GetAspectRatio() {
return gfx_current_dimensions.aspect_ratio;
}
extern "C" CtlEntry* GameEngine_LoadBank(uint8_t bankId) {
auto engine = GameEngine::Instance;
if(bankId > (sizeof(gBankTable) / sizeof(gBankTable[0]))){
if(bankId > (sizeof(gBankTable) / sizeof(gBankTable[0])) - 1){
return nullptr;
}
if(engine->banks.contains(bankId)){
@@ -107,7 +187,7 @@ extern "C" void GameEngine_UnloadBank(uint8_t bankId) {
extern "C" AudioSequenceData* GameEngine_LoadSequence(uint8_t seqId) {
auto engine = GameEngine::Instance;
if(seqId > (sizeof(gSequenceTable) / sizeof(gSequenceTable[0]))){
if(seqId > (sizeof(gSequenceTable) / sizeof(gSequenceTable[0])) - 1){
return nullptr;
}
if(engine->sequences.contains(seqId)){
+7
View File
@@ -26,6 +26,13 @@ class GameEngine {
void StartFrame() const;
static void RunCommands(Gfx* Commands);
void ProcessFrame(void (*run_one_game_iter)()) const;
static void HandleAudioThread();
static void StartAudioFrame();
static void EndAudioFrame();
static void AudioInit();
static void AudioExit();
void Destroy();
};
#else
uint32_t GameEngine_GetSampleRate();
+3 -15
View File
@@ -8,8 +8,6 @@ extern "C" {
#include "game/game_init.h"
}
bool sAudioEnabled = true;
void alloc_pool() {
static u64 pool[1024 * 1024 * 4];
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
@@ -22,20 +20,10 @@ void exec_display_list(SPTask *spTask) {
}
void push_frame() {
GameEngine::StartAudioFrame();
GameEngine::Instance->StartFrame();
thread5_iteration();
if(sAudioEnabled) {
int samples_left = AudioPlayerBuffered();
u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
}
AudioPlayerPlayFrame((u8 *) audio_buffer, 2 * num_audio_samples * 4);
}
GameEngine::EndAudioFrame();
}
#ifdef _WIN32
@@ -47,8 +35,8 @@ int main(){
alloc_pool();
audio_init();
sound_init();
thread5_game_loop();
GameEngine::Instance->ProcessFrame(push_frame);
GameEngine::Instance->Destroy();
return 0;
}
-58
View File
@@ -1,58 +0,0 @@
#include "ImguiUI.h"
#include <spdlog/spdlog.h>
#include <ImGui/imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <ImGui/imgui_internal.h>
#include <libultraship/libultraship.h>
#include <Fast3D/gfx_pc.h>
namespace GameUI {
std::shared_ptr<GameMenuBar> mGameMenuBar;
std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
std::shared_ptr<LUS::GuiWindow> mStatsWindow;
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
void SetupGuiElements() {
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
mGameMenuBar = std::make_shared<GameMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(mGameMenuBar);
mStatsWindow = gui->GetGuiWindow("Stats");
if (mStatsWindow == nullptr) {
SPDLOG_ERROR("Could not find stats window");
}
mConsoleWindow = gui->GetGuiWindow("Console");
if (mConsoleWindow == nullptr) {
SPDLOG_ERROR("Could not find console window");
}
mInputEditorWindow = gui->GetGuiWindow("Input Editor");
if (mInputEditorWindow == nullptr) {
SPDLOG_ERROR("Could not find input editor window");
return;
}
}
void Destroy() {
mConsoleWindow = nullptr;
mStatsWindow = nullptr;
mInputEditorWindow = nullptr;
}
}
void GameMenuBar::DrawElement() {
if(ImGui::BeginMenuBar()){
if(ImGui::BeginMenu("Settings")){
if (GameUI::mInputEditorWindow) {
if (ImGui::Button("Controller Mapping", ImVec2 (-1.0f, 0.0f))) {
GameUI::mInputEditorWindow->ToggleVisibility();
}
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings();
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <thread>
#include <condition_variable>
static struct {
std::thread thread;
std::condition_variable cv_to_thread, cv_from_thread;
std::mutex mutex;
bool running;
bool processing;
} audio;
+102
View File
@@ -0,0 +1,102 @@
#include "ImguiUI.h"
#include "UIWidgets.h"
#include <spdlog/spdlog.h>
#include <ImGui/imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <ImGui/imgui_internal.h>
#include <libultraship/libultraship.h>
#include <Fast3D/gfx_pc.h>
extern "C" {
#include "audio/external.h"
}
namespace GameUI {
std::shared_ptr<GameMenuBar> mGameMenuBar;
std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
std::shared_ptr<LUS::GuiWindow> mStatsWindow;
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
void SetupGuiElements() {
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
mGameMenuBar = std::make_shared<GameMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(mGameMenuBar);
mStatsWindow = gui->GetGuiWindow("Stats");
if (mStatsWindow == nullptr) {
SPDLOG_ERROR("Could not find stats window");
}
mConsoleWindow = gui->GetGuiWindow("Console");
if (mConsoleWindow == nullptr) {
SPDLOG_ERROR("Could not find console window");
}
mInputEditorWindow = gui->GetGuiWindow("Input Editor");
if (mInputEditorWindow == nullptr) {
SPDLOG_ERROR("Could not find input editor window");
return;
}
}
void Destroy() {
mConsoleWindow = nullptr;
mStatsWindow = nullptr;
mInputEditorWindow = nullptr;
}
}
void GameMenuBar::DrawElement() {
if(ImGui::BeginMenuBar()){
if(ImGui::BeginMenu("Settings")){
if (ImGui::BeginMenu("Audio")) {
UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true);
if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
}
if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %d %%", "##Sound_Effect_Vol", "gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
}
if (UIWidgets::PaddedEnhancementSliderFloat("Environment Volume: %d %%", "##Environment_Vol", "gEnvironmentVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
}
static std::unordered_map<LUS::AudioBackend, const char*> audioBackendNames = {
{ LUS::AudioBackend::WASAPI, "Windows Audio Session API" },
{ LUS::AudioBackend::PULSE, "PulseAudio" },
{ LUS::AudioBackend::SDL, "SDL" },
};
ImGui::Text("Audio API (Needs reload)");
auto currentAudioBackend = LUS::Context::GetInstance()->GetAudio()->GetAudioBackend();
if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) {
for (uint8_t i = 0; i < LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) {
auto backend = LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i];
if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) {
LUS::Context::GetInstance()->GetAudio()->SetAudioBackend(backend);
}
}
ImGui::EndCombo();
}
if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
UIWidgets::ReEnableComponent("");
}
ImGui::EndMenu();
}
if (GameUI::mInputEditorWindow) {
if (ImGui::Button("Controller Mapping", ImVec2 (-1.0f, 0.0f))) {
GameUI::mInputEditorWindow->ToggleVisibility();
}
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings();
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
#pragma once
#include <string>
#include <vector>
#include <span>
#include <stdint.h>
#include <ImGui/imgui.h>
namespace UIWidgets {
struct TextFilters {
static int FilterNumbers(ImGuiInputTextCallbackData* data) {
if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) {
return 0;
}
return 1;
}
static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
return 0;
}
return 1;
}
};
// MARK: - Enums
enum class CheckboxGraphics {
Cross,
Checkmark,
None
};
constexpr float maxSliderWidth = 260.0f;
#ifdef __SWITCH__
constexpr float sliderButtonWidth = 42.0f;
#elif defined(__WIIU__)
constexpr float sliderButtonWidth = 60.0f;
#else
constexpr float sliderButtonWidth = 30.0f;
#endif
char* WrappedText(const char* text, unsigned int charactersPerLine = 60);
char* WrappedText(const std::string& text, unsigned int charactersPerLine);
void SetLastItemHoverText(const std::string& text);
void SetLastItemHoverText(const char* text);
void InsertHelpHoverText(const std::string& text);
void InsertHelpHoverText(const char* text);
void Tooltip(const char* text);
void Spacer(float height);
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f);
void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic);
void ReEnableComponent(const char* disabledTooltipText);
void DisableComponent(const float alpha);
bool EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
bool PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
bool EnhancementCombobox(const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
bool LabeledRightAlignedEnhancementCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
void PaddedText(const char* text, bool padTop = true, bool padBottom = true);
bool EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
bool PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
bool EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
bool PaddedEnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
bool EnhancementRadioButton(const char* text, const char* cvarName, int id);
bool DrawResetColorButton(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
bool DrawRandomizeColorButton(const char* cvarName, ImVec4* colors);
void DrawLockColorCheckbox(const char* cvarName);
void RainbowColor(const char* cvarName, ImVec4* colors);
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha);
bool EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha = false, bool TitleSameLine = false);
void DrawFlagArray32(const std::string& name, uint32_t& flags);
void DrawFlagArray16(const std::string& name, uint16_t& flags);
void DrawFlagArray8(const std::string& name, uint8_t& flags);
}