mirror of
https://github.com/0ldsk00l/nestopia.git
synced 2024-06-22 06:02:26 -04:00
FLTK: Rewrite audio playback code
This commit is contained in:
parent
fcb3976aaf
commit
eee60f7a5c
|
@ -13,11 +13,13 @@ nestopia_CPPFLAGS = \
|
|||
-DNST_PRAGMA_ONCE \
|
||||
$(ZLIB_CFLAGS) \
|
||||
$(LIBARCHIVE_CFLAGS) \
|
||||
$(SAMPLERATE_CFLAGS) \
|
||||
$(SDL2_CFLAGS) \
|
||||
$(FLTK_CFLAGS)
|
||||
nestopia_LDADD = \
|
||||
$(ZLIB_LIBS) \
|
||||
$(LIBARCHIVE_LIBS) \
|
||||
$(SAMPLERATE_LIBS) \
|
||||
$(SDL2_LIBS) \
|
||||
$(FLTK_LIBS)
|
||||
|
||||
|
@ -710,6 +712,8 @@ nestopia_SOURCES = \
|
|||
source/nes_ntsc/demo_impl.h
|
||||
|
||||
nestopia_SOURCES += \
|
||||
source/fltkui/audiomanager.cpp \
|
||||
source/fltkui/audiomanager.h \
|
||||
source/fltkui/chtmanager.cpp \
|
||||
source/fltkui/chtmanager.h \
|
||||
source/fltkui/cli.cpp \
|
||||
|
@ -722,8 +726,6 @@ nestopia_SOURCES += \
|
|||
source/fltkui/font.h \
|
||||
source/fltkui/png.cpp \
|
||||
source/fltkui/png.h \
|
||||
source/fltkui/audio.cpp \
|
||||
source/fltkui/audio.h \
|
||||
source/fltkui/jgmanager.cpp \
|
||||
source/fltkui/jgmanager.h \
|
||||
source/fltkui/setmanager.cpp \
|
||||
|
|
|
@ -20,12 +20,12 @@ libretro community. For libretro-specific issues, please use the libretro reposi
|
|||
https://github.com/libretro/nestopia
|
||||
|
||||
This project depends on the following libraries:
|
||||
FLTK 1.3, SDL2, libarchive, zlib
|
||||
FLTK 1.3, SDL2, libarchive, libsamplerate, zlib
|
||||
|
||||
## Installing Dependencies
|
||||
Install dependencies required for building on Debian-based Linux distributions:
|
||||
```
|
||||
apt-get install build-essential autoconf autoconf-archive automake autotools-dev libfltk1.3-dev libsdl2-dev libarchive-dev zlib1g-dev
|
||||
apt-get install build-essential autoconf autoconf-archive automake autotools-dev libfltk1.3-dev libsamplerate0-dev libsdl2-dev libarchive-dev zlib1g-dev
|
||||
```
|
||||
|
||||
## FLTK Build
|
||||
|
@ -43,7 +43,7 @@ make install
|
|||
## macOS Build
|
||||
```
|
||||
# Install dependencies
|
||||
brew install autoconf automake autoconf-archive pkg-config libarchive libepoxy fltk
|
||||
brew install autoconf automake autoconf-archive pkg-config libarchive libepoxy libsamplerate fltk sdl2
|
||||
|
||||
# Build
|
||||
autoreconf -vif
|
||||
|
|
|
@ -72,6 +72,9 @@ PKG_CHECK_MODULES([ZLIB], [zlib])
|
|||
dnl libarchive
|
||||
PKG_CHECK_MODULES([LIBARCHIVE], [libarchive])
|
||||
|
||||
dnl SAMPLERATE
|
||||
PKG_CHECK_MODULES([SAMPLERATE], [samplerate])
|
||||
|
||||
dnl SDL2
|
||||
PKG_CHECK_MODULES([SDL2], [sdl2])
|
||||
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Nestopia UE
|
||||
*
|
||||
* Copyright (C) 2012-2024 R. Danbrook
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <jg/jg.h>
|
||||
|
||||
#include "audio.h"
|
||||
#include "jgmanager.h"
|
||||
|
||||
#define BUFSIZE 16384
|
||||
|
||||
static SDL_AudioSpec spec, obtained;
|
||||
static SDL_AudioDeviceID dev;
|
||||
static SDL_AudioCVT cvt;
|
||||
|
||||
static JGManager *jgm = nullptr;
|
||||
static jg_audioinfo_t* audinfo = nullptr;
|
||||
|
||||
static int16_t intbuf[BUFSIZE];
|
||||
static int16_t extbuf[BUFSIZE];
|
||||
static uint16_t bufstart = 0;
|
||||
static uint16_t bufend = 0;
|
||||
static uint16_t bufsamples = 0;
|
||||
|
||||
static size_t bufsize;
|
||||
static int ffspeed = 1;
|
||||
|
||||
static bool paused = false;
|
||||
|
||||
void audio_set_speed(int speed) {
|
||||
bufsize = (audinfo->rate / jgm->get_frametime()) / speed;
|
||||
ffspeed = speed;
|
||||
}
|
||||
|
||||
void audio_queue(size_t in_size) {
|
||||
while ((bufsamples + bufsize) >= BUFSIZE) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
size_t numsamples = in_size / ffspeed;
|
||||
|
||||
SDL_LockAudioDevice(dev);
|
||||
|
||||
if (bufsamples < bufsize * 3) {
|
||||
SDL_ConvertAudio(&cvt);
|
||||
numsamples += 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numsamples; i++) {
|
||||
extbuf[bufend] = intbuf[i];
|
||||
bufend = (bufend + 1) % BUFSIZE;
|
||||
bufsamples++;
|
||||
if (bufsamples >= BUFSIZE - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockAudioDevice(dev);
|
||||
}
|
||||
|
||||
static inline int16_t audio_dequeue() {
|
||||
if (bufsamples == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t sample = extbuf[bufstart];
|
||||
bufstart = (bufstart + 1) % BUFSIZE;
|
||||
bufsamples--;
|
||||
return sample;
|
||||
}
|
||||
|
||||
void audio_cb(void *data, uint8_t *stream, int len) {
|
||||
int16_t *out = (int16_t*)stream;
|
||||
for (int i = 0; i < len / sizeof(int16_t); i++) {
|
||||
out[i] = audio_dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
void audio_deinit() {
|
||||
if (dev) {
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void audio_init_sdl() {
|
||||
int e = 1; // Check Endianness
|
||||
SDL_AudioFormat fmt = ((int)*((unsigned char *)&e) == 1) ? AUDIO_S16LSB : AUDIO_S16MSB;
|
||||
|
||||
spec.freq = audinfo->rate;
|
||||
spec.format = fmt;
|
||||
spec.channels = 1;
|
||||
spec.silence = 0;
|
||||
spec.samples = 512;
|
||||
spec.userdata = 0;
|
||||
spec.callback = audio_cb;
|
||||
|
||||
// FIXME 60 should be frametime
|
||||
bufsize = audinfo->rate / 60;
|
||||
bufend = bufstart = bufsamples = 0;
|
||||
|
||||
dev = SDL_OpenAudioDevice(NULL, 0, &spec, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Error opening audio device.\n");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Audio: SDL - %dHz, %d channel(s)\n", spec.freq, spec.channels);
|
||||
}
|
||||
|
||||
// FIXME 60 should be frametime
|
||||
SDL_BuildAudioCVT(&cvt, fmt, 1, audinfo->rate, fmt, 1, audinfo->rate + (60 * 2));
|
||||
SDL_assert(cvt.needed);
|
||||
cvt.len = (bufsize + 2) * sizeof(int16_t);
|
||||
cvt.buf = (Uint8*)intbuf;
|
||||
|
||||
SDL_PauseAudioDevice(dev, 1); // Setting to 0 unpauses
|
||||
}
|
||||
|
||||
void audio_init(JGManager *jgmgr) {
|
||||
jgm = jgmgr;
|
||||
audinfo = jg_get_audioinfo();
|
||||
audinfo->buf = &intbuf[0];
|
||||
|
||||
// Initialize audio device
|
||||
memset(intbuf, 0, sizeof(int16_t) * BUFSIZE);
|
||||
audio_init_sdl();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
void audio_pause() {
|
||||
// Pause the SDL audio device
|
||||
SDL_PauseAudioDevice(dev, 1);
|
||||
paused = true;
|
||||
}
|
||||
|
||||
void audio_unpause() {
|
||||
// Unpause the SDL audio device
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
paused = false;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "jgmanager.h"
|
||||
|
||||
void audio_set_funcs();
|
||||
void audio_init(JGManager *jgmgr);
|
||||
void audio_deinit();
|
||||
void audio_queue(size_t in_size);
|
||||
void audio_pause();
|
||||
void audio_unpause();
|
||||
void audio_set_speed(int speed);
|
216
source/fltkui/audiomanager.cpp
Normal file
216
source/fltkui/audiomanager.cpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Nestopia UE
|
||||
*
|
||||
* Copyright (C) 2012-2024 R. Danbrook
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include <jg/jg.h>
|
||||
|
||||
#include "audiomanager.h"
|
||||
#include "jgmanager.h"
|
||||
|
||||
namespace {
|
||||
|
||||
jg_audioinfo_t* audinfo{nullptr};
|
||||
|
||||
SDL_AudioSpec spec, obtained;
|
||||
SDL_AudioDeviceID dev;
|
||||
|
||||
SRC_STATE *srcstate{nullptr};
|
||||
SRC_DATA srcdata;
|
||||
float *fltbuf_in;
|
||||
float *fltbuf_out;
|
||||
|
||||
int16_t *buf_in;
|
||||
int16_t *buf_out;
|
||||
|
||||
size_t bufstart{0};
|
||||
size_t bufend{0};
|
||||
size_t bufsamples{0};
|
||||
|
||||
size_t spf;
|
||||
int ffspeed{1};
|
||||
|
||||
void audio_cb_sdl(void *data, uint8_t *stream, int len) {
|
||||
AudioManager *audiomgr = static_cast<AudioManager*>(data);
|
||||
int16_t *out = (int16_t*)stream;
|
||||
for (int i = 0; i < len / sizeof(int16_t); i++) {
|
||||
out[i] = audiomgr->dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
AudioManager::AudioManager(JGManager& jgm, SettingManager& setmgr)
|
||||
: jgm(jgm), setmgr(setmgr) {
|
||||
jgm.set_audio_cb(AudioManager::queue);
|
||||
|
||||
// Initialize audio buffers
|
||||
buf_in = new int16_t[BUFSIZE];
|
||||
std::fill(buf_in, buf_in + BUFSIZE, 0);
|
||||
buf_out = new int16_t[BUFSIZE];
|
||||
std::fill(buf_out, buf_out + BUFSIZE, 0);
|
||||
|
||||
fltbuf_in = new float[BUFSIZE];
|
||||
std::fill(fltbuf_in, fltbuf_in + BUFSIZE, 0);
|
||||
fltbuf_out = new float[BUFSIZE];
|
||||
std::fill(fltbuf_out, fltbuf_out + BUFSIZE, 0);
|
||||
|
||||
bufend = bufstart = bufsamples = 0;
|
||||
|
||||
audinfo = jgm.get_audioinfo();
|
||||
audinfo->buf = &buf_in[0];
|
||||
spf = audinfo->spf;
|
||||
|
||||
// Resampler
|
||||
int err;
|
||||
srcstate = src_new(setmgr.get_setting("a_rsqual")->val, audinfo->channels, &err);
|
||||
srcdata.data_in = fltbuf_in;
|
||||
srcdata.data_out = fltbuf_out;
|
||||
srcdata.output_frames = audinfo->spf;
|
||||
srcdata.src_ratio = 1.0;
|
||||
|
||||
// SDL Audio Output
|
||||
spec.freq = audinfo->rate;
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
spec.format = AUDIO_S16MSB;
|
||||
#else
|
||||
spec.format = AUDIO_S16LSB;
|
||||
#endif
|
||||
spec.channels = audinfo->channels;
|
||||
spec.silence = 0;
|
||||
spec.samples = 512;
|
||||
spec.userdata = this;
|
||||
spec.callback = audio_cb_sdl;
|
||||
|
||||
dev = SDL_OpenAudioDevice(NULL, 0, &spec, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Error opening audio device.\n");
|
||||
}
|
||||
|
||||
SDL_PauseAudioDevice(dev, 0); // Setting to 0 unpauses
|
||||
}
|
||||
|
||||
AudioManager::~AudioManager() {
|
||||
if (dev) {
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
|
||||
if (srcstate) {
|
||||
srcstate = src_delete(srcstate);
|
||||
}
|
||||
|
||||
if (buf_in) {
|
||||
delete[] buf_in;
|
||||
}
|
||||
|
||||
if (buf_out) {
|
||||
delete[] buf_out;
|
||||
}
|
||||
|
||||
if (fltbuf_in) {
|
||||
delete[] fltbuf_in;
|
||||
}
|
||||
|
||||
if (fltbuf_out) {
|
||||
delete[] fltbuf_out;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t AudioManager::dequeue() {
|
||||
if (bufsamples == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t sample = buf_out[bufstart];
|
||||
bufstart = (bufstart + 1) % BUFSIZE;
|
||||
bufsamples--;
|
||||
return sample;
|
||||
}
|
||||
|
||||
void AudioManager::queue(size_t in_size) {
|
||||
spf = audinfo->spf;
|
||||
while ((bufsamples + spf) >= BUFSIZE) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
size_t numsamples = in_size / ffspeed;
|
||||
|
||||
src_short_to_float_array(buf_in, fltbuf_in, numsamples);
|
||||
srcdata.input_frames = numsamples;
|
||||
srcdata.end_of_input = 0;
|
||||
|
||||
SDL_LockAudioDevice(dev);
|
||||
|
||||
size_t frames_queued = bufsamples / spf;
|
||||
|
||||
if (frames_queued < 3) {
|
||||
size_t step = 3 - frames_queued;
|
||||
srcdata.output_frames = numsamples + step;
|
||||
srcdata.src_ratio = (audinfo->rate + (JGManager::get_frametime() * step)) /
|
||||
(audinfo->rate * 1.0);
|
||||
}
|
||||
else {
|
||||
srcdata.output_frames = numsamples;
|
||||
srcdata.src_ratio = 1.0;
|
||||
}
|
||||
|
||||
src_process(srcstate, &srcdata);
|
||||
|
||||
for (int i = 0; i < srcdata.output_frames_gen; i++) {
|
||||
fltbuf_out[i] *= 32768;
|
||||
buf_out[bufend] = fltbuf_out[i] >= 32767.0 ? 32767 :
|
||||
fltbuf_out[i] <= -32768.0 ? -32768 :
|
||||
fltbuf_out[i];
|
||||
bufend = (bufend + 1) % BUFSIZE;
|
||||
bufsamples++;
|
||||
if (bufsamples >= BUFSIZE - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockAudioDevice(dev);
|
||||
}
|
||||
|
||||
void AudioManager::rehash() {
|
||||
if (srcstate) {
|
||||
srcstate = src_delete(srcstate);
|
||||
}
|
||||
int err;
|
||||
srcstate = src_new(setmgr.get_setting("a_rsqual")->val, audinfo->channels, &err);
|
||||
}
|
||||
|
||||
void AudioManager::set_speed(int speed) {
|
||||
spf = (audinfo->rate / jgm.get_frametime()) / speed;
|
||||
ffspeed = speed;
|
||||
}
|
||||
|
||||
void AudioManager::pause() {
|
||||
SDL_PauseAudioDevice(dev, 1);
|
||||
}
|
||||
|
||||
void AudioManager::unpause() {
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
}
|
26
source/fltkui/audiomanager.h
Normal file
26
source/fltkui/audiomanager.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "jgmanager.h"
|
||||
#include "setmanager.h"
|
||||
|
||||
constexpr size_t BUFSIZE = 4800;
|
||||
|
||||
class AudioManager {
|
||||
public:
|
||||
AudioManager() = delete;
|
||||
AudioManager(JGManager& jgm, SettingManager& setmgr);
|
||||
~AudioManager();
|
||||
|
||||
void set_speed(int speed);
|
||||
void pause();
|
||||
void unpause();
|
||||
|
||||
inline int16_t dequeue();
|
||||
static void queue(size_t in_size);
|
||||
|
||||
void rehash();
|
||||
|
||||
private:
|
||||
JGManager &jgm;
|
||||
SettingManager &setmgr;
|
||||
};
|
|
@ -40,12 +40,12 @@
|
|||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "audiomanager.h"
|
||||
#include "chtmanager.h"
|
||||
#include "inputmanager.h"
|
||||
#include "jgmanager.h"
|
||||
#include "setmanager.h"
|
||||
#include "inputmanager.h"
|
||||
#include "chtmanager.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "video.h"
|
||||
|
||||
#include "fltkui.h"
|
||||
|
@ -66,6 +66,7 @@ static NstSettingsWindow *setwin;
|
|||
static JGManager *jgm = nullptr;
|
||||
static SettingManager *setmgr = nullptr;
|
||||
static InputManager *inputmgr = nullptr;
|
||||
static AudioManager *audiomgr = nullptr;
|
||||
static CheatManager *chtmgr = nullptr;
|
||||
|
||||
static std::vector<uint8_t> game;
|
||||
|
@ -319,12 +320,12 @@ static void fltkui_state_qsave(Fl_Widget* w, void* userdata) {
|
|||
static void fltkui_pause(Fl_Widget* w, void* userdata) {
|
||||
paused ^= 1;
|
||||
if (paused) {
|
||||
audio_pause();
|
||||
audiomgr->pause();
|
||||
Fl_Menu_Item* m = const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue());
|
||||
m->label("Play");
|
||||
}
|
||||
else {
|
||||
audio_unpause();
|
||||
audiomgr->unpause();
|
||||
Fl_Menu_Item* m = const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue());
|
||||
m->label("Pause");
|
||||
}
|
||||
|
@ -351,6 +352,11 @@ void NstGlArea::resize(int x, int y, int w, int h) {
|
|||
nst_video_resize(w, h);
|
||||
}
|
||||
|
||||
void fltkui_rehash() {
|
||||
nst_video_rehash();
|
||||
audiomgr->rehash();
|
||||
}
|
||||
|
||||
void fltkui_fullscreen(Fl_Widget *w, void *data) {
|
||||
if (!jgm->is_loaded()) {
|
||||
return;
|
||||
|
@ -579,7 +585,7 @@ void fltkui_set_ffspeed(bool on) {
|
|||
speed = 1;
|
||||
}
|
||||
|
||||
audio_set_speed(speed);
|
||||
audiomgr->set_speed(speed);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -599,8 +605,7 @@ int main(int argc, char *argv[]) {
|
|||
// Read frontend and emulator settings
|
||||
setmgr->read(*jgm);
|
||||
|
||||
audio_init(jgm);
|
||||
audio_unpause();
|
||||
audiomgr = new AudioManager(*jgm, *setmgr);
|
||||
|
||||
// Initialize video params
|
||||
video_init(setmgr, jgm);
|
||||
|
@ -674,12 +679,13 @@ int main(int argc, char *argv[]) {
|
|||
glarea->redraw();
|
||||
}
|
||||
|
||||
// Deinitialize audio
|
||||
audio_deinit();
|
||||
|
||||
// Write frontend and emulator settings
|
||||
setmgr->write(*jgm);
|
||||
|
||||
if (audiomgr) {
|
||||
delete audiomgr;
|
||||
}
|
||||
|
||||
if (inputmgr) {
|
||||
delete inputmgr;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ constexpr Fl_Color NstWhite = 0xffffff00;
|
|||
constexpr Fl_Color NstBlueGrey = 0x383c4a00;
|
||||
constexpr Fl_Color NstLightGrey = 0xd3dae300;
|
||||
|
||||
void fltkui_rehash();
|
||||
void fltkui_fullscreen(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
void fltkui_enable_menu();
|
||||
void fltkui_set_ffspeed(bool on);
|
||||
|
|
|
@ -117,7 +117,7 @@ void NstSettingsWindow::cb_chooser(Fl_Widget *w, void *data) {
|
|||
setting->val = ((Fl_Choice*)w)->value();
|
||||
|
||||
if (setting->flags & FLAG_FRONTEND) {
|
||||
setmgr.rehash();
|
||||
fltkui_rehash();
|
||||
}
|
||||
else {
|
||||
jgm.rehash();
|
||||
|
@ -137,7 +137,7 @@ void NstSettingsWindow::cb_slider(Fl_Widget *w, void *data) {
|
|||
setting->val = ((Fl_Hor_Value_Slider*)w)->value();
|
||||
|
||||
if (setting->flags & FLAG_FRONTEND) {
|
||||
setmgr.rehash();
|
||||
fltkui_rehash();
|
||||
}
|
||||
else {
|
||||
jgm.rehash();
|
||||
|
|
|
@ -1305,6 +1305,8 @@ int jg_game_load(void) {
|
|||
jg_cb_frametime(FRAMERATE_PAL);
|
||||
}
|
||||
else {
|
||||
vidinfo.aspect = ASPECT_NTSC;
|
||||
audinfo.spf = (SAMPLERATE / (unsigned)FRAMERATE) * CHANNELS;
|
||||
jg_cb_frametime(FRAMERATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,18 +30,12 @@
|
|||
|
||||
#include "jgmanager.h"
|
||||
|
||||
// FIXME - move these...
|
||||
#include "audio.h"
|
||||
#include "video.h"
|
||||
#include "video.h" // FIXME - move this
|
||||
|
||||
namespace {
|
||||
|
||||
int frametime = 0;
|
||||
|
||||
void jg_audio(size_t in_size) {
|
||||
audio_queue(in_size);
|
||||
}
|
||||
|
||||
void jg_frametime(double interval) {
|
||||
frametime = interval + 0.5;
|
||||
}
|
||||
|
@ -83,7 +77,6 @@ JGManager::JGManager() {
|
|||
settings.push_back(&jg_settings[i]);
|
||||
}
|
||||
|
||||
jg_set_cb_audio(&jg_audio);
|
||||
jg_set_cb_frametime(jg_frametime);
|
||||
jg_set_cb_log(&jg_log);
|
||||
jg_init();
|
||||
|
@ -291,3 +284,11 @@ jg_coreinfo_t *JGManager::get_coreinfo() {
|
|||
jg_inputinfo_t *JGManager::get_inputinfo(int port) {
|
||||
return jg_get_inputinfo(port);
|
||||
}
|
||||
|
||||
jg_audioinfo_t *JGManager::get_audioinfo() {
|
||||
return jg_get_audioinfo();
|
||||
}
|
||||
|
||||
void JGManager::set_audio_cb(jg_cb_audio_t cb) {
|
||||
jg_set_cb_audio(cb);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
void cheat_clear();
|
||||
void cheat_set(const char *code);
|
||||
|
||||
int get_frametime();
|
||||
static int get_frametime();
|
||||
|
||||
std::string& get_basepath();
|
||||
std::string& get_gamename();
|
||||
|
@ -42,6 +42,9 @@ public:
|
|||
|
||||
jg_coreinfo_t* get_coreinfo();
|
||||
jg_inputinfo_t* get_inputinfo(int port);
|
||||
jg_audioinfo_t* get_audioinfo();
|
||||
|
||||
void set_audio_cb(jg_cb_audio_t cb);
|
||||
|
||||
private:
|
||||
void set_paths();
|
||||
|
|
|
@ -52,6 +52,11 @@ jg_setting_t fe_settings[] = {
|
|||
"Set the aspect ratio to the correct TV aspect, 1:1 (square pixels), or 4:3",
|
||||
0, 0, 2, FLAG_FRONTEND
|
||||
},
|
||||
{ "a_rsqual", "Audio Resampler Quality",
|
||||
"0 = Sinc (Best), 1 = Sinc (Medium), 2 = Sinc (Fast), 3 = Zero Order Hold, 4 = Linear",
|
||||
"Set the frontend's audio resampling quality. Use Sinc unless you are on extremely weak hardware.",
|
||||
2, 0, 4, FLAG_FRONTEND
|
||||
},
|
||||
{ "m_ffspeed", "Fast-forward Speed",
|
||||
"N = Fast-forward speed multiplier",
|
||||
"Set the speed multiplier to run emulation faster",
|
||||
|
@ -179,10 +184,6 @@ void SettingManager::write(JGManager& jgm) {
|
|||
}*/
|
||||
}
|
||||
|
||||
void SettingManager::rehash() {
|
||||
nst_video_rehash();
|
||||
}
|
||||
|
||||
std::vector<jg_setting_t*> *SettingManager::get_settings() {
|
||||
return &settings;
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ public:
|
|||
void read(JGManager& jgm);
|
||||
void write(JGManager& jgm);
|
||||
|
||||
void rehash();
|
||||
|
||||
std::vector<jg_setting_t*>* get_settings();
|
||||
jg_setting_t* get_setting(std::string name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue