Compare commits
7 Commits
master
...
port-audio
Author | SHA1 | Date | |
---|---|---|---|
|
b4335e5934 | ||
|
1abb6e62f4 | ||
|
3bc68fef8f | ||
|
51177cd80d | ||
|
c4ec9e51d1 | ||
|
a17d971fc0 | ||
|
936a39f624 |
4
.github/actions/install_deps.sh
vendored
4
.github/actions/install_deps.sh
vendored
@ -1,7 +1,7 @@
|
|||||||
case `echo $1 | cut -d '-' -f 1` in
|
case `echo $1 | cut -d '-' -f 1` in
|
||||||
ubuntu)
|
ubuntu)
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt-get install -yq bison libpng-dev pkg-config libsdl2-dev
|
sudo apt-get install -yq bison libpng-dev pkg-config libsdl2-dev portaudio19-dev
|
||||||
(
|
(
|
||||||
cd `mktemp -d`
|
cd `mktemp -d`
|
||||||
curl -L https://github.com/rednex/rgbds/archive/v0.4.0.zip > rgbds.zip
|
curl -L https://github.com/rednex/rgbds/archive/v0.4.0.zip > rgbds.zip
|
||||||
@ -14,7 +14,7 @@ case `echo $1 | cut -d '-' -f 1` in
|
|||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
macos)
|
macos)
|
||||||
brew install rgbds sdl2
|
brew install rgbds sdl2 portaudio
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unsupported OS"
|
echo "Unsupported OS"
|
||||||
|
2
.github/workflows/sanity.yml
vendored
2
.github/workflows/sanity.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
./.github/actions/install_deps.sh ${{ matrix.os }}
|
./.github/actions/install_deps.sh ${{ matrix.os }}
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
${{ matrix.cc }} -v; make -j sdl tester libretro ${{ matrix.extra_target }} CONF=release CC=${{ matrix.cc }}
|
${{ matrix.cc }} -v; (make -j sdl tester libretro ${{ matrix.extra_target }} CONF=release CC=${{ matrix.cc }} || (echo "==== Build Failed ==="; make sdl tester libretro ${{ matrix.extra_target }} CONF=release CC=${{ matrix.cc }}))
|
||||||
- name: Sanity tests
|
- name: Sanity tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
13
Makefile
13
Makefile
@ -38,6 +38,12 @@ VERSION := 0.12.3
|
|||||||
export VERSION
|
export VERSION
|
||||||
CONF ?= debug
|
CONF ?= debug
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM),windows32)
|
||||||
|
SDL_AUDIO_DRIVER ?= sdl
|
||||||
|
else
|
||||||
|
SDL_AUDIO_DRIVER ?= portaudio
|
||||||
|
endif
|
||||||
|
|
||||||
BIN := build/bin
|
BIN := build/bin
|
||||||
OBJ := build/obj
|
OBJ := build/obj
|
||||||
BOOTROMS_DIR ?= $(BIN)/BootROMs
|
BOOTROMS_DIR ?= $(BIN)/BootROMs
|
||||||
@ -120,6 +126,11 @@ else
|
|||||||
LDFLAGS += -lc -lm -ldl
|
LDFLAGS += -lc -lm -ldl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SDL_AUDIO_DRIVER),portaudio)
|
||||||
|
SDL_CFLAGS += -I/usr/local/include
|
||||||
|
SDL_LDFLAGS += -lportaudio
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),Darwin)
|
ifeq ($(PLATFORM),Darwin)
|
||||||
SYSROOT := $(shell xcodebuild -sdk macosx -version Path 2> $(NULL))
|
SYSROOT := $(shell xcodebuild -sdk macosx -version Path 2> $(NULL))
|
||||||
CFLAGS += -F/Library/Frameworks -mmacosx-version-min=10.9
|
CFLAGS += -F/Library/Frameworks -mmacosx-version-min=10.9
|
||||||
@ -172,7 +183,7 @@ all: cocoa sdl tester libretro
|
|||||||
# Get a list of our source files and their respective object file targets
|
# Get a list of our source files and their respective object file targets
|
||||||
|
|
||||||
CORE_SOURCES := $(shell ls Core/*.c)
|
CORE_SOURCES := $(shell ls Core/*.c)
|
||||||
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG)
|
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG) SDL/audio/$(SDL_AUDIO_DRIVER).c
|
||||||
TESTER_SOURCES := $(shell ls Tester/*.c)
|
TESTER_SOURCES := $(shell ls Tester/*.c)
|
||||||
|
|
||||||
ifeq ($(PLATFORM),Darwin)
|
ifeq ($(PLATFORM),Darwin)
|
||||||
|
@ -37,8 +37,8 @@ SameBoy passes all of [blargg's test ROMs](http://gbdev.gg8.se/wiki/articles/Tes
|
|||||||
SameBoy requires the following tools and libraries to build:
|
SameBoy requires the following tools and libraries to build:
|
||||||
* clang
|
* clang
|
||||||
* make
|
* make
|
||||||
* Cocoa port: OS X SDK and Xcode command line tools
|
* Cocoa frontend: OS X SDK and Xcode command line tools
|
||||||
* SDL port: libsdl2
|
* SDL frontend: libsdl2, portaudio (Optional but recommended, set `SDL_AUDIO_DRIVER` to `sdl` to avoid)
|
||||||
* [rgbds](https://github.com/bentley/rgbds/releases/), for boot ROM compilation
|
* [rgbds](https://github.com/bentley/rgbds/releases/), for boot ROM compilation
|
||||||
|
|
||||||
On Windows, SameBoy also requires:
|
On Windows, SameBoy also requires:
|
||||||
@ -46,8 +46,8 @@ On Windows, SameBoy also requires:
|
|||||||
* [GnuWin](http://gnuwin32.sourceforge.net/)
|
* [GnuWin](http://gnuwin32.sourceforge.net/)
|
||||||
* Running vcvars32 before running make. Make sure all required tools and libraries are in %PATH% and %lib%, respectively.
|
* Running vcvars32 before running make. Make sure all required tools and libraries are in %PATH% and %lib%, respectively.
|
||||||
|
|
||||||
To compile, simply run `make`. The targets are `cocoa` (Default for macOS), `sdl` (Default for everything else), `libretro`, `bootroms` and `tester`. You may also specify `CONF=debug` (default), `CONF=release` or `CONF=native_release` to control optimization and symbols. `native_release` is faster than `release`, but is optimized to the host's CPU and therefore is not portable. You may set `BOOTROMS_DIR=...` to a directory containing precompiled `dmg_boot.bin` and `cgb_boot.bin` files, otherwise the build system will compile and use SameBoy's own boot ROMs.
|
To compile, simply run `make`. The targets are `cocoa` (Default for macOS), `sdl` (Default for everything else), `libretro`, `bootroms` and `tester`. You may also specify `CONF=debug` (default), `CONF=release` or `CONF=native_release` to control optimization and symbols. `native_release` is faster than `release`, but is optimized to the host's CPU and therefore is not portable. You may set `BOOTROMS_DIR=...` to a directory containing precompiled `dmg_boot.bin` and `cgb_boot.bin` files, otherwise the build system will compile and use SameBoy's own boot ROMs. When compiling the SDL frontend, `SDL_AUDIO_DRIVER` can be set to either `sdl` or `portaudio`; the default driver is `sdl` for Windows and `portaudio` for every other platform.
|
||||||
|
|
||||||
By default, the SDL port will look for resource files with a path relative to executable. If you are packaging SameBoy, you may wish to override this by setting the `DATA_DIR` variable during compilation to the target path of the directory containing all files (apart from the executable, that's not necessary) from the `build/bin/SDL` directory in the source tree. Make sure the variable ends with a `/` character.
|
By default, the SDL frontend will look for resource files with a path relative to executable. If you are packaging SameBoy, you may wish to override this by setting the `DATA_DIR` variable during compilation to the target path of the directory containing all files (apart from the executable, that's not necessary) from the `build/bin/SDL` directory in the source tree. Make sure the variable ends with a `/` character.
|
||||||
|
|
||||||
SameBoy was compiled and tested on macOS, Ubuntu and 32-bit Windows 7.
|
SameBoy was compiled and tested on macOS, Ubuntu and 32-bit Windows 7.
|
||||||
|
17
SDL/audio/audio.h
Normal file
17
SDL/audio/audio.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef sdl_audio_h
|
||||||
|
#define sdl_audio_h
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
bool GB_audio_is_playing(void);
|
||||||
|
void GB_audio_set_paused(bool paused);
|
||||||
|
void GB_audio_clear_queue(void);
|
||||||
|
unsigned GB_audio_get_frequency(void);
|
||||||
|
size_t GB_audio_get_queue_length(void);
|
||||||
|
void GB_audio_queue_sample(GB_sample_t *sample);
|
||||||
|
void GB_audio_init(void);
|
||||||
|
bool GB_audio_set_sync_mode(bool sync_mode);
|
||||||
|
|
||||||
|
#endif /* sdl_audio_h */
|
93
SDL/audio/portaudio.c
Normal file
93
SDL/audio/portaudio.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "audio.h"
|
||||||
|
#include <portaudio.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AUDIO_FREQUENCY 96000
|
||||||
|
static PaStream *stream;
|
||||||
|
static size_t buffer_position = 0;
|
||||||
|
static GB_sample_t buffer[4096];
|
||||||
|
static bool blocking_mode = false;
|
||||||
|
|
||||||
|
bool GB_audio_set_sync_mode(bool sync_mode)
|
||||||
|
{
|
||||||
|
blocking_mode = sync_mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GB_audio_is_playing(void)
|
||||||
|
{
|
||||||
|
return stream && Pa_IsStreamActive(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_set_paused(bool paused)
|
||||||
|
{
|
||||||
|
if (!stream) return;
|
||||||
|
|
||||||
|
if (paused) {
|
||||||
|
Pa_StopStream(stream);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Pa_StartStream(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_clear_queue(void)
|
||||||
|
{
|
||||||
|
buffer_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned GB_audio_get_frequency(void)
|
||||||
|
{
|
||||||
|
return stream? Pa_GetStreamInfo(stream)->sampleRate : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GB_audio_get_queue_length(void)
|
||||||
|
{
|
||||||
|
return buffer_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_queue_sample(GB_sample_t *sample)
|
||||||
|
{
|
||||||
|
if (!stream) return;
|
||||||
|
|
||||||
|
if (buffer_position < sizeof(buffer) / sizeof(buffer[0])) {
|
||||||
|
buffer[buffer_position++] = *sample;
|
||||||
|
if (blocking_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (blocking_mode) {
|
||||||
|
Pa_WriteStream(stream, buffer, sizeof(buffer) / sizeof(buffer[0]));
|
||||||
|
buffer_position = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t write_legnth = Pa_GetStreamWriteAvailable(stream);
|
||||||
|
|
||||||
|
if (write_legnth > buffer_position) {
|
||||||
|
write_legnth = buffer_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_legnth) {
|
||||||
|
Pa_WriteStream(stream, buffer, write_legnth);
|
||||||
|
memmove(buffer, buffer + write_legnth, sizeof(buffer[0]) * (buffer_position - write_legnth));
|
||||||
|
buffer_position -= write_legnth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_init(void)
|
||||||
|
{
|
||||||
|
Pa_Initialize();
|
||||||
|
Pa_OpenDefaultStream(&stream,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
paInt16,
|
||||||
|
AUDIO_FREQUENCY,
|
||||||
|
sizeof(buffer) / sizeof(buffer[0]),
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
}
|
93
SDL/audio/sdl.c
Normal file
93
SDL/audio/sdl.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "audio.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define AUDIO_FREQUENCY 96000
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <Windows.h>
|
||||||
|
/* Windows (well, at least my VM) can't handle 96KHz sound well :( */
|
||||||
|
|
||||||
|
/* felsqualle says: For SDL 2.0.6+ using the WASAPI driver, the highest freq.
|
||||||
|
we can get is 48000. 96000 also works, but always has some faint crackling in
|
||||||
|
the audio, no matter how high or low I set the buffer length...
|
||||||
|
Not quite satisfied with that solution, because acc. to SDL2 docs,
|
||||||
|
96k + WASAPI *should* work. */
|
||||||
|
|
||||||
|
#define AUDIO_FREQUENCY 48000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Compatibility with older SDL versions */
|
||||||
|
#ifndef SDL_AUDIO_ALLOW_SAMPLES_CHANGE
|
||||||
|
#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SDL_AudioDeviceID device_id;
|
||||||
|
static SDL_AudioSpec want_aspec, have_aspec;
|
||||||
|
|
||||||
|
bool GB_audio_set_sync_mode(bool sync_mode)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GB_audio_is_playing(void)
|
||||||
|
{
|
||||||
|
return SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_set_paused(bool paused)
|
||||||
|
{
|
||||||
|
GB_audio_clear_queue();
|
||||||
|
SDL_PauseAudioDevice(device_id, paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_clear_queue(void)
|
||||||
|
{
|
||||||
|
SDL_ClearQueuedAudio(device_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned GB_audio_get_frequency(void)
|
||||||
|
{
|
||||||
|
return have_aspec.freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GB_audio_get_queue_length(void)
|
||||||
|
{
|
||||||
|
return SDL_GetQueuedAudioSize(device_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_queue_sample(GB_sample_t *sample)
|
||||||
|
{
|
||||||
|
SDL_QueueAudio(device_id, sample, sizeof(*sample));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_audio_init(void)
|
||||||
|
{
|
||||||
|
SDL_Init(SDL_INIT_AUDIO);
|
||||||
|
/* Configure Audio */
|
||||||
|
memset(&want_aspec, 0, sizeof(want_aspec));
|
||||||
|
want_aspec.freq = AUDIO_FREQUENCY;
|
||||||
|
want_aspec.format = AUDIO_S16SYS;
|
||||||
|
want_aspec.channels = 2;
|
||||||
|
want_aspec.samples = 512;
|
||||||
|
|
||||||
|
SDL_version _sdl_version;
|
||||||
|
SDL_GetVersion(&_sdl_version);
|
||||||
|
unsigned sdl_version = _sdl_version.major * 1000 + _sdl_version.minor * 100 + _sdl_version.patch;
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* SDL 2.0.5 on macOS and Linux introduced a bug where certain combinations of buffer lengths and frequencies
|
||||||
|
fail to produce audio correctly. */
|
||||||
|
if (sdl_version >= 2005) {
|
||||||
|
want_aspec.samples = 2048;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (sdl_version < 2006) {
|
||||||
|
/* Since WASAPI audio was introduced in SDL 2.0.6, we have to lower the audio frequency
|
||||||
|
to 44100 because otherwise we would get garbled audio output.*/
|
||||||
|
want_aspec.freq = 44100;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
device_id = SDL_OpenAudioDevice(0, 0, &want_aspec, &have_aspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
||||||
|
}
|
102
SDL/main.c
102
SDL/main.c
@ -8,27 +8,12 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "audio/audio.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#define AUDIO_FREQUENCY 96000
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
/* Windows (well, at least my VM) can't handle 96KHz sound well :( */
|
|
||||||
|
|
||||||
/* felsqualle says: For SDL 2.0.6+ using the WASAPI driver, the highest freq.
|
|
||||||
we can get is 48000. 96000 also works, but always has some faint crackling in
|
|
||||||
the audio, no matter how high or low I set the buffer length...
|
|
||||||
Not quite satisfied with that solution, because acc. to SDL2 docs,
|
|
||||||
96k + WASAPI *should* work. */
|
|
||||||
|
|
||||||
#define AUDIO_FREQUENCY 48000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Compatibility with older SDL versions */
|
|
||||||
#ifndef SDL_AUDIO_ALLOW_SAMPLES_CHANGE
|
|
||||||
#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GB_gameboy_t gb;
|
GB_gameboy_t gb;
|
||||||
@ -42,7 +27,16 @@ static char *filename = NULL;
|
|||||||
static typeof(free) *free_function = NULL;
|
static typeof(free) *free_function = NULL;
|
||||||
static char *battery_save_path_ptr;
|
static char *battery_save_path_ptr;
|
||||||
|
|
||||||
SDL_AudioDeviceID device_id;
|
static void update_turbo_mode(void)
|
||||||
|
{
|
||||||
|
if (GB_audio_set_sync_mode(!turbo_down) && !turbo_down) {
|
||||||
|
GB_set_turbo_mode(&gb, true, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Sync mode is not supported
|
||||||
|
GB_set_turbo_mode(&gb, turbo_down, turbo_down && rewind_down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_filename(const char *new_filename, typeof(free) *new_free_function)
|
void set_filename(const char *new_filename, typeof(free) *new_free_function)
|
||||||
{
|
{
|
||||||
@ -53,8 +47,6 @@ void set_filename(const char *new_filename, typeof(free) *new_free_function)
|
|||||||
free_function = new_free_function;
|
free_function = new_free_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_AudioSpec want_aspec, have_aspec;
|
|
||||||
|
|
||||||
static char *captured_log = NULL;
|
static char *captured_log = NULL;
|
||||||
|
|
||||||
static void log_capture_callback(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes)
|
static void log_capture_callback(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes)
|
||||||
@ -127,16 +119,15 @@ static void screen_size_changed(void)
|
|||||||
|
|
||||||
static void open_menu(void)
|
static void open_menu(void)
|
||||||
{
|
{
|
||||||
bool audio_playing = SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING;
|
bool audio_playing = GB_audio_is_playing();
|
||||||
if (audio_playing) {
|
if (audio_playing) {
|
||||||
SDL_PauseAudioDevice(device_id, 1);
|
GB_audio_set_paused(true);
|
||||||
}
|
}
|
||||||
size_t previous_width = GB_get_screen_width(&gb);
|
size_t previous_width = GB_get_screen_width(&gb);
|
||||||
run_gui(true);
|
run_gui(true);
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
if (audio_playing) {
|
if (audio_playing) {
|
||||||
SDL_ClearQueuedAudio(device_id);
|
GB_audio_set_paused(false);
|
||||||
SDL_PauseAudioDevice(device_id, 0);
|
|
||||||
}
|
}
|
||||||
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
||||||
GB_set_border_mode(&gb, configuration.border_mode);
|
GB_set_border_mode(&gb, configuration.border_mode);
|
||||||
@ -176,9 +167,9 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
GB_set_key_state(gb, (GB_key_t) button, event.type == SDL_JOYBUTTONDOWN);
|
GB_set_key_state(gb, (GB_key_t) button, event.type == SDL_JOYBUTTONDOWN);
|
||||||
}
|
}
|
||||||
else if (button == JOYPAD_BUTTON_TURBO) {
|
else if (button == JOYPAD_BUTTON_TURBO) {
|
||||||
SDL_ClearQueuedAudio(device_id);
|
GB_audio_clear_queue();
|
||||||
turbo_down = event.type == SDL_JOYBUTTONDOWN;
|
turbo_down = event.type == SDL_JOYBUTTONDOWN;
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
update_turbo_mode();
|
||||||
}
|
}
|
||||||
else if (button == JOYPAD_BUTTON_SLOW_MOTION) {
|
else if (button == JOYPAD_BUTTON_SLOW_MOTION) {
|
||||||
underclock_down = event.type == SDL_JOYBUTTONDOWN;
|
underclock_down = event.type == SDL_JOYBUTTONDOWN;
|
||||||
@ -188,7 +179,7 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
if (event.type == SDL_JOYBUTTONUP) {
|
if (event.type == SDL_JOYBUTTONUP) {
|
||||||
rewind_paused = false;
|
rewind_paused = false;
|
||||||
}
|
}
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
update_turbo_mode();
|
||||||
}
|
}
|
||||||
else if (button == JOYPAD_BUTTON_MENU && event.type == SDL_JOYBUTTONDOWN) {
|
else if (button == JOYPAD_BUTTON_MENU && event.type == SDL_JOYBUTTONDOWN) {
|
||||||
open_menu();
|
open_menu();
|
||||||
@ -294,14 +285,7 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bool audio_playing = SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING;
|
GB_audio_set_paused(GB_audio_is_playing());
|
||||||
if (audio_playing) {
|
|
||||||
SDL_PauseAudioDevice(device_id, 1);
|
|
||||||
}
|
|
||||||
else if (!audio_playing) {
|
|
||||||
SDL_ClearQueuedAudio(device_id);
|
|
||||||
SDL_PauseAudioDevice(device_id, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -336,15 +320,15 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
case SDL_KEYUP: // Fallthrough
|
case SDL_KEYUP: // Fallthrough
|
||||||
if (event.key.keysym.scancode == configuration.keys[8]) {
|
if (event.key.keysym.scancode == configuration.keys[8]) {
|
||||||
turbo_down = event.type == SDL_KEYDOWN;
|
turbo_down = event.type == SDL_KEYDOWN;
|
||||||
SDL_ClearQueuedAudio(device_id);
|
GB_audio_clear_queue();
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
update_turbo_mode();
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.scancode == configuration.keys_2[0]) {
|
else if (event.key.keysym.scancode == configuration.keys_2[0]) {
|
||||||
rewind_down = event.type == SDL_KEYDOWN;
|
rewind_down = event.type == SDL_KEYDOWN;
|
||||||
if (event.type == SDL_KEYUP) {
|
if (event.type == SDL_KEYUP) {
|
||||||
rewind_paused = false;
|
rewind_paused = false;
|
||||||
}
|
}
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
update_turbo_mode();
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.scancode == configuration.keys_2[1]) {
|
else if (event.key.keysym.scancode == configuration.keys_2[1]) {
|
||||||
underclock_down = event.type == SDL_KEYDOWN;
|
underclock_down = event.type == SDL_KEYDOWN;
|
||||||
@ -409,15 +393,15 @@ static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample)
|
|||||||
if (turbo_down) {
|
if (turbo_down) {
|
||||||
static unsigned skip = 0;
|
static unsigned skip = 0;
|
||||||
skip++;
|
skip++;
|
||||||
if (skip == have_aspec.freq / 8) {
|
if (skip == GB_audio_get_frequency() / 8) {
|
||||||
skip = 0;
|
skip = 0;
|
||||||
}
|
}
|
||||||
if (skip > have_aspec.freq / 16) {
|
if (skip > GB_audio_get_frequency() / 16) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_GetQueuedAudioSize(device_id) / sizeof(*sample) > have_aspec.freq / 4) {
|
if (GB_audio_get_queue_length() / sizeof(*sample) > GB_audio_get_frequency() / 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +410,7 @@ static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample)
|
|||||||
sample->right = sample->right * configuration.volume / 100;
|
sample->right = sample->right * configuration.volume / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QueueAudio(device_id, sample, sizeof(*sample));
|
GB_audio_queue_sample(sample);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +498,7 @@ restart:
|
|||||||
GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank);
|
GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank);
|
||||||
GB_set_pixels_output(&gb, active_pixel_buffer);
|
GB_set_pixels_output(&gb, active_pixel_buffer);
|
||||||
GB_set_rgb_encode_callback(&gb, rgb_encode);
|
GB_set_rgb_encode_callback(&gb, rgb_encode);
|
||||||
GB_set_sample_rate(&gb, have_aspec.freq);
|
GB_set_sample_rate(&gb, GB_audio_get_frequency());
|
||||||
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
||||||
update_palette();
|
update_palette();
|
||||||
if ((unsigned)configuration.border_mode <= GB_BORDER_ALWAYS) {
|
if ((unsigned)configuration.border_mode <= GB_BORDER_ALWAYS) {
|
||||||
@ -641,7 +625,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
signal(SIGINT, debugger_interrupt);
|
signal(SIGINT, debugger_interrupt);
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_EVERYTHING);
|
SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO);
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||||
@ -675,34 +659,7 @@ int main(int argc, char **argv)
|
|||||||
pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
|
pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GB_audio_init();
|
||||||
/* Configure Audio */
|
|
||||||
memset(&want_aspec, 0, sizeof(want_aspec));
|
|
||||||
want_aspec.freq = AUDIO_FREQUENCY;
|
|
||||||
want_aspec.format = AUDIO_S16SYS;
|
|
||||||
want_aspec.channels = 2;
|
|
||||||
want_aspec.samples = 512;
|
|
||||||
|
|
||||||
SDL_version _sdl_version;
|
|
||||||
SDL_GetVersion(&_sdl_version);
|
|
||||||
unsigned sdl_version = _sdl_version.major * 1000 + _sdl_version.minor * 100 + _sdl_version.patch;
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/* SDL 2.0.5 on macOS and Linux introduced a bug where certain combinations of buffer lengths and frequencies
|
|
||||||
fail to produce audio correctly. */
|
|
||||||
if (sdl_version >= 2005) {
|
|
||||||
want_aspec.samples = 2048;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (sdl_version < 2006) {
|
|
||||||
/* Since WASAPI audio was introduced in SDL 2.0.6, we have to lower the audio frequency
|
|
||||||
to 44100 because otherwise we would get garbled audio output.*/
|
|
||||||
want_aspec.freq = 44100;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
device_id = SDL_OpenAudioDevice(0, 0, &want_aspec, &have_aspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
|
||||||
/* Start Audio */
|
|
||||||
|
|
||||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||||
|
|
||||||
@ -735,7 +692,8 @@ int main(int argc, char **argv)
|
|||||||
else {
|
else {
|
||||||
connect_joypad();
|
connect_joypad();
|
||||||
}
|
}
|
||||||
SDL_PauseAudioDevice(device_id, 0);
|
GB_audio_set_paused(false);
|
||||||
|
update_turbo_mode();
|
||||||
run(); // Never returns
|
run(); // Never returns
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user