mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-22 23:49:50 +00:00
Merge midi_driver.c and location_driver.c into retroarch.c -
files were not touched for 6 months so splitting them up serves no real purpose
This commit is contained in:
parent
230503b206
commit
10082e1c32
@ -242,8 +242,6 @@ OBJ += frontend/frontend_driver.o \
|
||||
record/record_driver.o \
|
||||
command.o \
|
||||
msg_hash.o \
|
||||
midi_driver.o \
|
||||
location_driver.o \
|
||||
intl/msg_hash_us.o \
|
||||
$(LIBRETRO_COMM_DIR)/queues/task_queue.o \
|
||||
tasks/task_content.o
|
||||
|
@ -1906,7 +1906,7 @@ void rcheevos_test(void)
|
||||
#ifdef HAVE_THREADS
|
||||
if (rcheevos_locals.queued_command != CMD_EVENT_NONE)
|
||||
{
|
||||
if (rcheevos_locals.queued_command != CMD_CHEEVOS_NON_COMMAND)
|
||||
if ((int)rcheevos_locals.queued_command != CMD_CHEEVOS_NON_COMMAND)
|
||||
command_event(rcheevos_locals.queued_command, NULL);
|
||||
|
||||
rcheevos_locals.queued_command = CMD_EVENT_NONE;
|
||||
|
@ -1170,8 +1170,6 @@ RETROARCH
|
||||
#include "../runahead.c"
|
||||
#endif
|
||||
#include "../command.c"
|
||||
#include "../midi_driver.c"
|
||||
#include "../location_driver.c"
|
||||
#include "../ui/ui_companion_driver.c"
|
||||
#include "../libretro-common/queues/task_queue.c"
|
||||
|
||||
|
@ -1,205 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2021 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch 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 RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "configuration.h"
|
||||
#include "driver.h"
|
||||
#include "list_special.h"
|
||||
#include "location_driver.h"
|
||||
#include "retroarch.h"
|
||||
#include "runloop.h"
|
||||
#include "verbosity.h"
|
||||
|
||||
static location_driver_t location_null = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"null",
|
||||
};
|
||||
|
||||
const location_driver_t *location_drivers[] = {
|
||||
#ifdef ANDROID
|
||||
&location_android,
|
||||
#endif
|
||||
&location_null,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static location_driver_state_t location_driver_st = {0};
|
||||
|
||||
location_driver_state_t *location_state_get_ptr(void)
|
||||
{
|
||||
return &location_driver_st;
|
||||
}
|
||||
|
||||
const char *config_get_location_driver_options(void)
|
||||
{
|
||||
return char_list_new_special(STRING_LIST_LOCATION_DRIVERS, NULL);
|
||||
}
|
||||
|
||||
void location_driver_find_driver(
|
||||
settings_t *settings,
|
||||
const char *prefix,
|
||||
bool verbosity_enabled)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
int i = (int)driver_find_index(
|
||||
"location_driver",
|
||||
settings->arrays.location_driver);
|
||||
|
||||
if (i >= 0)
|
||||
location_st->driver = (const location_driver_t*)
|
||||
location_drivers[i];
|
||||
else
|
||||
{
|
||||
if (verbosity_enabled)
|
||||
{
|
||||
unsigned d;
|
||||
RARCH_ERR("Couldn't find any %s named \"%s\"\n", prefix,
|
||||
settings->arrays.location_driver);
|
||||
RARCH_LOG_OUTPUT("Available %ss are:\n", prefix);
|
||||
for (d = 0; location_drivers[d]; d++)
|
||||
RARCH_LOG_OUTPUT("\t%s\n", location_drivers[d]->ident);
|
||||
|
||||
RARCH_WARN("Going to default to first %s...\n", prefix);
|
||||
}
|
||||
|
||||
location_st->driver = (const location_driver_t*)location_drivers[0];
|
||||
}
|
||||
}
|
||||
|
||||
bool driver_location_start(void)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->data
|
||||
&& location_st->driver
|
||||
&& location_st->driver->start)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool location_allow = settings->bools.location_allow;
|
||||
if (location_allow)
|
||||
return location_st->driver->start(location_st->data);
|
||||
|
||||
runloop_msg_queue_push("Location is explicitly disabled.\n",
|
||||
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
|
||||
MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void driver_location_stop(void)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->stop
|
||||
&& location_st->data)
|
||||
location_st->driver->stop(location_st->data);
|
||||
}
|
||||
|
||||
void driver_location_set_interval(unsigned interval_msecs,
|
||||
unsigned interval_distance)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->set_interval
|
||||
&& location_st->data)
|
||||
location_st->driver->set_interval(location_st->data,
|
||||
interval_msecs, interval_distance);
|
||||
}
|
||||
|
||||
bool driver_location_get_position(double *lat, double *lon,
|
||||
double *horiz_accuracy, double *vert_accuracy)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->get_position
|
||||
&& location_st->data)
|
||||
return location_st->driver->get_position(location_st->data,
|
||||
lat, lon, horiz_accuracy, vert_accuracy);
|
||||
|
||||
*lat = 0.0;
|
||||
*lon = 0.0;
|
||||
*horiz_accuracy = 0.0;
|
||||
*vert_accuracy = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool init_location(
|
||||
void *data,
|
||||
settings_t *settings,
|
||||
bool verbosity_enabled)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
|
||||
/* Resource leaks will follow if location
|
||||
interface is initialized twice. */
|
||||
if (!location_st->data)
|
||||
{
|
||||
rarch_system_info_t *sys_info = (rarch_system_info_t*)data;
|
||||
location_driver_find_driver(settings,
|
||||
"location driver", verbosity_enabled);
|
||||
|
||||
if (!(location_st->data = location_st->driver->init()))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize location driver. Will continue without location.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sys_info->location_cb.initialized)
|
||||
sys_info->location_cb.initialized();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void uninit_location(void *data)
|
||||
{
|
||||
location_driver_state_t *location_st = &location_driver_st;
|
||||
|
||||
if (location_st->data && location_st->driver)
|
||||
{
|
||||
rarch_system_info_t *sys_info = (rarch_system_info_t*)data;
|
||||
if (sys_info->location_cb.deinitialized)
|
||||
sys_info->location_cb.deinitialized();
|
||||
|
||||
if (location_st->driver->free)
|
||||
location_st->driver->free(location_st->data);
|
||||
}
|
||||
|
||||
location_st->active = false;
|
||||
location_st->data = NULL;
|
||||
}
|
||||
|
||||
void destroy_location(void)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
|
||||
location_st->active = false;
|
||||
location_st->driver = NULL;
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef struct location_driver
|
||||
@ -103,27 +101,11 @@ void driver_location_stop(void);
|
||||
**/
|
||||
bool driver_location_start(void);
|
||||
|
||||
void destroy_location(void);
|
||||
|
||||
void location_driver_find_driver(
|
||||
settings_t *settings,
|
||||
const char *prefix,
|
||||
bool verbosity_enabled);
|
||||
|
||||
void uninit_location(void *data);
|
||||
|
||||
bool init_location(
|
||||
void *data,
|
||||
settings_t *settings,
|
||||
bool verbosity_enabled);
|
||||
|
||||
location_driver_state_t *location_state_get_ptr(void);
|
||||
|
||||
extern location_driver_t location_corelocation;
|
||||
extern location_driver_t location_android;
|
||||
|
||||
extern const location_driver_t *location_drivers[];
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
634
midi_driver.c
634
midi_driver.c
@ -1,634 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2021 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch 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 RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boolean.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "midi_driver.h"
|
||||
#include "verbosity.h"
|
||||
|
||||
#ifdef HAVE_WASAPI
|
||||
#include "audio/audio_driver.h"
|
||||
#include "gfx/video_driver.h"
|
||||
#endif
|
||||
|
||||
#define MIDI_DRIVER_BUF_SIZE 4096
|
||||
#define MIDI_DRIVER_OFF "OFF"
|
||||
|
||||
static void *rarch_midi_drv_data;
|
||||
static struct string_list *rarch_midi_drv_inputs;
|
||||
static struct string_list *rarch_midi_drv_outputs;
|
||||
static uint8_t *rarch_midi_drv_input_buffer;
|
||||
static uint8_t *rarch_midi_drv_output_buffer;
|
||||
|
||||
static midi_event_t rarch_midi_drv_input_event; /* ptr alignment */
|
||||
static midi_event_t rarch_midi_drv_output_event; /* ptr alignment */
|
||||
|
||||
static bool rarch_midi_drv_input_enabled;
|
||||
static bool rarch_midi_drv_output_enabled;
|
||||
static bool rarch_midi_drv_output_pending;
|
||||
|
||||
static void null_midi_free(void *p) { }
|
||||
static void *null_midi_init(const char *input, const char *output) { return (void*)-1; }
|
||||
static bool null_midi_get_avail_inputs(struct string_list *inputs) { union string_list_elem_attr attr = {0}; return string_list_append(inputs, "Null", attr); }
|
||||
static bool null_midi_get_avail_outputs(struct string_list *outputs) { union string_list_elem_attr attr = {0}; return string_list_append(outputs, "Null", attr); }
|
||||
static bool null_midi_set_input(void *p, const char *input) { return input == NULL || string_is_equal(input, "Null"); }
|
||||
static bool null_midi_set_output(void *p, const char *output) { return output == NULL || string_is_equal(output, "Null"); }
|
||||
static bool null_midi_read(void *p, midi_event_t *event) { return false; }
|
||||
static bool null_midi_write(void *p, const midi_event_t *event) { return true; }
|
||||
static bool null_midi_flush(void *p) { return true; }
|
||||
|
||||
static midi_driver_t midi_null = {
|
||||
"null",
|
||||
null_midi_get_avail_inputs,
|
||||
null_midi_get_avail_outputs,
|
||||
null_midi_init,
|
||||
null_midi_free,
|
||||
null_midi_set_input,
|
||||
null_midi_set_output,
|
||||
null_midi_read,
|
||||
null_midi_write,
|
||||
null_midi_flush
|
||||
};
|
||||
|
||||
static midi_driver_t *midi_drv = &midi_null;
|
||||
|
||||
midi_driver_t *midi_drivers[] = {
|
||||
#if defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) && !defined(DINGUX)
|
||||
&midi_alsa,
|
||||
#endif
|
||||
#ifdef HAVE_WINMM
|
||||
&midi_winmm,
|
||||
#endif
|
||||
&midi_null
|
||||
};
|
||||
|
||||
static midi_driver_t *midi_driver_find_driver(const char *ident)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(midi_drivers); ++i)
|
||||
{
|
||||
if (string_is_equal(midi_drivers[i]->ident, ident))
|
||||
return midi_drivers[i];
|
||||
}
|
||||
|
||||
RARCH_ERR("[MIDI]: Unknown driver \"%s\", falling back to \"null\" driver.\n", ident);
|
||||
|
||||
return &midi_null;
|
||||
}
|
||||
|
||||
const void *midi_driver_find_handle(int index)
|
||||
{
|
||||
if (index < 0 || index >= (int)ARRAY_SIZE(midi_drivers))
|
||||
return NULL;
|
||||
|
||||
return midi_drivers[index];
|
||||
}
|
||||
|
||||
struct string_list *midi_driver_get_avail_inputs(void)
|
||||
{
|
||||
return rarch_midi_drv_inputs;
|
||||
}
|
||||
|
||||
struct string_list *midi_driver_get_avail_outputs(void)
|
||||
{
|
||||
return rarch_midi_drv_outputs;
|
||||
}
|
||||
|
||||
bool midi_driver_set_all_sounds_off(void)
|
||||
{
|
||||
midi_event_t event;
|
||||
uint8_t i;
|
||||
uint8_t data[3] = { 0xB0, 120, 0 };
|
||||
bool result = true;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_WASAPI
|
||||
/* FIXME: Due to some mysterious reason Frame Delay does not
|
||||
* work with WASAPI unless MIDI output is active, even when
|
||||
* MIDI is not used. Frame Delay also breaks if MIDI sounds
|
||||
* are "set off", which happens on menu toggle, therefore
|
||||
* skip this if WASAPI is used and Frame Delay is active.. */
|
||||
if (string_is_equal(audio_state_get_ptr()->current_audio->ident, "wasapi"))
|
||||
{
|
||||
if (video_state_get_ptr()->frame_delay_target > 0)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
event.data = data;
|
||||
event.data_size = sizeof(data);
|
||||
event.delta_time = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
data[0] = 0xB0 | i;
|
||||
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &event))
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!midi_drv->flush(rarch_midi_drv_data))
|
||||
result = false;
|
||||
|
||||
if (!result)
|
||||
RARCH_ERR("[MIDI]: All sounds off failed.\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool midi_driver_set_volume(unsigned volume)
|
||||
{
|
||||
midi_event_t event;
|
||||
uint8_t data[8] = {
|
||||
0xF0, 0x7F, 0x7F, 0x04, 0x01, 0, 0, 0xF7};
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
return false;
|
||||
|
||||
volume = (unsigned)(163.83 * volume + 0.5);
|
||||
if (volume > 16383)
|
||||
volume = 16383;
|
||||
|
||||
data[5] = (uint8_t)(volume & 0x7F);
|
||||
data[6] = (uint8_t)(volume >> 7);
|
||||
|
||||
event.data = data;
|
||||
event.data_size = sizeof(data);
|
||||
event.delta_time = 0;
|
||||
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &event))
|
||||
{
|
||||
RARCH_ERR("[MIDI]: Volume change failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool midi_driver_init_io_buffers(void)
|
||||
{
|
||||
uint8_t *midi_drv_input_buffer = (uint8_t*)malloc(MIDI_DRIVER_BUF_SIZE);
|
||||
uint8_t *midi_drv_output_buffer = (uint8_t*)malloc(MIDI_DRIVER_BUF_SIZE);
|
||||
|
||||
if (!midi_drv_input_buffer || !midi_drv_output_buffer)
|
||||
{
|
||||
if (midi_drv_input_buffer)
|
||||
free(midi_drv_input_buffer);
|
||||
if (midi_drv_output_buffer)
|
||||
free(midi_drv_output_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
rarch_midi_drv_input_buffer = midi_drv_input_buffer;
|
||||
rarch_midi_drv_output_buffer = midi_drv_output_buffer;
|
||||
|
||||
rarch_midi_drv_input_event.data = midi_drv_input_buffer;
|
||||
rarch_midi_drv_input_event.data_size = 0;
|
||||
|
||||
rarch_midi_drv_output_event.data = midi_drv_output_buffer;
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void midi_driver_free(void)
|
||||
{
|
||||
if (rarch_midi_drv_data)
|
||||
{
|
||||
midi_drv->free(rarch_midi_drv_data);
|
||||
rarch_midi_drv_data = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_inputs)
|
||||
{
|
||||
string_list_free(rarch_midi_drv_inputs);
|
||||
rarch_midi_drv_inputs = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_outputs)
|
||||
{
|
||||
string_list_free(rarch_midi_drv_outputs);
|
||||
rarch_midi_drv_outputs = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_input_buffer)
|
||||
{
|
||||
free(rarch_midi_drv_input_buffer);
|
||||
rarch_midi_drv_input_buffer = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_output_buffer)
|
||||
{
|
||||
free(rarch_midi_drv_output_buffer);
|
||||
rarch_midi_drv_output_buffer = NULL;
|
||||
}
|
||||
|
||||
rarch_midi_drv_input_enabled = false;
|
||||
rarch_midi_drv_output_enabled = false;
|
||||
}
|
||||
|
||||
bool midi_driver_init(void *data)
|
||||
{
|
||||
union string_list_elem_attr
|
||||
attr = {0};
|
||||
bool ret = true;
|
||||
settings_t *settings = (settings_t*)data;
|
||||
|
||||
rarch_midi_drv_inputs = string_list_new();
|
||||
rarch_midi_drv_outputs = string_list_new();
|
||||
|
||||
if (!rarch_midi_drv_inputs || !rarch_midi_drv_outputs)
|
||||
ret = false;
|
||||
else if (!string_list_append(rarch_midi_drv_inputs, MIDI_DRIVER_OFF, attr) ||
|
||||
!string_list_append(rarch_midi_drv_outputs, MIDI_DRIVER_OFF, attr))
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
char * input = NULL;
|
||||
char * output = NULL;
|
||||
|
||||
midi_drv = midi_driver_find_driver(
|
||||
settings->arrays.midi_driver);
|
||||
|
||||
if (strcmp(midi_drv->ident, settings->arrays.midi_driver))
|
||||
{
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_driver, midi_drv->ident);
|
||||
}
|
||||
|
||||
if (!midi_drv->get_avail_inputs(rarch_midi_drv_inputs))
|
||||
ret = false;
|
||||
else if (!midi_drv->get_avail_outputs(rarch_midi_drv_outputs))
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
if (string_is_not_equal(settings->arrays.midi_input, MIDI_DRIVER_OFF))
|
||||
{
|
||||
if (string_list_find_elem(rarch_midi_drv_inputs, settings->arrays.midi_input))
|
||||
input = settings->arrays.midi_input;
|
||||
else
|
||||
{
|
||||
RARCH_WARN("[MIDI]: Input device \"%s\" unavailable.\n",
|
||||
settings->arrays.midi_input);
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_input, MIDI_DRIVER_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (string_is_not_equal(settings->arrays.midi_output, MIDI_DRIVER_OFF))
|
||||
{
|
||||
if (string_list_find_elem(rarch_midi_drv_outputs, settings->arrays.midi_output))
|
||||
output = settings->arrays.midi_output;
|
||||
else
|
||||
{
|
||||
RARCH_WARN("[MIDI]: Output device \"%s\" unavailable.\n",
|
||||
settings->arrays.midi_output);
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_output, MIDI_DRIVER_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
rarch_midi_drv_data = midi_drv->init(input, output);
|
||||
if (!rarch_midi_drv_data)
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
rarch_midi_drv_input_enabled = (input != NULL);
|
||||
rarch_midi_drv_output_enabled = (output != NULL);
|
||||
|
||||
if (!midi_driver_init_io_buffers())
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
if (input)
|
||||
RARCH_LOG("[MIDI]: Input device: \"%s\".\n", input);
|
||||
|
||||
if (output)
|
||||
{
|
||||
RARCH_LOG("[MIDI]: Output device: \"%s\".\n", output);
|
||||
midi_driver_set_volume(settings->uints.midi_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
midi_driver_free();
|
||||
RARCH_ERR("[MIDI]: Initialization failed.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_set_input(const char *input)
|
||||
{
|
||||
if (!rarch_midi_drv_data)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_set_input called on uninitialized driver.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_equal(input, MIDI_DRIVER_OFF))
|
||||
input = NULL;
|
||||
|
||||
if (!midi_drv->set_input(rarch_midi_drv_data, input))
|
||||
{
|
||||
if (input)
|
||||
RARCH_ERR("[MIDI]: Failed to change input device to \"%s\".\n", input);
|
||||
else
|
||||
RARCH_ERR("[MIDI]: Failed to disable input.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input)
|
||||
RARCH_LOG("[MIDI]: Input device changed to \"%s\".\n", input);
|
||||
else
|
||||
RARCH_LOG("[MIDI]: Input disabled.\n");
|
||||
|
||||
rarch_midi_drv_input_enabled = input != NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_set_output(void *settings_data, const char *output)
|
||||
{
|
||||
settings_t *settings = (settings_t*)settings_data;
|
||||
|
||||
if (!rarch_midi_drv_data)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_set_output called on uninitialized driver.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_equal(output, MIDI_DRIVER_OFF))
|
||||
output = NULL;
|
||||
|
||||
if (!midi_drv->set_output(rarch_midi_drv_data, output))
|
||||
{
|
||||
if (output)
|
||||
RARCH_ERR("[MIDI]: Failed to change output device to \"%s\".\n", output);
|
||||
else
|
||||
RARCH_ERR("[MIDI]: Failed to disable output.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output)
|
||||
{
|
||||
rarch_midi_drv_output_enabled = true;
|
||||
RARCH_LOG("[MIDI]: Output device changed to \"%s\".\n", output);
|
||||
|
||||
midi_driver_set_volume(settings->uints.midi_volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
rarch_midi_drv_output_enabled = false;
|
||||
RARCH_LOG("[MIDI]: Output disabled.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_input_enabled(void)
|
||||
{
|
||||
return rarch_midi_drv_input_enabled;
|
||||
}
|
||||
|
||||
bool midi_driver_output_enabled(void)
|
||||
{
|
||||
return rarch_midi_drv_output_enabled;
|
||||
}
|
||||
|
||||
bool midi_driver_read(uint8_t *byte)
|
||||
{
|
||||
static int i = 0;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_input_enabled || !byte)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!rarch_midi_drv_data)
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called on uninitialized driver.\n");
|
||||
else if (!rarch_midi_drv_input_enabled)
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called when input is disabled.\n");
|
||||
else
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called with null pointer.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == (int)rarch_midi_drv_input_event.data_size)
|
||||
{
|
||||
rarch_midi_drv_input_event.data_size = MIDI_DRIVER_BUF_SIZE;
|
||||
if (!midi_drv->read(rarch_midi_drv_data, &rarch_midi_drv_input_event))
|
||||
{
|
||||
rarch_midi_drv_input_event.data_size = i;
|
||||
return false;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (rarch_midi_drv_input_event.data_size == 1)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0]);
|
||||
else if (rarch_midi_drv_input_event.data_size == 2)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data[1]);
|
||||
else if (rarch_midi_drv_input_event.data_size == 3)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data[1],
|
||||
rarch_midi_drv_input_event.data[2]);
|
||||
else
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
*byte = rarch_midi_drv_input_event.data[i++];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_write(uint8_t byte, uint32_t delta_time)
|
||||
{
|
||||
static int event_size;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!rarch_midi_drv_data)
|
||||
RARCH_ERR("[MIDI]: midi_driver_write called on uninitialized driver.\n");
|
||||
else
|
||||
RARCH_ERR("[MIDI]: midi_driver_write called when output is disabled.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (byte >= 0x80)
|
||||
{
|
||||
if ( rarch_midi_drv_output_event.data_size
|
||||
&& rarch_midi_drv_output_event.data[0] == 0xF0)
|
||||
{
|
||||
if (byte == 0xF7)
|
||||
event_size = (int)rarch_midi_drv_output_event.data_size + 1;
|
||||
else
|
||||
{
|
||||
if (!midi_drv->write(rarch_midi_drv_data,
|
||||
&rarch_midi_drv_output_event))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
case 1:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0]);
|
||||
break;
|
||||
case 2:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1]);
|
||||
break;
|
||||
case 3:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1],
|
||||
rarch_midi_drv_output_event.data[2]);
|
||||
break;
|
||||
default:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data_size);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
rarch_midi_drv_output_pending = true;
|
||||
event_size = (int)midi_driver_get_event_size(byte);
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event_size = (int)midi_driver_get_event_size(byte);
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_output_event.data_size < MIDI_DRIVER_BUF_SIZE)
|
||||
{
|
||||
rarch_midi_drv_output_event.data[rarch_midi_drv_output_event.data_size] = byte;
|
||||
++rarch_midi_drv_output_event.data_size;
|
||||
rarch_midi_drv_output_event.delta_time += delta_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: Output event dropped.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event_size == (int)rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &rarch_midi_drv_output_event))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
case 1:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0]);
|
||||
break;
|
||||
case 2:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1]);
|
||||
break;
|
||||
case 3:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1],
|
||||
rarch_midi_drv_output_event.data[2]);
|
||||
break;
|
||||
default:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data_size);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
rarch_midi_drv_output_pending = true;
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_flush(void)
|
||||
{
|
||||
if (!rarch_midi_drv_data)
|
||||
return false;
|
||||
|
||||
if (rarch_midi_drv_output_pending)
|
||||
rarch_midi_drv_output_pending = !midi_drv->flush(rarch_midi_drv_data);
|
||||
|
||||
return !rarch_midi_drv_output_pending;
|
||||
}
|
||||
|
||||
size_t midi_driver_get_event_size(uint8_t status)
|
||||
{
|
||||
static const uint8_t midi_drv_ev_sizes[128] =
|
||||
{
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
0, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
if (status < 0x80)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_get_event_size called with invalid status.\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
return midi_drv_ev_sizes[status - 0x80];
|
||||
}
|
@ -232,14 +232,8 @@ bool midi_driver_read(uint8_t *byte);
|
||||
|
||||
bool midi_driver_write(uint8_t byte, uint32_t delta_time);
|
||||
|
||||
bool midi_driver_init(void *data);
|
||||
|
||||
void midi_driver_free(void);
|
||||
|
||||
bool midi_driver_set_all_sounds_off(void);
|
||||
|
||||
const void *midi_driver_find_handle(int index);
|
||||
|
||||
extern midi_driver_t midi_winmm;
|
||||
extern midi_driver_t midi_alsa;
|
||||
|
||||
|
783
retroarch.c
783
retroarch.c
@ -114,6 +114,8 @@
|
||||
#include "menu/menu_driver.h"
|
||||
#endif
|
||||
|
||||
#include "location_driver.h"
|
||||
|
||||
#include "runloop.h"
|
||||
#include "camera/camera_driver.h"
|
||||
#include "location_driver.h"
|
||||
@ -255,6 +257,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MIDI_DRIVER_BUF_SIZE 4096
|
||||
#define MIDI_DRIVER_OFF "OFF"
|
||||
|
||||
/* Descriptive names for options without short variant.
|
||||
*
|
||||
* Please keep the name in sync with the option name.
|
||||
@ -338,6 +343,778 @@ static void retro_frame_null(const void *data, unsigned width,
|
||||
unsigned height, size_t pitch) { }
|
||||
void retro_input_poll_null(void) { }
|
||||
|
||||
static location_driver_t location_null = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"null",
|
||||
};
|
||||
|
||||
static const location_driver_t *location_drivers[] = {
|
||||
#ifdef ANDROID
|
||||
&location_android,
|
||||
#endif
|
||||
&location_null,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static location_driver_state_t location_driver_st = {0};
|
||||
|
||||
location_driver_state_t *location_state_get_ptr(void)
|
||||
{
|
||||
return &location_driver_st;
|
||||
}
|
||||
|
||||
const char *config_get_location_driver_options(void)
|
||||
{
|
||||
return char_list_new_special(STRING_LIST_LOCATION_DRIVERS, NULL);
|
||||
}
|
||||
|
||||
static void location_driver_find_driver(
|
||||
settings_t *settings,
|
||||
location_driver_state_t *location_st,
|
||||
const char *prefix,
|
||||
bool verbosity_enabled)
|
||||
{
|
||||
int i = (int)driver_find_index(
|
||||
"location_driver",
|
||||
settings->arrays.location_driver);
|
||||
|
||||
if (i >= 0)
|
||||
location_st->driver = (const location_driver_t*)
|
||||
location_drivers[i];
|
||||
else
|
||||
{
|
||||
if (verbosity_enabled)
|
||||
{
|
||||
unsigned d;
|
||||
RARCH_ERR("Couldn't find any %s named \"%s\"\n", prefix,
|
||||
settings->arrays.location_driver);
|
||||
RARCH_LOG_OUTPUT("Available %ss are:\n", prefix);
|
||||
for (d = 0; location_drivers[d]; d++)
|
||||
RARCH_LOG_OUTPUT("\t%s\n", location_drivers[d]->ident);
|
||||
|
||||
RARCH_WARN("Going to default to first %s...\n", prefix);
|
||||
}
|
||||
|
||||
location_st->driver = (const location_driver_t*)location_drivers[0];
|
||||
}
|
||||
}
|
||||
|
||||
bool driver_location_start(void)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->data
|
||||
&& location_st->driver
|
||||
&& location_st->driver->start)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool location_allow = settings->bools.location_allow;
|
||||
if (location_allow)
|
||||
return location_st->driver->start(location_st->data);
|
||||
|
||||
runloop_msg_queue_push("Location is explicitly disabled.\n",
|
||||
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
|
||||
MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void driver_location_stop(void)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->stop
|
||||
&& location_st->data)
|
||||
location_st->driver->stop(location_st->data);
|
||||
}
|
||||
|
||||
void driver_location_set_interval(unsigned interval_msecs,
|
||||
unsigned interval_distance)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->set_interval
|
||||
&& location_st->data)
|
||||
location_st->driver->set_interval(location_st->data,
|
||||
interval_msecs, interval_distance);
|
||||
}
|
||||
|
||||
bool driver_location_get_position(double *lat, double *lon,
|
||||
double *horiz_accuracy, double *vert_accuracy)
|
||||
{
|
||||
location_driver_state_t
|
||||
*location_st = &location_driver_st;
|
||||
if ( location_st
|
||||
&& location_st->driver
|
||||
&& location_st->driver->get_position
|
||||
&& location_st->data)
|
||||
return location_st->driver->get_position(location_st->data,
|
||||
lat, lon, horiz_accuracy, vert_accuracy);
|
||||
|
||||
*lat = 0.0;
|
||||
*lon = 0.0;
|
||||
*horiz_accuracy = 0.0;
|
||||
*vert_accuracy = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool init_location(
|
||||
void *data,
|
||||
location_driver_state_t *location_st,
|
||||
settings_t *settings,
|
||||
bool verbosity_enabled)
|
||||
{
|
||||
/* Resource leaks will follow if location
|
||||
interface is initialized twice. */
|
||||
if (!location_st->data)
|
||||
{
|
||||
rarch_system_info_t *sys_info = (rarch_system_info_t*)data;
|
||||
location_driver_find_driver(settings,
|
||||
&location_driver_st,
|
||||
"location driver", verbosity_enabled);
|
||||
|
||||
if (!(location_st->data = location_st->driver->init()))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize location driver. Will continue without location.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sys_info->location_cb.initialized)
|
||||
sys_info->location_cb.initialized();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void uninit_location(void *data, location_driver_state_t *location_st)
|
||||
{
|
||||
if (location_st->data && location_st->driver)
|
||||
{
|
||||
rarch_system_info_t *sys_info = (rarch_system_info_t*)data;
|
||||
if (sys_info->location_cb.deinitialized)
|
||||
sys_info->location_cb.deinitialized();
|
||||
|
||||
if (location_st->driver->free)
|
||||
location_st->driver->free(location_st->data);
|
||||
}
|
||||
|
||||
location_st->active = false;
|
||||
location_st->data = NULL;
|
||||
}
|
||||
|
||||
static void *rarch_midi_drv_data;
|
||||
static struct string_list *rarch_midi_drv_inputs;
|
||||
static struct string_list *rarch_midi_drv_outputs;
|
||||
static uint8_t *rarch_midi_drv_input_buffer;
|
||||
static uint8_t *rarch_midi_drv_output_buffer;
|
||||
|
||||
static midi_event_t rarch_midi_drv_input_event; /* ptr alignment */
|
||||
static midi_event_t rarch_midi_drv_output_event; /* ptr alignment */
|
||||
|
||||
static bool rarch_midi_drv_input_enabled;
|
||||
static bool rarch_midi_drv_output_enabled;
|
||||
static bool rarch_midi_drv_output_pending;
|
||||
|
||||
static void null_midi_free(void *p) { }
|
||||
static void *null_midi_init(const char *input, const char *output) { return (void*)-1; }
|
||||
static bool null_midi_get_avail_inputs(struct string_list *inputs) { union string_list_elem_attr attr = {0}; return string_list_append(inputs, "Null", attr); }
|
||||
static bool null_midi_get_avail_outputs(struct string_list *outputs) { union string_list_elem_attr attr = {0}; return string_list_append(outputs, "Null", attr); }
|
||||
static bool null_midi_set_input(void *p, const char *input) { return input == NULL || string_is_equal(input, "Null"); }
|
||||
static bool null_midi_set_output(void *p, const char *output) { return output == NULL || string_is_equal(output, "Null"); }
|
||||
static bool null_midi_read(void *p, midi_event_t *event) { return false; }
|
||||
static bool null_midi_write(void *p, const midi_event_t *event) { return true; }
|
||||
static bool null_midi_flush(void *p) { return true; }
|
||||
|
||||
static midi_driver_t midi_null = {
|
||||
"null",
|
||||
null_midi_get_avail_inputs,
|
||||
null_midi_get_avail_outputs,
|
||||
null_midi_init,
|
||||
null_midi_free,
|
||||
null_midi_set_input,
|
||||
null_midi_set_output,
|
||||
null_midi_read,
|
||||
null_midi_write,
|
||||
null_midi_flush
|
||||
};
|
||||
|
||||
static midi_driver_t *midi_drv = &midi_null;
|
||||
|
||||
midi_driver_t *midi_drivers[] = {
|
||||
#if defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) && !defined(DINGUX)
|
||||
&midi_alsa,
|
||||
#endif
|
||||
#ifdef HAVE_WINMM
|
||||
&midi_winmm,
|
||||
#endif
|
||||
&midi_null
|
||||
};
|
||||
|
||||
static midi_driver_t *midi_driver_find_driver(const char *ident)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(midi_drivers); ++i)
|
||||
{
|
||||
if (string_is_equal(midi_drivers[i]->ident, ident))
|
||||
return midi_drivers[i];
|
||||
}
|
||||
|
||||
RARCH_ERR("[MIDI]: Unknown driver \"%s\", falling back to \"null\" driver.\n", ident);
|
||||
|
||||
return &midi_null;
|
||||
}
|
||||
|
||||
static const void *midi_driver_find_handle(int index)
|
||||
{
|
||||
if (index < 0 || index >= (int)ARRAY_SIZE(midi_drivers))
|
||||
return NULL;
|
||||
|
||||
return midi_drivers[index];
|
||||
}
|
||||
|
||||
struct string_list *midi_driver_get_avail_inputs(void)
|
||||
{
|
||||
return rarch_midi_drv_inputs;
|
||||
}
|
||||
|
||||
struct string_list *midi_driver_get_avail_outputs(void)
|
||||
{
|
||||
return rarch_midi_drv_outputs;
|
||||
}
|
||||
|
||||
bool midi_driver_set_all_sounds_off(void)
|
||||
{
|
||||
midi_event_t event;
|
||||
uint8_t i;
|
||||
uint8_t data[3] = { 0xB0, 120, 0 };
|
||||
bool result = true;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_WASAPI
|
||||
/* FIXME: Due to some mysterious reason Frame Delay does not
|
||||
* work with WASAPI unless MIDI output is active, even when
|
||||
* MIDI is not used. Frame Delay also breaks if MIDI sounds
|
||||
* are "set off", which happens on menu toggle, therefore
|
||||
* skip this if WASAPI is used and Frame Delay is active.. */
|
||||
if (string_is_equal(audio_state_get_ptr()->current_audio->ident, "wasapi"))
|
||||
{
|
||||
if (video_state_get_ptr()->frame_delay_target > 0)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
event.data = data;
|
||||
event.data_size = sizeof(data);
|
||||
event.delta_time = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
data[0] = 0xB0 | i;
|
||||
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &event))
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!midi_drv->flush(rarch_midi_drv_data))
|
||||
result = false;
|
||||
|
||||
if (!result)
|
||||
RARCH_ERR("[MIDI]: All sounds off failed.\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool midi_driver_set_volume(unsigned volume)
|
||||
{
|
||||
midi_event_t event;
|
||||
uint8_t data[8] = {
|
||||
0xF0, 0x7F, 0x7F, 0x04, 0x01, 0, 0, 0xF7};
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
return false;
|
||||
|
||||
volume = (unsigned)(163.83 * volume + 0.5);
|
||||
if (volume > 16383)
|
||||
volume = 16383;
|
||||
|
||||
data[5] = (uint8_t)(volume & 0x7F);
|
||||
data[6] = (uint8_t)(volume >> 7);
|
||||
|
||||
event.data = data;
|
||||
event.data_size = sizeof(data);
|
||||
event.delta_time = 0;
|
||||
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &event))
|
||||
{
|
||||
RARCH_ERR("[MIDI]: Volume change failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool midi_driver_init_io_buffers(void)
|
||||
{
|
||||
uint8_t *midi_drv_input_buffer = (uint8_t*)malloc(MIDI_DRIVER_BUF_SIZE);
|
||||
uint8_t *midi_drv_output_buffer = (uint8_t*)malloc(MIDI_DRIVER_BUF_SIZE);
|
||||
|
||||
if (!midi_drv_input_buffer || !midi_drv_output_buffer)
|
||||
{
|
||||
if (midi_drv_input_buffer)
|
||||
free(midi_drv_input_buffer);
|
||||
if (midi_drv_output_buffer)
|
||||
free(midi_drv_output_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
rarch_midi_drv_input_buffer = midi_drv_input_buffer;
|
||||
rarch_midi_drv_output_buffer = midi_drv_output_buffer;
|
||||
|
||||
rarch_midi_drv_input_event.data = midi_drv_input_buffer;
|
||||
rarch_midi_drv_input_event.data_size = 0;
|
||||
|
||||
rarch_midi_drv_output_event.data = midi_drv_output_buffer;
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void midi_driver_free(void)
|
||||
{
|
||||
if (rarch_midi_drv_data)
|
||||
{
|
||||
midi_drv->free(rarch_midi_drv_data);
|
||||
rarch_midi_drv_data = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_inputs)
|
||||
{
|
||||
string_list_free(rarch_midi_drv_inputs);
|
||||
rarch_midi_drv_inputs = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_outputs)
|
||||
{
|
||||
string_list_free(rarch_midi_drv_outputs);
|
||||
rarch_midi_drv_outputs = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_input_buffer)
|
||||
{
|
||||
free(rarch_midi_drv_input_buffer);
|
||||
rarch_midi_drv_input_buffer = NULL;
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_output_buffer)
|
||||
{
|
||||
free(rarch_midi_drv_output_buffer);
|
||||
rarch_midi_drv_output_buffer = NULL;
|
||||
}
|
||||
|
||||
rarch_midi_drv_input_enabled = false;
|
||||
rarch_midi_drv_output_enabled = false;
|
||||
}
|
||||
|
||||
static bool midi_driver_init(void *data)
|
||||
{
|
||||
union string_list_elem_attr
|
||||
attr = {0};
|
||||
bool ret = true;
|
||||
settings_t *settings = (settings_t*)data;
|
||||
|
||||
rarch_midi_drv_inputs = string_list_new();
|
||||
rarch_midi_drv_outputs = string_list_new();
|
||||
|
||||
if (!rarch_midi_drv_inputs || !rarch_midi_drv_outputs)
|
||||
ret = false;
|
||||
else if (!string_list_append(rarch_midi_drv_inputs, MIDI_DRIVER_OFF, attr) ||
|
||||
!string_list_append(rarch_midi_drv_outputs, MIDI_DRIVER_OFF, attr))
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
char * input = NULL;
|
||||
char * output = NULL;
|
||||
|
||||
midi_drv = midi_driver_find_driver(
|
||||
settings->arrays.midi_driver);
|
||||
|
||||
if (strcmp(midi_drv->ident, settings->arrays.midi_driver))
|
||||
{
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_driver, midi_drv->ident);
|
||||
}
|
||||
|
||||
if (!midi_drv->get_avail_inputs(rarch_midi_drv_inputs))
|
||||
ret = false;
|
||||
else if (!midi_drv->get_avail_outputs(rarch_midi_drv_outputs))
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
if (string_is_not_equal(settings->arrays.midi_input, MIDI_DRIVER_OFF))
|
||||
{
|
||||
if (string_list_find_elem(rarch_midi_drv_inputs, settings->arrays.midi_input))
|
||||
input = settings->arrays.midi_input;
|
||||
else
|
||||
{
|
||||
RARCH_WARN("[MIDI]: Input device \"%s\" unavailable.\n",
|
||||
settings->arrays.midi_input);
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_input, MIDI_DRIVER_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (string_is_not_equal(settings->arrays.midi_output, MIDI_DRIVER_OFF))
|
||||
{
|
||||
if (string_list_find_elem(rarch_midi_drv_outputs, settings->arrays.midi_output))
|
||||
output = settings->arrays.midi_output;
|
||||
else
|
||||
{
|
||||
RARCH_WARN("[MIDI]: Output device \"%s\" unavailable.\n",
|
||||
settings->arrays.midi_output);
|
||||
configuration_set_string(settings,
|
||||
settings->arrays.midi_output, MIDI_DRIVER_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
rarch_midi_drv_data = midi_drv->init(input, output);
|
||||
if (!rarch_midi_drv_data)
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
rarch_midi_drv_input_enabled = (input != NULL);
|
||||
rarch_midi_drv_output_enabled = (output != NULL);
|
||||
|
||||
if (!midi_driver_init_io_buffers())
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
if (input)
|
||||
RARCH_LOG("[MIDI]: Input device: \"%s\".\n", input);
|
||||
|
||||
if (output)
|
||||
{
|
||||
RARCH_LOG("[MIDI]: Output device: \"%s\".\n", output);
|
||||
midi_driver_set_volume(settings->uints.midi_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
midi_driver_free();
|
||||
RARCH_ERR("[MIDI]: Initialization failed.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_set_input(const char *input)
|
||||
{
|
||||
if (!rarch_midi_drv_data)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_set_input called on uninitialized driver.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_equal(input, MIDI_DRIVER_OFF))
|
||||
input = NULL;
|
||||
|
||||
if (!midi_drv->set_input(rarch_midi_drv_data, input))
|
||||
{
|
||||
if (input)
|
||||
RARCH_ERR("[MIDI]: Failed to change input device to \"%s\".\n", input);
|
||||
else
|
||||
RARCH_ERR("[MIDI]: Failed to disable input.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input)
|
||||
RARCH_LOG("[MIDI]: Input device changed to \"%s\".\n", input);
|
||||
else
|
||||
RARCH_LOG("[MIDI]: Input disabled.\n");
|
||||
|
||||
rarch_midi_drv_input_enabled = input != NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_set_output(void *settings_data, const char *output)
|
||||
{
|
||||
settings_t *settings = (settings_t*)settings_data;
|
||||
|
||||
if (!rarch_midi_drv_data)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_set_output called on uninitialized driver.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_equal(output, MIDI_DRIVER_OFF))
|
||||
output = NULL;
|
||||
|
||||
if (!midi_drv->set_output(rarch_midi_drv_data, output))
|
||||
{
|
||||
if (output)
|
||||
RARCH_ERR("[MIDI]: Failed to change output device to \"%s\".\n", output);
|
||||
else
|
||||
RARCH_ERR("[MIDI]: Failed to disable output.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output)
|
||||
{
|
||||
rarch_midi_drv_output_enabled = true;
|
||||
RARCH_LOG("[MIDI]: Output device changed to \"%s\".\n", output);
|
||||
|
||||
midi_driver_set_volume(settings->uints.midi_volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
rarch_midi_drv_output_enabled = false;
|
||||
RARCH_LOG("[MIDI]: Output disabled.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_input_enabled(void)
|
||||
{
|
||||
return rarch_midi_drv_input_enabled;
|
||||
}
|
||||
|
||||
bool midi_driver_output_enabled(void)
|
||||
{
|
||||
return rarch_midi_drv_output_enabled;
|
||||
}
|
||||
|
||||
bool midi_driver_read(uint8_t *byte)
|
||||
{
|
||||
static int i = 0;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_input_enabled || !byte)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!rarch_midi_drv_data)
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called on uninitialized driver.\n");
|
||||
else if (!rarch_midi_drv_input_enabled)
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called when input is disabled.\n");
|
||||
else
|
||||
RARCH_ERR("[MIDI]: midi_driver_read called with null pointer.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == (int)rarch_midi_drv_input_event.data_size)
|
||||
{
|
||||
rarch_midi_drv_input_event.data_size = MIDI_DRIVER_BUF_SIZE;
|
||||
if (!midi_drv->read(rarch_midi_drv_data, &rarch_midi_drv_input_event))
|
||||
{
|
||||
rarch_midi_drv_input_event.data_size = i;
|
||||
return false;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (rarch_midi_drv_input_event.data_size == 1)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0]);
|
||||
else if (rarch_midi_drv_input_event.data_size == 2)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data[1]);
|
||||
else if (rarch_midi_drv_input_event.data_size == 3)
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data[1],
|
||||
rarch_midi_drv_input_event.data[2]);
|
||||
else
|
||||
RARCH_LOG("[MIDI]: In [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_input_event.data[0],
|
||||
rarch_midi_drv_input_event.data_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
*byte = rarch_midi_drv_input_event.data[i++];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_write(uint8_t byte, uint32_t delta_time)
|
||||
{
|
||||
static int event_size;
|
||||
|
||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!rarch_midi_drv_data)
|
||||
RARCH_ERR("[MIDI]: midi_driver_write called on uninitialized driver.\n");
|
||||
else
|
||||
RARCH_ERR("[MIDI]: midi_driver_write called when output is disabled.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (byte >= 0x80)
|
||||
{
|
||||
if ( rarch_midi_drv_output_event.data_size
|
||||
&& rarch_midi_drv_output_event.data[0] == 0xF0)
|
||||
{
|
||||
if (byte == 0xF7)
|
||||
event_size = (int)rarch_midi_drv_output_event.data_size + 1;
|
||||
else
|
||||
{
|
||||
if (!midi_drv->write(rarch_midi_drv_data,
|
||||
&rarch_midi_drv_output_event))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
case 1:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0]);
|
||||
break;
|
||||
case 2:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1]);
|
||||
break;
|
||||
case 3:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1],
|
||||
rarch_midi_drv_output_event.data[2]);
|
||||
break;
|
||||
default:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data_size);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
rarch_midi_drv_output_pending = true;
|
||||
event_size = (int)midi_driver_get_event_size(byte);
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event_size = (int)midi_driver_get_event_size(byte);
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rarch_midi_drv_output_event.data_size < MIDI_DRIVER_BUF_SIZE)
|
||||
{
|
||||
rarch_midi_drv_output_event.data[rarch_midi_drv_output_event.data_size] = byte;
|
||||
++rarch_midi_drv_output_event.data_size;
|
||||
rarch_midi_drv_output_event.delta_time += delta_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: Output event dropped.\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event_size == (int)rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
if (!midi_drv->write(rarch_midi_drv_data, &rarch_midi_drv_output_event))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (rarch_midi_drv_output_event.data_size)
|
||||
{
|
||||
case 1:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0]);
|
||||
break;
|
||||
case 2:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1]);
|
||||
break;
|
||||
case 3:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, 0x%02X, 0x%02X].\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data[1],
|
||||
rarch_midi_drv_output_event.data[2]);
|
||||
break;
|
||||
default:
|
||||
RARCH_LOG("[MIDI]: Out [0x%02X, ...], size %u.\n",
|
||||
rarch_midi_drv_output_event.data[0],
|
||||
rarch_midi_drv_output_event.data_size);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
rarch_midi_drv_output_pending = true;
|
||||
rarch_midi_drv_output_event.data_size = 0;
|
||||
rarch_midi_drv_output_event.delta_time = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_driver_flush(void)
|
||||
{
|
||||
if (!rarch_midi_drv_data)
|
||||
return false;
|
||||
|
||||
if (rarch_midi_drv_output_pending)
|
||||
rarch_midi_drv_output_pending = !midi_drv->flush(rarch_midi_drv_data);
|
||||
|
||||
return !rarch_midi_drv_output_pending;
|
||||
}
|
||||
|
||||
size_t midi_driver_get_event_size(uint8_t status)
|
||||
{
|
||||
static const uint8_t midi_drv_ev_sizes[128] =
|
||||
{
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
0, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
if (status < 0x80)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_ERR("[MIDI]: midi_driver_get_event_size called with invalid status.\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
return midi_drv_ev_sizes[status - 0x80];
|
||||
}
|
||||
|
||||
/**
|
||||
* find_driver_nonempty:
|
||||
* @label : string of driver type to be found.
|
||||
@ -986,6 +1763,7 @@ void drivers_init(
|
||||
/* Only initialize location driver if we're ever going to use it. */
|
||||
if (location_st->active)
|
||||
if (!init_location(&runloop_state_get_ptr()->system,
|
||||
&location_driver_st,
|
||||
settings, verbosity_is_enabled()))
|
||||
location_st->active = false;
|
||||
}
|
||||
@ -1116,7 +1894,7 @@ void driver_uninit(int flags, enum driver_lifetime_flags lifetime_flags)
|
||||
#endif
|
||||
|
||||
if ((flags & DRIVER_LOCATION_MASK))
|
||||
uninit_location(&runloop_st->system);
|
||||
uninit_location(&runloop_st->system, &location_driver_st);
|
||||
|
||||
if ((flags & DRIVER_CAMERA_MASK))
|
||||
{
|
||||
@ -1239,7 +2017,7 @@ static void retroarch_deinit_drivers(struct retro_callbacks *cbs)
|
||||
menu_state_get_ptr());
|
||||
#endif
|
||||
location_st->active = false;
|
||||
destroy_location();
|
||||
location_st->driver = NULL;
|
||||
|
||||
/* Camera */
|
||||
camera_st->active = false;
|
||||
@ -6692,6 +7470,7 @@ bool retroarch_main_init(int argc, char *argv[])
|
||||
"cloud sync driver", verbosity_enabled);
|
||||
#endif
|
||||
location_driver_find_driver(settings,
|
||||
&location_driver_st,
|
||||
"location driver", verbosity_enabled);
|
||||
#ifdef HAVE_MENU
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user