refactored so that pc_main has the functions for waiting for a semaphore and whatnot

This commit is contained in:
KingOfSpadesJFK 2024-04-12 18:45:50 -07:00
parent edf5b4ffc1
commit 85d44fd641
5 changed files with 45 additions and 41 deletions

View File

@ -13,7 +13,7 @@
#include "seq_ids.h"
#include "dialog_ids.h"
#include "level_table.h"
#include "pc/thread.h"
#include "pc/pc_main.h"
#ifdef VERSION_EU
#define EU_FLOAT(x) x ## f
@ -776,13 +776,6 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) {
sGameLoopTicked = 0;
}
// If the game thread is resetting the sound, don't process any audio commands
pcthread_mutex_lock(&pcthread_game_mutex); bool reseting_sound = pcthread_game_reset_sound; pcthread_mutex_unlock(&pcthread_game_mutex);
if (reseting_sound) {
printf("Audio thread: Dropped 1 frame\n");
return;
}
s32 writtenCmds;
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
@ -2358,9 +2351,8 @@ void sound_reset(u8 presetId) {
}
#endif
// Wait for audio thread to finish rendering
pcthread_mutex_lock(&pcthread_game_mutex); pcthread_game_reset_sound = true; pcthread_mutex_unlock(&pcthread_game_mutex);
pcthread_mutex_lock(&pcthread_audio_mutex); bool rendering = pcthread_audio_rendering; pcthread_mutex_unlock(&pcthread_audio_mutex);
if (rendering) pcthread_semaphore_wait(&pcthread_audio_sema);
pc_wait_for_audio();
pc_request_gameloop_wait();
sGameLoopTicked = 0;
disable_all_sequence_players();

View File

@ -69,6 +69,7 @@ sem_t pcthread_audio_sema;
pthread_mutex_t pcthread_game_mutex = PTHREAD_MUTEX_INITIALIZER;
bool pcthread_game_loop_iterating = false;
bool pcthread_game_reset_sound = false;
bool pcthread_wait_for_gameloop = false;
sem_t pcthread_game_sema;
extern void gfx_run(Gfx *commands);
@ -84,6 +85,28 @@ void dispatch_audio_sptask(struct SPTask *spTask) {
void set_vblank_handler(s32 index, struct VblankHandler *handler, OSMesgQueue *queue, OSMesg *msg) {
}
// Send a request for non-game threads to wait for the game thread to finish
void pc_request_gameloop_wait(void) {
pcthread_mutex_lock(&pcthread_game_mutex); pcthread_wait_for_gameloop = true; pcthread_mutex_unlock(&pcthread_game_mutex);
}
// Wait for the audio thread to finish rendering audio
void pc_wait_for_audio(void) {
pcthread_semaphore_wait(&pcthread_audio_sema);
}
// Check if the audio thread is currently rendering audio
bool pc_check_audio_rendering(void) {
pcthread_mutex_lock(&pcthread_audio_mutex); bool rendering = pcthread_audio_rendering; pcthread_mutex_unlock(&pcthread_audio_mutex);
return rendering;
}
// Check if the game thread should finish before continuing
bool pc_check_gameloop_wait(void) {
pcthread_mutex_lock(&pcthread_game_mutex); bool waiting = pcthread_wait_for_gameloop; pcthread_mutex_unlock(&pcthread_game_mutex);
return waiting;
}
static bool inited = false;
#include "game/display.h" // for gGlobalTimer
@ -100,19 +123,6 @@ void send_display_list(struct SPTask *spTask) {
#define SAMPLES_LOW 528
#endif
void lock_game_loop(bool unlock) {
pcthread_mutex_lock(&pcthread_game_mutex);
pcthread_game_loop_iterating = unlock;
pcthread_mutex_unlock(&pcthread_game_mutex);
}
bool game_loop_locked() {
pcthread_mutex_lock(&pcthread_game_mutex);
bool locked = pcthread_game_loop_iterating;
pcthread_mutex_unlock(&pcthread_game_mutex);
return locked;
}
void produce_one_frame(void) {
gfx_start_frame();
@ -120,9 +130,9 @@ void produce_one_frame(void) {
// Post the game thread semaphore if the game requested a sound reset
pcthread_mutex_lock(&pcthread_game_mutex);
if (pcthread_game_reset_sound) {
if (pcthread_wait_for_gameloop) {
pcthread_semaphore_post(&pcthread_game_sema);
pcthread_game_reset_sound = false;
pcthread_wait_for_gameloop = false;
}
pcthread_mutex_unlock(&pcthread_game_mutex);
@ -156,10 +166,14 @@ void* audio_thread() {
}
u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/
pcthread_mutex_lock(&pcthread_audio_mutex); pcthread_audio_rendering = true; pcthread_mutex_unlock(&pcthread_audio_mutex);
create_next_audio_buffer(audio_buffer, num_audio_samples);
pcthread_semaphore_post(&pcthread_audio_sema);
pcthread_mutex_lock(&pcthread_audio_mutex); pcthread_audio_rendering = false; pcthread_mutex_unlock(&pcthread_audio_mutex);
if (!pc_check_gameloop_wait()) {
pcthread_mutex_lock(&pcthread_audio_mutex); pcthread_audio_rendering = true; pcthread_mutex_unlock(&pcthread_audio_mutex);
create_next_audio_buffer(audio_buffer, num_audio_samples);
pcthread_semaphore_post(&pcthread_audio_sema);
pcthread_mutex_lock(&pcthread_audio_mutex); pcthread_audio_rendering = false; pcthread_mutex_unlock(&pcthread_audio_mutex);
} /* else {
printf("Audio thread: dropped frame\n");
} */
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
audio_api->play((u8 *)audio_buffer, num_audio_samples * 4);

View File

@ -5,9 +5,16 @@
extern "C" {
#endif
#include <stdbool.h>
void game_deinit(void);
void game_exit(void);
void pc_request_gameloop_wait(void);
void pc_wait_for_audio(void);
bool pc_check_audio_rendering(void);
bool pc_check_gameloop_wait(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,7 @@
#include "thread.h"
// TODO: Cross-platform stuff
void pcthread_mutex_lock(pthread_mutex_t *mutex) {
pthread_mutex_lock(mutex);
}

View File

@ -5,17 +5,6 @@
#include <semaphore.h>
#include <stdbool.h>
extern pthread_t pcthread_audio_id;
extern pthread_mutex_t pcthread_audio_mutex;
extern sem_t pcthread_audio_sema;
extern bool pcthread_audio_init;
extern bool pcthread_audio_rendering;
extern pthread_mutex_t pcthread_game_mutex;
extern sem_t pcthread_game_sema;
extern bool pcthread_game_loop_iterating;
extern bool pcthread_game_reset_sound;
void pcthread_mutex_lock(pthread_mutex_t *mutex);
void pcthread_mutex_unlock(pthread_mutex_t *mutex);
void pcthread_semaphore_init(sem_t *sem, int pshared, unsigned int value);