diff --git a/Makefile.common b/Makefile.common
index 0e7548968f..432ded9cfd 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -85,6 +85,7 @@ endif
OBJ += frontend/frontend.o \
frontend/frontend_context.o \
frontend/platform/platform_null.o \
+ libretro_version_1.o \
retroarch.o \
file.o \
file_list.o \
diff --git a/general.h b/general.h
index af94efd87a..c0d27c1109 100644
--- a/general.h
+++ b/general.h
@@ -796,14 +796,14 @@ bool config_load_file(const char *path, bool set_defaults);
bool config_save_file(const char *path);
bool config_read_keybinds(const char *path);
+void rarch_deinit_recording(void);
+bool rarch_audio_flush(const int16_t *data, size_t samples);
void rarch_main_clear_state(void);
int rarch_main(int argc, char *argv[]);
-
bool rarch_replace_config(const char *path);
-
void rarch_main_init_wrap(const struct rarch_main_wrap *args,
int *argc, char **argv);
-
+void rarch_deinit_gpu_recording(void);
int rarch_main_init(int argc, char *argv[]);
void rarch_main_set_state(unsigned action);
void rarch_main_command(unsigned action);
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 8c3cfe37b8..6c90608cee 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -591,6 +591,7 @@ MAIN
RETROARCH
============================================================ */
#include "../general.c"
+#include "../libretro_version_1.c"
#include "../retroarch.c"
/*============================================================
diff --git a/libretro_version_1.c b/libretro_version_1.c
new file mode 100644
index 0000000000..c74744e6a8
--- /dev/null
+++ b/libretro_version_1.c
@@ -0,0 +1,347 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ * Copyright (C) 2012-2014 - Michael Lelli
+ *
+ * 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 "boolean.h"
+#include "libretro.h"
+#include
+#include
+#include
+#include
+#include
+#include "general.h"
+#include "performance.h"
+
+static void recording_dump_frame(const void *data, unsigned width,
+ unsigned height, size_t pitch)
+{
+ struct ffemu_video_data ffemu_data = {0};
+
+ ffemu_data.pitch = pitch;
+ ffemu_data.width = width;
+ ffemu_data.height = height;
+ ffemu_data.data = data;
+
+ if (g_extern.record_gpu_buffer)
+ {
+ struct rarch_viewport vp = {0};
+
+ if (driver.video && driver.video->viewport_info)
+ driver.video->viewport_info(driver.video_data, &vp);
+
+ if (!vp.width || !vp.height)
+ {
+ RARCH_WARN("Viewport size calculation failed! Will continue using raw data. This will probably not work right ...\n");
+ rarch_deinit_gpu_recording();
+
+ recording_dump_frame(data, width, height, pitch);
+ return;
+ }
+
+ /* User has resized. We kinda have a problem now. */
+ if (vp.width != g_extern.record_gpu_width ||
+ vp.height != g_extern.record_gpu_height)
+ {
+ static const char msg[] = "Recording terminated due to resize.";
+ RARCH_WARN("%s\n", msg);
+ msg_queue_clear(g_extern.msg_queue);
+ msg_queue_push(g_extern.msg_queue, msg, 1, 180);
+
+ rarch_deinit_recording();
+ return;
+ }
+
+ /* Big bottleneck.
+ * Since we might need to do read-backs asynchronously,
+ * it might take 3-4 times before this returns true. */
+ if (driver.video && driver.video->read_viewport)
+ if (!driver.video->read_viewport(driver.video_data,
+ g_extern.record_gpu_buffer))
+ return;
+
+ ffemu_data.pitch = g_extern.record_gpu_width * 3;
+ ffemu_data.width = g_extern.record_gpu_width;
+ ffemu_data.height = g_extern.record_gpu_height;
+ ffemu_data.data = g_extern.record_gpu_buffer +
+ (ffemu_data.height - 1) * ffemu_data.pitch;
+
+ ffemu_data.pitch = -ffemu_data.pitch;
+ }
+
+ if (!g_extern.record_gpu_buffer)
+ ffemu_data.is_dupe = !data;
+
+ if (g_extern.rec_driver && g_extern.rec_driver->push_video)
+ g_extern.rec_driver->push_video(g_extern.rec, &ffemu_data);
+}
+
+
+static void video_frame(const void *data, unsigned width,
+ unsigned height, size_t pitch)
+{
+ const char *msg = NULL;
+
+ if (!g_extern.video_active)
+ return;
+
+ g_extern.frame_cache.data = data;
+ g_extern.frame_cache.width = width;
+ g_extern.frame_cache.height = height;
+ g_extern.frame_cache.pitch = pitch;
+
+ if (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555 &&
+ data && data != RETRO_HW_FRAME_BUFFER_VALID)
+ {
+ RARCH_PERFORMANCE_INIT(video_frame_conv);
+ RARCH_PERFORMANCE_START(video_frame_conv);
+ driver.scaler.in_width = width;
+ driver.scaler.in_height = height;
+ driver.scaler.out_width = width;
+ driver.scaler.out_height = height;
+ driver.scaler.in_stride = pitch;
+ driver.scaler.out_stride = width * sizeof(uint16_t);
+
+ scaler_ctx_scale(&driver.scaler, driver.scaler_out, data);
+ data = driver.scaler_out;
+ pitch = driver.scaler.out_stride;
+ RARCH_PERFORMANCE_STOP(video_frame_conv);
+ }
+
+ /* Slightly messy code,
+ * but we really need to do processing before blocking on VSync
+ * for best possible scheduling.
+ */
+ if (g_extern.rec && (!g_extern.filter.filter
+ || !g_settings.video.post_filter_record || !data
+ || g_extern.record_gpu_buffer)
+ )
+ recording_dump_frame(data, width, height, pitch);
+
+ msg = msg_queue_pull(g_extern.msg_queue);
+ driver.current_msg = msg;
+
+ if (g_extern.filter.filter && data)
+ {
+ unsigned owidth = 0;
+ unsigned oheight = 0;
+ unsigned opitch = 0;
+
+ rarch_softfilter_get_output_size(g_extern.filter.filter,
+ &owidth, &oheight, width, height);
+
+ opitch = owidth * g_extern.filter.out_bpp;
+
+ RARCH_PERFORMANCE_INIT(softfilter_process);
+ RARCH_PERFORMANCE_START(softfilter_process);
+ rarch_softfilter_process(g_extern.filter.filter,
+ g_extern.filter.buffer, opitch,
+ data, width, height, pitch);
+ RARCH_PERFORMANCE_STOP(softfilter_process);
+
+ if (g_extern.rec && g_settings.video.post_filter_record)
+ recording_dump_frame(g_extern.filter.buffer, owidth, oheight, opitch);
+
+ data = g_extern.filter.buffer;
+ width = owidth;
+ height = oheight;
+ pitch = opitch;
+ }
+
+ if (!driver.video->frame(driver.video_data, data, width, height, pitch, msg))
+ g_extern.video_active = false;
+}
+
+static void audio_sample(int16_t left, int16_t right)
+{
+ g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = left;
+ g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = right;
+
+ if (g_extern.audio_data.data_ptr < g_extern.audio_data.chunk_size)
+ return;
+
+ g_extern.audio_active = rarch_audio_flush(g_extern.audio_data.conv_outsamples,
+ g_extern.audio_data.data_ptr) && g_extern.audio_active;
+
+ g_extern.audio_data.data_ptr = 0;
+}
+
+static size_t audio_sample_batch(const int16_t *data, size_t frames)
+{
+ if (frames > (AUDIO_CHUNK_SIZE_NONBLOCKING >> 1))
+ frames = AUDIO_CHUNK_SIZE_NONBLOCKING >> 1;
+
+ g_extern.audio_active = rarch_audio_flush(data, frames << 1)
+ && g_extern.audio_active;
+
+ return frames;
+}
+
+/* Turbo scheme: If turbo button is held, all buttons pressed except
+ * for D-pad will go into a turbo mode. Until the button is
+ * released again, the input state will be modulated by a periodic pulse
+ * defined by the configured duty cycle. */
+
+static bool input_apply_turbo(unsigned port, unsigned id, bool res)
+{
+ if (res && g_extern.turbo_frame_enable[port])
+ g_extern.turbo_enable[port] |= (1 << id);
+ else if (!res)
+ g_extern.turbo_enable[port] &= ~(1 << id);
+
+ if (g_extern.turbo_enable[port] & (1 << id))
+ return res && ((g_extern.turbo_count % g_settings.input.turbo_period)
+ < g_settings.input.turbo_duty_cycle);
+ return res;
+}
+
+static int16_t input_state(unsigned port, unsigned device,
+ unsigned index, unsigned id)
+{
+ int16_t res = 0;
+
+ device &= RETRO_DEVICE_MASK;
+
+ if (g_extern.bsv.movie && g_extern.bsv.movie_playback)
+ {
+ int16_t ret;
+ if (bsv_movie_get_input(g_extern.bsv.movie, &ret))
+ return ret;
+
+ g_extern.bsv.movie_end = true;
+ }
+
+ static const struct retro_keybind *binds[MAX_PLAYERS] = {
+ g_settings.input.binds[0],
+ g_settings.input.binds[1],
+ g_settings.input.binds[2],
+ g_settings.input.binds[3],
+ g_settings.input.binds[4],
+ g_settings.input.binds[5],
+ g_settings.input.binds[6],
+ g_settings.input.binds[7],
+ g_settings.input.binds[8],
+ g_settings.input.binds[9],
+ g_settings.input.binds[10],
+ g_settings.input.binds[11],
+ g_settings.input.binds[12],
+ g_settings.input.binds[13],
+ g_settings.input.binds[14],
+ g_settings.input.binds[15],
+ };
+
+ if (!driver.block_libretro_input && (id < RARCH_FIRST_META_KEY ||
+ device == RETRO_DEVICE_KEYBOARD))
+ res = driver.input->input_state(driver.input_data, binds, port,
+ device, index, id);
+
+#ifdef HAVE_OVERLAY
+ if (device == RETRO_DEVICE_JOYPAD && port == 0)
+ res |= driver.overlay_state.buttons & (UINT64_C(1) << id) ? 1 : 0;
+ else if (device == RETRO_DEVICE_KEYBOARD && port == 0 && id < RETROK_LAST)
+ res |= OVERLAY_GET_KEY(&driver.overlay_state, id) ? 1 : 0;
+ else if (device == RETRO_DEVICE_ANALOG && port == 0)
+ {
+ unsigned base = (index == RETRO_DEVICE_INDEX_ANALOG_RIGHT) ? 2 : 0;
+ base += (id == RETRO_DEVICE_ID_ANALOG_Y) ? 1 : 0;
+ if (driver.overlay_state.analog[base])
+ res = driver.overlay_state.analog[base];
+ }
+#endif
+
+ /* Don't allow turbo for D-pad. */
+ if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP ||
+ id > RETRO_DEVICE_ID_JOYPAD_RIGHT))
+ res = input_apply_turbo(port, id, res);
+
+ if (g_extern.bsv.movie && !g_extern.bsv.movie_playback)
+ bsv_movie_set_input(g_extern.bsv.movie, res);
+
+ return res;
+}
+
+static void audio_sample_rewind(int16_t left, int16_t right)
+{
+ g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = right;
+ g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = left;
+}
+
+static size_t audio_sample_batch_rewind(const int16_t *data, size_t frames)
+{
+ size_t i;
+ size_t samples = frames << 1;
+
+ for (i = 0; i < samples; i++)
+ g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = data[i];
+
+ return frames;
+}
+
+void retro_init_libretro_cbs(void)
+{
+ pretro_set_video_refresh(video_frame);
+ pretro_set_audio_sample(audio_sample);
+ pretro_set_audio_sample_batch(audio_sample_batch);
+ pretro_set_input_state(input_state);
+ pretro_set_input_poll(rarch_input_poll);
+
+#ifdef HAVE_NETPLAY
+ if (!g_extern.netplay)
+ return;
+
+ if (g_extern.netplay_is_spectate)
+ {
+ pretro_set_input_state(
+ (g_extern.netplay_is_client ?
+ input_state_spectate_client : input_state_spectate)
+ );
+ }
+ else
+ {
+ pretro_set_video_refresh(video_frame_net);
+ pretro_set_audio_sample(audio_sample_net);
+ pretro_set_audio_sample_batch(audio_sample_batch_net);
+ pretro_set_input_state(input_state_net);
+ }
+#endif
+}
+
+void retro_video_frame(const void *data, unsigned width,
+ unsigned height, size_t pitch)
+{
+ video_frame(data, width, height, pitch);
+}
+
+void retro_set_default_callbacks(struct retro_callbacks* cbs)
+{
+ cbs->frame_cb = video_frame;
+ cbs->sample_cb = audio_sample;
+ cbs->sample_batch_cb = audio_sample_batch;
+ cbs->state_cb = input_state;
+}
+
+void retro_set_rewind_callbacks(void)
+{
+ if (g_extern.frame_is_reverse)
+ {
+ pretro_set_audio_sample(audio_sample_rewind);
+ pretro_set_audio_sample_batch(audio_sample_batch_rewind);
+ }
+ else
+ {
+ pretro_set_audio_sample(audio_sample);
+ pretro_set_audio_sample_batch(audio_sample_batch);
+ }
+}
diff --git a/netplay.h b/netplay.h
index 7967a1f6d8..0d9b9626c8 100644
--- a/netplay.h
+++ b/netplay.h
@@ -21,6 +21,7 @@
#include
#include "boolean.h"
#include "libretro.h"
+#include "retro.h"
void input_poll_net(void);
@@ -42,14 +43,6 @@ int16_t input_state_spectate_client(unsigned port, unsigned device,
typedef struct netplay netplay_t;
-struct retro_callbacks
-{
- retro_video_refresh_t frame_cb;
- retro_audio_sample_t sample_cb;
- retro_audio_sample_batch_t sample_batch_cb;
- retro_input_state_t state_cb;
-};
-
bool netplay_init_network(void);
/* Creates a new netplay handle. A NULL host means we're
diff --git a/retro.h b/retro.h
new file mode 100644
index 0000000000..f50c56c703
--- /dev/null
+++ b/retro.h
@@ -0,0 +1,40 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ * Copyright (C) 2012-2014 - Michael Lelli
+ *
+ * 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 .
+ */
+
+#ifndef _RETRO_IMPLEMENTATION_H
+#define _RETRO_IMPLEMENTATION_H
+
+#include "libretro.h"
+
+struct retro_callbacks
+{
+ retro_video_refresh_t frame_cb;
+ retro_audio_sample_t sample_cb;
+ retro_audio_sample_batch_t sample_batch_cb;
+ retro_input_state_t state_cb;
+};
+
+void retro_init_libretro_cbs(void);
+
+void retro_video_frame(const void *data, unsigned width,
+ unsigned height, size_t pitch);
+
+void retro_set_default_callbacks(struct retro_callbacks* cbs);
+
+void retro_set_rewind_callbacks(void);
+
+#endif
diff --git a/retroarch.c b/retroarch.c
index 25b2e36f1d..b7640ca214 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -17,6 +17,7 @@
#include "boolean.h"
#include "libretro.h"
+#include "retro.h"
#include
#include
#include
@@ -218,7 +219,7 @@ static void readjust_audio_input_rate(void)
// g_extern.audio_data.src_ratio, g_extern.audio_data.orig_src_ratio);
}
-static void deinit_gpu_recording(void)
+void rarch_deinit_gpu_recording(void)
{
if (g_extern.record_gpu_buffer)
free(g_extern.record_gpu_buffer);
@@ -344,11 +345,11 @@ static void init_recording(void)
if (!ffemu_init_first(&g_extern.rec_driver, &g_extern.rec, ¶ms))
{
RARCH_ERR(RETRO_LOG_INIT_RECORDING_FAILED);
- deinit_gpu_recording();
+ rarch_deinit_gpu_recording();
}
}
-static void deinit_recording(void)
+void rarch_deinit_recording(void)
{
if (!g_extern.rec || !g_extern.rec_driver)
return;
@@ -361,145 +362,7 @@ static void deinit_recording(void)
g_extern.rec = NULL;
g_extern.rec_driver = NULL;
- deinit_gpu_recording();
-}
-
-static void recording_dump_frame(const void *data, unsigned width,
- unsigned height, size_t pitch)
-{
- struct ffemu_video_data ffemu_data = {0};
-
- ffemu_data.pitch = pitch;
- ffemu_data.width = width;
- ffemu_data.height = height;
- ffemu_data.data = data;
-
- if (g_extern.record_gpu_buffer)
- {
- struct rarch_viewport vp = {0};
-
- if (driver.video && driver.video->viewport_info)
- driver.video->viewport_info(driver.video_data, &vp);
-
- if (!vp.width || !vp.height)
- {
- RARCH_WARN("Viewport size calculation failed! Will continue using raw data. This will probably not work right ...\n");
- deinit_gpu_recording();
-
- recording_dump_frame(data, width, height, pitch);
- return;
- }
-
- /* User has resized. We kinda have a problem now. */
- if (vp.width != g_extern.record_gpu_width ||
- vp.height != g_extern.record_gpu_height)
- {
- static const char msg[] = "Recording terminated due to resize.";
- RARCH_WARN("%s\n", msg);
- msg_queue_clear(g_extern.msg_queue);
- msg_queue_push(g_extern.msg_queue, msg, 1, 180);
-
- deinit_recording();
- return;
- }
-
- /* Big bottleneck.
- * Since we might need to do read-backs asynchronously,
- * it might take 3-4 times before this returns true. */
- if (driver.video && driver.video->read_viewport)
- if (!driver.video->read_viewport(driver.video_data,
- g_extern.record_gpu_buffer))
- return;
-
- ffemu_data.pitch = g_extern.record_gpu_width * 3;
- ffemu_data.width = g_extern.record_gpu_width;
- ffemu_data.height = g_extern.record_gpu_height;
- ffemu_data.data = g_extern.record_gpu_buffer +
- (ffemu_data.height - 1) * ffemu_data.pitch;
-
- ffemu_data.pitch = -ffemu_data.pitch;
- }
-
- if (!g_extern.record_gpu_buffer)
- ffemu_data.is_dupe = !data;
-
- if (g_extern.rec_driver && g_extern.rec_driver->push_video)
- g_extern.rec_driver->push_video(g_extern.rec, &ffemu_data);
-}
-
-static void video_frame(const void *data, unsigned width,
- unsigned height, size_t pitch)
-{
- const char *msg = NULL;
-
- if (!g_extern.video_active)
- return;
-
- g_extern.frame_cache.data = data;
- g_extern.frame_cache.width = width;
- g_extern.frame_cache.height = height;
- g_extern.frame_cache.pitch = pitch;
-
- if (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555 &&
- data && data != RETRO_HW_FRAME_BUFFER_VALID)
- {
- RARCH_PERFORMANCE_INIT(video_frame_conv);
- RARCH_PERFORMANCE_START(video_frame_conv);
- driver.scaler.in_width = width;
- driver.scaler.in_height = height;
- driver.scaler.out_width = width;
- driver.scaler.out_height = height;
- driver.scaler.in_stride = pitch;
- driver.scaler.out_stride = width * sizeof(uint16_t);
-
- scaler_ctx_scale(&driver.scaler, driver.scaler_out, data);
- data = driver.scaler_out;
- pitch = driver.scaler.out_stride;
- RARCH_PERFORMANCE_STOP(video_frame_conv);
- }
-
- /* Slightly messy code,
- * but we really need to do processing before blocking on VSync
- * for best possible scheduling.
- */
- if (g_extern.rec && (!g_extern.filter.filter
- || !g_settings.video.post_filter_record || !data
- || g_extern.record_gpu_buffer)
- )
- recording_dump_frame(data, width, height, pitch);
-
- msg = msg_queue_pull(g_extern.msg_queue);
- driver.current_msg = msg;
-
- if (g_extern.filter.filter && data)
- {
- unsigned owidth = 0;
- unsigned oheight = 0;
- unsigned opitch = 0;
-
- rarch_softfilter_get_output_size(g_extern.filter.filter,
- &owidth, &oheight, width, height);
-
- opitch = owidth * g_extern.filter.out_bpp;
-
- RARCH_PERFORMANCE_INIT(softfilter_process);
- RARCH_PERFORMANCE_START(softfilter_process);
- rarch_softfilter_process(g_extern.filter.filter,
- g_extern.filter.buffer, opitch,
- data, width, height, pitch);
- RARCH_PERFORMANCE_STOP(softfilter_process);
-
- if (g_extern.rec && g_settings.video.post_filter_record)
- recording_dump_frame(g_extern.filter.buffer, owidth, oheight, opitch);
-
- data = g_extern.filter.buffer;
- width = owidth;
- height = oheight;
- pitch = opitch;
- }
-
- if (!driver.video->frame(driver.video_data, data, width, height, pitch, msg))
- g_extern.video_active = false;
+ rarch_deinit_gpu_recording();
}
void rarch_render_cached_frame(void)
@@ -517,7 +380,7 @@ void rarch_render_cached_frame(void)
* freed the memory, but no known implementations do this.
* It would be really stupid at any rate ...
*/
- video_frame(frame,
+ retro_video_frame(frame,
g_extern.frame_cache.width,
g_extern.frame_cache.height,
g_extern.frame_cache.pitch);
@@ -525,7 +388,7 @@ void rarch_render_cached_frame(void)
g_extern.rec = recording;
}
-static bool audio_flush(const int16_t *data, size_t samples)
+bool rarch_audio_flush(const int16_t *data, size_t samples)
{
const void *output_data = NULL;
unsigned output_frames = 0;
@@ -610,48 +473,6 @@ static bool audio_flush(const int16_t *data, size_t samples)
return true;
}
-static void audio_sample_rewind(int16_t left, int16_t right)
-{
- g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = right;
- g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = left;
-}
-
-static size_t audio_sample_batch_rewind(const int16_t *data, size_t frames)
-{
- size_t i;
- size_t samples = frames << 1;
-
- for (i = 0; i < samples; i++)
- g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = data[i];
-
- return frames;
-}
-
-static void audio_sample(int16_t left, int16_t right)
-{
- g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = left;
- g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = right;
-
- if (g_extern.audio_data.data_ptr < g_extern.audio_data.chunk_size)
- return;
-
- g_extern.audio_active = audio_flush(g_extern.audio_data.conv_outsamples,
- g_extern.audio_data.data_ptr) && g_extern.audio_active;
-
- g_extern.audio_data.data_ptr = 0;
-}
-
-static size_t audio_sample_batch(const int16_t *data, size_t frames)
-{
- if (frames > (AUDIO_CHUNK_SIZE_NONBLOCKING >> 1))
- frames = AUDIO_CHUNK_SIZE_NONBLOCKING >> 1;
-
- g_extern.audio_active = audio_flush(data, frames << 1)
- && g_extern.audio_active;
-
- return frames;
-}
-
#ifdef HAVE_OVERLAY
static inline void input_poll_overlay(void)
{
@@ -787,89 +608,6 @@ void rarch_input_poll(void)
#endif
}
-/* Turbo scheme: If turbo button is held, all buttons pressed except
- * for D-pad will go into a turbo mode. Until the button is
- * released again, the input state will be modulated by a periodic pulse
- * defined by the configured duty cycle. */
-
-static bool input_apply_turbo(unsigned port, unsigned id, bool res)
-{
- if (res && g_extern.turbo_frame_enable[port])
- g_extern.turbo_enable[port] |= (1 << id);
- else if (!res)
- g_extern.turbo_enable[port] &= ~(1 << id);
-
- if (g_extern.turbo_enable[port] & (1 << id))
- return res && ((g_extern.turbo_count % g_settings.input.turbo_period)
- < g_settings.input.turbo_duty_cycle);
- return res;
-}
-
-static int16_t input_state(unsigned port, unsigned device,
- unsigned index, unsigned id)
-{
- int16_t res = 0;
-
- device &= RETRO_DEVICE_MASK;
-
- if (g_extern.bsv.movie && g_extern.bsv.movie_playback)
- {
- int16_t ret;
- if (bsv_movie_get_input(g_extern.bsv.movie, &ret))
- return ret;
-
- g_extern.bsv.movie_end = true;
- }
-
- static const struct retro_keybind *binds[MAX_PLAYERS] = {
- g_settings.input.binds[0],
- g_settings.input.binds[1],
- g_settings.input.binds[2],
- g_settings.input.binds[3],
- g_settings.input.binds[4],
- g_settings.input.binds[5],
- g_settings.input.binds[6],
- g_settings.input.binds[7],
- g_settings.input.binds[8],
- g_settings.input.binds[9],
- g_settings.input.binds[10],
- g_settings.input.binds[11],
- g_settings.input.binds[12],
- g_settings.input.binds[13],
- g_settings.input.binds[14],
- g_settings.input.binds[15],
- };
-
- if (!driver.block_libretro_input && (id < RARCH_FIRST_META_KEY ||
- device == RETRO_DEVICE_KEYBOARD))
- res = driver.input->input_state(driver.input_data, binds, port,
- device, index, id);
-
-#ifdef HAVE_OVERLAY
- if (device == RETRO_DEVICE_JOYPAD && port == 0)
- res |= driver.overlay_state.buttons & (UINT64_C(1) << id) ? 1 : 0;
- else if (device == RETRO_DEVICE_KEYBOARD && port == 0 && id < RETROK_LAST)
- res |= OVERLAY_GET_KEY(&driver.overlay_state, id) ? 1 : 0;
- else if (device == RETRO_DEVICE_ANALOG && port == 0)
- {
- unsigned base = (index == RETRO_DEVICE_INDEX_ANALOG_RIGHT) ? 2 : 0;
- base += (id == RETRO_DEVICE_ID_ANALOG_Y) ? 1 : 0;
- if (driver.overlay_state.analog[base])
- res = driver.overlay_state.analog[base];
- }
-#endif
-
- /* Don't allow turbo for D-pad. */
- if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP ||
- id > RETRO_DEVICE_ID_JOYPAD_RIGHT))
- res = input_apply_turbo(port, id, res);
-
- if (g_extern.bsv.movie && !g_extern.bsv.movie_playback)
- bsv_movie_set_input(g_extern.bsv.movie, res);
-
- return res;
-}
-
#if !defined(_WIN32) && !defined(GLOBAL_CONFIG_DIR)
#if defined(__HAIKU__)
#define GLOBAL_CONFIG_DIR "/system/settings"
@@ -1740,10 +1478,7 @@ static void init_netplay(void)
return;
}
- cbs.frame_cb = video_frame;
- cbs.sample_cb = audio_sample;
- cbs.sample_batch_cb = audio_sample_batch;
- cbs.state_cb = input_state;
+ retro_set_default_callbacks(&cbs);
if (*g_extern.netplay_server)
{
@@ -1806,40 +1541,6 @@ static void deinit_command(void)
#endif
-#ifdef HAVE_NETPLAY
-static void init_libretro_cbs_netplay(void)
-{
- if (!g_extern.netplay)
- return;
-
- pretro_set_video_refresh(g_extern.netplay_is_spectate ?
- video_frame : video_frame_net);
-
- pretro_set_audio_sample(g_extern.netplay_is_spectate ?
- audio_sample : audio_sample_net);
- pretro_set_audio_sample_batch(g_extern.netplay_is_spectate ?
- audio_sample_batch : audio_sample_batch_net);
-
- pretro_set_input_state(g_extern.netplay_is_spectate ?
- (g_extern.netplay_is_client ?
- input_state_spectate_client : input_state_spectate)
- : input_state_net);
-}
-#endif
-
-static void init_libretro_cbs(void)
-{
- pretro_set_video_refresh(video_frame);
- pretro_set_audio_sample(audio_sample);
- pretro_set_audio_sample_batch(audio_sample_batch);
- pretro_set_input_state(input_state);
- pretro_set_input_poll(rarch_input_poll);
-
-#ifdef HAVE_NETPLAY
- init_libretro_cbs_netplay();
-#endif
-}
-
#if defined(HAVE_THREADS)
static void init_autosave(void)
{
@@ -2214,7 +1915,7 @@ static void check_stateslots(
static inline void flush_rewind_audio(void)
{
/* We just rewound. Flush rewind audio buffer. */
- g_extern.audio_active = audio_flush(g_extern.audio_data.rewind_buf
+ g_extern.audio_active = rarch_audio_flush(g_extern.audio_data.rewind_buf
+ g_extern.audio_data.rewind_ptr,
g_extern.audio_data.rewind_size - g_extern.audio_data.rewind_ptr)
&& g_extern.audio_active;
@@ -2299,10 +2000,7 @@ static void check_rewind(bool pressed)
}
}
- pretro_set_audio_sample(g_extern.frame_is_reverse ?
- audio_sample_rewind : audio_sample);
- pretro_set_audio_sample_batch(g_extern.frame_is_reverse ?
- audio_sample_batch_rewind : audio_sample_batch);
+ retro_set_rewind_callbacks();
}
static void check_slowmotion(bool pressed)
@@ -3091,7 +2789,7 @@ int rarch_main_init(int argc, char *argv[])
#endif
}
- init_libretro_cbs();
+ retro_init_libretro_cbs();
init_system_av_info();
init_drivers();
@@ -3389,7 +3087,7 @@ void rarch_main_command(unsigned cmd)
init_recording();
break;
case RARCH_CMD_RECORD_DEINIT:
- deinit_recording();
+ rarch_deinit_recording();
break;
case RARCH_CMD_HISTORY_INIT:
if (!g_extern.history)
@@ -3705,23 +3403,24 @@ bool rarch_main_iterate(void)
return true;
}
+static void free_temporary_content(void)
+{
+ unsigned i;
+ for (i = 0; i < g_extern.temporary_content->size; i++)
+ {
+ const char *path = g_extern.temporary_content->elems[i].data;
+
+ RARCH_LOG("Removing temporary content file: %s.\n", path);
+ if (remove(path) < 0)
+ RARCH_ERR("Failed to remove temporary file: %s.\n", path);
+ }
+ string_list_free(g_extern.temporary_content);
+}
static void deinit_temporary_content(void)
{
- unsigned i;
-
if (g_extern.temporary_content)
- {
- for (i = 0; i < g_extern.temporary_content->size; i++)
- {
- const char *path = g_extern.temporary_content->elems[i].data;
-
- RARCH_LOG("Removing temporary content file: %s.\n", path);
- if (remove(path) < 0)
- RARCH_ERR("Failed to remove temporary file: %s.\n", path);
- }
- string_list_free(g_extern.temporary_content);
- }
+ free_temporary_content();
g_extern.temporary_content = NULL;
}
@@ -3747,7 +3446,7 @@ void rarch_main_deinit(void)
deinit_autosave();
#endif
- deinit_recording();
+ rarch_deinit_recording();
save_files();