Make it work with SDL3
This commit is contained in:
@@ -8,10 +8,10 @@ struct Event;
|
|||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Core {
|
struct Core {
|
||||||
Core(ParallelRDP &);
|
explicit Core(ParallelRDP &);
|
||||||
void Stop();
|
void Stop();
|
||||||
void LoadROM(const std::string &);
|
void LoadROM(const std::string &);
|
||||||
bool LoadTAS(const fs::path &) const;
|
[[nodiscard]] bool LoadTAS(const fs::path &) const;
|
||||||
void Run(float volumeL, float volumeR);
|
void Run(float volumeL, float volumeR);
|
||||||
void Serialize();
|
void Serialize();
|
||||||
void Deserialize();
|
void Deserialize();
|
||||||
|
|||||||
@@ -9,29 +9,6 @@ namespace n64 {
|
|||||||
#define SYSTEM_SAMPLE_SIZE 4
|
#define SYSTEM_SAMPLE_SIZE 4
|
||||||
#define BYTES_PER_HALF_SECOND (((float)AUDIO_SAMPLE_RATE / 2) * SYSTEM_SAMPLE_SIZE)
|
#define BYTES_PER_HALF_SECOND (((float)AUDIO_SAMPLE_RATE / 2) * SYSTEM_SAMPLE_SIZE)
|
||||||
|
|
||||||
void audioCallback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount) {
|
|
||||||
auto audioDevice = (AudioDevice *)userdata;
|
|
||||||
int gotten = 0, available = 0;
|
|
||||||
|
|
||||||
if (audioDevice) {
|
|
||||||
audioDevice->LockMutex();
|
|
||||||
available = SDL_GetAudioStreamAvailable(audioDevice->GetStream());
|
|
||||||
if (available > 0) {
|
|
||||||
gotten = SDL_GetAudioStreamData(audioDevice->GetStream(), stream, total_amount);
|
|
||||||
}
|
|
||||||
audioDevice->UnlockMutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
int gottenSamples = (int)(gotten / sizeof(float));
|
|
||||||
auto *out = (float *)stream;
|
|
||||||
out += gottenSamples;
|
|
||||||
|
|
||||||
for (int i = gottenSamples; i < total_amount / sizeof(float); i++) {
|
|
||||||
float sample = 0;
|
|
||||||
*out++ = sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice::~AudioDevice() {
|
AudioDevice::~AudioDevice() {
|
||||||
LockMutex();
|
LockMutex();
|
||||||
SDL_DestroyAudioStream(GetStream());
|
SDL_DestroyAudioStream(GetStream());
|
||||||
@@ -39,52 +16,47 @@ AudioDevice::~AudioDevice() {
|
|||||||
SDL_DestroyMutex(audioStreamMutex);
|
SDL_DestroyMutex(audioStreamMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDevice::AudioDevice() : audioStreamMutex(SDL_CreateMutex()) {
|
AudioDevice::AudioDevice() {
|
||||||
request.freq = AUDIO_SAMPLE_RATE;
|
audioStreamMutex = SDL_CreateMutex();
|
||||||
request.format = SYSTEM_SAMPLE_FORMAT;
|
|
||||||
request.channels = 2;
|
|
||||||
|
|
||||||
audioStream = SDL_CreateAudioStream(&request, &request);
|
|
||||||
|
|
||||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
|
||||||
|
|
||||||
if (!audioStreamMutex) {
|
if (!audioStreamMutex) {
|
||||||
Util::panic("Unable to initialize audio mutex: {}", SDL_GetError());
|
Util::panic("Unable to initialize audio mutex: {}", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &request);
|
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||||
SDL_BindAudioStream(handle, audioStream);
|
request = {SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE};
|
||||||
SDL_SetAudioStreamGetCallback(audioStream, audioCallback, this);
|
|
||||||
|
|
||||||
if (!handle) {
|
audioStream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &request, nullptr, nullptr);
|
||||||
Util::panic("Failed to initialize SDL Audio: {}", SDL_GetError());
|
if (!audioStream) {
|
||||||
|
Util::panic("Unable to create audio stream: {}", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_PauseAudioDevice(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDevice::PushSample(float left, float volumeL, float right, float volumeR) {
|
void AudioDevice::PushSample(float left, float volumeL, float right, float volumeR) {
|
||||||
float adjustedL = left * volumeL;
|
float adjustedL = left * volumeL;
|
||||||
float adjustedR = right * volumeR;
|
float adjustedR = right * volumeR;
|
||||||
float samples[2]{adjustedL, adjustedR};
|
float samples[]{adjustedL, adjustedR};
|
||||||
|
|
||||||
auto availableBytes = (float)SDL_GetAudioStreamAvailable(audioStream);
|
auto availableBytes = (float)SDL_GetAudioStreamAvailable(audioStream);
|
||||||
if (availableBytes <= BYTES_PER_HALF_SECOND) {
|
if (availableBytes <= BYTES_PER_HALF_SECOND) {
|
||||||
SDL_PutAudioStreamData(audioStream, samples, 2 * sizeof(float));
|
SDL_PutAudioStreamData(audioStream, samples, 2 * sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!running) {
|
||||||
|
SDL_ResumeAudioStreamDevice(audioStream);
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDevice::AdjustSampleRate(int sampleRate) {
|
void AudioDevice::AdjustSampleRate(int sampleRate) {
|
||||||
LockMutex();
|
LockMutex();
|
||||||
SDL_DestroyAudioStream(audioStream);
|
SDL_DestroyAudioStream(audioStream);
|
||||||
|
|
||||||
auto oldReq = request;
|
request = {SYSTEM_SAMPLE_FORMAT, 2, sampleRate};
|
||||||
|
|
||||||
request.freq = sampleRate;
|
audioStream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &request, nullptr, nullptr);
|
||||||
request.format = SYSTEM_SAMPLE_FORMAT;
|
if (!audioStream) {
|
||||||
request.channels = 2;
|
Util::panic("Unable to create audio stream: {}", SDL_GetError());
|
||||||
|
}
|
||||||
audioStream = SDL_CreateAudioStream(&request, &oldReq);
|
|
||||||
UnlockMutex();
|
UnlockMutex();
|
||||||
}
|
}
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -23,9 +23,8 @@ struct AudioDevice {
|
|||||||
private:
|
private:
|
||||||
SDL_AudioStream *audioStream;
|
SDL_AudioStream *audioStream;
|
||||||
SDL_Mutex *audioStreamMutex;
|
SDL_Mutex *audioStreamMutex;
|
||||||
SDL_AudioSpec audioSpec{};
|
|
||||||
SDL_AudioSpec request{};
|
SDL_AudioSpec request{};
|
||||||
SDL_AudioDeviceID handle{};
|
bool running = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -46,14 +46,11 @@ EmuThread::EmuThread(const std::shared_ptr<QtInstanceFactory> &instance_,
|
|||||||
while (!isInterruptionRequested()) {
|
while (!isInterruptionRequested()) {
|
||||||
if (!core.pause) {
|
if (!core.pause) {
|
||||||
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
||||||
|
}
|
||||||
|
|
||||||
if (core.render) {
|
if (core.render) {
|
||||||
parallel.UpdateScreen(core.cpu->GetMem().mmio.vi);
|
parallel.UpdateScreen(core.cpu->GetMem().mmio.vi);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (core.render) {
|
|
||||||
parallel.UpdateScreen(core.cpu->GetMem().mmio.vi, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pollEvents();
|
pollEvents();
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
SettingsWindow &settings;
|
SettingsWindow &settings;
|
||||||
|
|
||||||
void TogglePause() {
|
void TogglePause() {
|
||||||
core.pause = !core.pause;
|
core.TogglePause();
|
||||||
Util::RPC::GetInstance().Update(core.pause ? Util::RPC::Paused : Util::RPC::GetInstance().GetState(),
|
Util::RPC::GetInstance().Update(core.pause ? Util::RPC::Paused : Util::RPC::GetInstance().GetState(),
|
||||||
core.cpu->GetMem().rom.gameNameDB,
|
core.cpu->GetMem().rom.gameNameDB,
|
||||||
core.cpu->GetMem().mmio.si.pif.movie.GetFilename());
|
core.cpu->GetMem().mmio.si.pif.movie.GetFilename());
|
||||||
|
|||||||
Reference in New Issue
Block a user