From 10082e1c322d7541e0aacb04e957516c2ef8a599 Mon Sep 17 00:00:00 2001 From: libretroadmin Date: Sun, 17 Dec 2023 05:01:12 +0100 Subject: [PATCH] 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 --- Makefile.common | 2 - cheevos/cheevos.c | 2 +- griffin/griffin.c | 2 - location_driver.c | 205 ------------ location_driver.h | 18 -- midi_driver.c | 634 ------------------------------------- midi_driver.h | 6 - retroarch.c | 787 +++++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 784 insertions(+), 872 deletions(-) delete mode 100644 location_driver.c delete mode 100644 midi_driver.c diff --git a/Makefile.common b/Makefile.common index ecab263bbd..d76be0515e 100644 --- a/Makefile.common +++ b/Makefile.common @@ -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 diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 3e8d53dab2..fd7e45e1cb 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -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; diff --git a/griffin/griffin.c b/griffin/griffin.c index 5cb54b6bf3..8475b48788 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -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" diff --git a/location_driver.c b/location_driver.c deleted file mode 100644 index 92c5c1f94e..0000000000 --- a/location_driver.c +++ /dev/null @@ -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 . - */ - -#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; -} diff --git a/location_driver.h b/location_driver.h index c17879a122..82c1d8ee7e 100644 --- a/location_driver.h +++ b/location_driver.h @@ -19,8 +19,6 @@ #include #include -#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 diff --git a/midi_driver.c b/midi_driver.c deleted file mode 100644 index d110d6fbf9..0000000000 --- a/midi_driver.c +++ /dev/null @@ -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 . - */ - -#include -#include -#include - -#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]; -} diff --git a/midi_driver.h b/midi_driver.h index b2c87894ee..6f22182afb 100644 --- a/midi_driver.h +++ b/midi_driver.h @@ -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; diff --git a/retroarch.c b/retroarch.c index c0513c064b..7d61d6b27e 100644 --- a/retroarch.c +++ b/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; @@ -2376,7 +3154,7 @@ bool command_event(enum event_command cmd, void *data) gfx_widgets_ai_service_overlay_unload(); #endif } - else + else { #ifdef HAVE_GFX_WIDGETS if (p_dispwidget->ai_service_overlay_state != 0) @@ -5973,7 +6751,7 @@ static bool retroarch_parse_input_and_config( /* Workaround for libdecor 0.2.0 setting unwanted locale */ #if defined(HAVE_WAYLAND) && defined(HAVE_DYNAMIC) setlocale(LC_NUMERIC,"C"); -#endif +#endif /* If this is a static build, load salamander * config file first (sets RARCH_PATH_CORE) */ #if !defined(HAVE_DYNAMIC) @@ -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 {