diff --git a/run/driar.run b/run/driar.run
index 6bbf95f..d6b874d 100644
--- a/run/driar.run
+++ b/run/driar.run
@@ -15,6 +15,7 @@ set unzip [check_installed unzip]
set build_components {
core init
app/retro_frontend
+ drivers/audio
drivers/framebuffer
drivers/input
drivers/timer
@@ -29,7 +30,8 @@ proc platform_drv_policy {} {
return {
- }
+
+ }
}
append_platform_drv_build_components
@@ -95,6 +97,10 @@ append_if [have_spec ps2] config {
}
append config {
+
+
+
+
@@ -112,10 +118,13 @@ append config {
-
-
-
-
+
+
+
+
+
+
+
@@ -166,6 +175,7 @@ if {![file exist bin/Driar.nes]} {
# generic modules
set boot_modules {
core init ld.lib.so
+ audio_drv
fb_upscale
input_remap
libc.lib.so
diff --git a/run/superbossgaiden.run b/run/superbossgaiden.run
index 57bbdcf..c17b468 100644
--- a/run/superbossgaiden.run
+++ b/run/superbossgaiden.run
@@ -15,6 +15,7 @@ set unzip [check_installed unzip]
set build_components {
core init
app/retro_frontend
+ drivers/audio
drivers/framebuffer
drivers/input
drivers/timer
@@ -29,7 +30,9 @@ proc platform_drv_policy {} {
return {
- }
+
+ }
+
}
append_platform_drv_build_components
@@ -95,6 +98,10 @@ append_if [have_spec ps2] config {
}
append config {
+
+
+
+
@@ -112,12 +119,13 @@ append config {
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -168,6 +176,7 @@ if {![file exist "bin/superbossgaiden.sfc"]} {
# generic modules
set boot_modules {
core init ld.lib.so
+ audio_drv
fb_upscale
input_remap
libc.lib.so
diff --git a/src/app/retro_frontend/audio.h b/src/app/retro_frontend/audio.h
new file mode 100644
index 0000000..c36b7a8
--- /dev/null
+++ b/src/app/retro_frontend/audio.h
@@ -0,0 +1,259 @@
+/*
+ * \brief Retro_frontend audio
+ * \author Emery Hemingway
+ * \date 2016-12-13
+ */
+
+/*
+ * Copyright (C) 2016 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#ifndef _RETRO_FRONTEND__AUDIO_H_
+#define _RETRO_FRONTEND__AUDIO_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#include
+
+namespace Retro_frontend {
+ #include
+
+ template
+ struct Ring_buffer;
+ struct Stereo_out;
+
+ enum { LEFT, RIGHT, NUM_CHANNELS };
+
+ enum {
+ SHIFT = 16,
+ SHIFT_ONE = 1 << SHIFT
+ };
+
+ unsigned audio_shift_factor = SHIFT_ONE;
+ static unsigned audio_input_period = 0;
+}
+
+
+/**
+ * Ring buffer using virtual addressing and Buffer Overflowâ„¢ technology
+ */
+template
+struct Retro_frontend::Ring_buffer : Genode::Lock
+{
+ enum { BUFFER_SIZE = sizeof(TYPE)*CAPACITY };
+
+ Genode::Env &env;
+
+ Genode::addr_t map_first;
+ Genode::addr_t map_second;
+
+ TYPE *buffer;
+
+ Genode::size_t wpos = 0;
+ Genode::size_t rpos = 0;
+
+ Genode::Ram_dataspace_capability buffer_ds = env.ram().alloc(BUFFER_SIZE);
+
+ Ring_buffer(Genode::Env &env) : env(env)
+ {
+ {
+ /* a hack to find the right sized void in the address space */
+ Genode::Attached_ram_dataspace filler(env.ram(), env.rm(), BUFFER_SIZE*2);
+ map_first = (Genode::addr_t)filler.local_addr();
+ }
+
+ map_second = map_first+BUFFER_SIZE;
+
+ /* attach the buffer in two consecutive regions */
+ map_first = env.rm().attach_at(buffer_ds, map_first, BUFFER_SIZE);
+ map_second = env.rm().attach_at(buffer_ds, map_second, BUFFER_SIZE);
+ if ((map_first+BUFFER_SIZE) != map_second) {
+ Genode::error("failed to map ring buffer to consecutive regions");
+ throw Genode::Exception();
+ }
+
+ buffer = (TYPE *)map_first;
+ }
+
+ ~Ring_buffer()
+ {
+ env.rm().detach(map_second);
+ env.rm().detach(map_first);
+ env.ram().free(buffer_ds);
+ }
+
+ Genode::size_t read_avail() const
+ {
+ if (wpos > rpos) return wpos - rpos;
+ else return (wpos - rpos + CAPACITY) % CAPACITY;
+ }
+
+ Genode::size_t write_avail() const
+ {
+ if (wpos > rpos) return ((rpos - wpos + CAPACITY) % CAPACITY) - 2;
+ else if (wpos < rpos) return rpos - wpos;
+ else return CAPACITY - 2;
+ }
+
+ Genode::size_t write(TYPE const *src, Genode::size_t len)
+ {
+ using Genode::size_t;
+
+ len = Genode::min(len, write_avail());
+
+ TYPE *wbuf = &buffer[wpos];
+
+ for (size_t i = 0; i < len; ++i)
+ wbuf[i] = src[i];
+
+ wpos = (wpos + len) % CAPACITY;
+ return len;
+ }
+
+ void drain_period(float *periodl, float *periodr)
+ {
+ using namespace Genode;
+
+ size_t const avail = read_avail();
+
+ if (avail < audio_input_period*2) {
+ Genode::memset(periodl, 0x00, sizeof(float)*Audio_out::PERIOD);
+ Genode::memset(periodr, 0x00, sizeof(float)*Audio_out::PERIOD);
+ return;
+ }
+
+ int16_t *rbuf = &buffer[rpos];
+
+ size_t buf_off;
+ for (size_t pkt_off = 0; pkt_off < Audio_out::PERIOD; ++pkt_off)
+ {
+ buf_off = 2*((pkt_off*audio_shift_factor)>>SHIFT);
+ periodl[pkt_off] = rbuf[buf_off+0] / 32768.0f;
+ periodr[pkt_off] = rbuf[buf_off+1] / 32768.0f;
+ }
+
+ rpos = (rpos+audio_input_period*2) % CAPACITY;
+ }
+};
+
+
+/**
+ * Thread for converting samples at the core sample rate
+ * to the native sample rate
+ */
+struct Retro_frontend::Stereo_out : Genode::Thread
+{
+ Audio_out::Connection left;
+ Audio_out::Connection right;
+
+ Ring_buffer buffer;
+
+ Genode::Lock run_lock { Genode::Lock::LOCKED };
+
+ bool running = false;
+
+ void entry() override;
+
+ Stereo_out(Genode::Env &env)
+ :
+ Genode::Thread(env, "audio-sync", 8*1024,
+ env.cpu().affinity_space().location_of_index(1),
+ Weight(Genode::Cpu_session::Weight::DEFAULT_WEIGHT-1),
+ env.cpu()),
+ left( env, "left", false, true),
+ right(env, "right", false, true),
+ buffer(env)
+ {
+ start();
+ }
+
+ void start_stream()
+ {
+ running = true;
+ run_lock.unlock();
+ }
+
+ void stop_stream()
+ {
+ running = false;
+ }
+};
+
+
+static Genode::Constructible stereo_out;
+
+
+static
+void audio_sample_noop(int16_t left, int16_t right) { }
+
+
+static /* not called in pratice */
+void audio_sample_callback(int16_t left, int16_t right)
+{
+ stereo_out->buffer.lock();
+ stereo_out->buffer.write(&left, 1);
+ stereo_out->buffer.write(&right, 1);
+ stereo_out->buffer.unlock();
+}
+
+
+static
+size_t audio_sample_batch_noop(const int16_t *data, size_t frames) { return 0; }
+
+
+static
+size_t audio_sample_batch_callback(const int16_t *data, size_t frames)
+{
+ Genode::Lock::Guard guard(stereo_out->buffer);
+ return stereo_out->buffer.write(data, frames*2)/2;
+}
+
+
+void Retro_frontend::Stereo_out::entry()
+{
+ Audio_out::Packet *p[NUM_CHANNELS];
+
+ for (;;) {
+ run_lock.lock();
+
+ p[LEFT] = left.stream()->next();
+
+ /* stuff the buffer a bit */
+ for (auto i = 0; i < 4; ++i)
+ p[LEFT] = left.stream()->next(p[LEFT]);
+
+ left.start();
+ right.start();
+
+ while (running) {
+ unsigned const ppos = left.stream()->packet_position(p[LEFT]);
+ p[RIGHT] = right.stream()->get(ppos);
+
+ buffer.lock();
+ buffer.drain_period(p[LEFT]->content(), p[RIGHT]->content());
+ buffer.unlock();
+
+ left.submit(p[LEFT]);
+ right.submit(p[RIGHT]);
+
+ p[LEFT] = left.stream()->next(p[LEFT]);
+
+ left.wait_for_progress();
+ }
+
+ /* empty the buffer to resync when started again */
+ while (!p[LEFT]->played())
+ left.wait_for_progress();
+
+ left.stop();
+ right.stop();
+ }
+}
+
+#endif
diff --git a/src/app/retro_frontend/callbacks.h b/src/app/retro_frontend/callbacks.h
index f32d664..3e67e1f 100644
--- a/src/app/retro_frontend/callbacks.h
+++ b/src/app/retro_frontend/callbacks.h
@@ -16,10 +16,6 @@
#include "frontend.h"
-namespace Libretro {
-
-#include
-
/**
* Doesn't work
@@ -49,6 +45,8 @@ void log_callback(enum retro_log_level level, const char *fmt, ...)
static
bool environment_callback(unsigned cmd, void *data)
{
+ using namespace Retro_frontend;
+
switch (cmd) {
case RETRO_ENVIRONMENT_GET_OVERSCAN:
@@ -232,14 +230,14 @@ bool environment_callback(unsigned cmd, void *data)
{
retro_framebuffer *fb = (retro_framebuffer*)data;
- if (!global_frontend->framebuffer.constructed())
+ if (!framebuffer.constructed())
return false;
- Framebuffer::Mode mode = global_frontend->framebuffer->mode;
+ ::Framebuffer::Mode mode = framebuffer->mode;
fb->width = (unsigned)mode.width();
fb->height = (unsigned)mode.height();
- fb->data = global_frontend->framebuffer->ds.local_addr();
+ fb->data = framebuffer->ds.local_addr();
fb->pitch = mode.width() * 2;
fb->format = RETRO_PIXEL_FORMAT_RGB565;
fb->memory_flags = RETRO_MEMORY_TYPE_CACHED;
@@ -257,15 +255,17 @@ void video_refresh_callback(const void *data,
unsigned src_width, unsigned src_height,
size_t src_pitch)
{
+ using namespace Retro_frontend;
using namespace Genode;
+
if (data == NULL) /* frame duping? */
return;
uint8_t const *src = (uint8_t const*)data;
- uint8_t *dst = global_frontend->framebuffer->ds.local_addr();
+ uint8_t *dst = framebuffer->ds.local_addr();
- unsigned const dst_width = global_frontend->framebuffer->mode.width();
- unsigned const dst_height = global_frontend->framebuffer->mode.height();
+ unsigned const dst_width = framebuffer->mode.width();
+ unsigned const dst_height = framebuffer->mode.height();
unsigned const width = min(src_width, dst_width);
unsigned const height = min(src_height, dst_height);
@@ -277,179 +277,7 @@ void video_refresh_callback(const void *data,
memcpy(&dst[y*dst_pitch], &src[y*src_pitch], dst_pitch);
}
- global_frontend->framebuffer->session.refresh(0, 0, width, height);
-}
-
-
-template
-struct Ring_buffer
-{
- Genode::size_t wpos { 0 };
- Genode::size_t rpos { 0 };
-
- char _data[CAPACITY];
-
- Ring_buffer() { }
-
- Genode::size_t read_avail() const
- {
- if (wpos > rpos) return wpos - rpos;
- else return (wpos - rpos + CAPACITY) % CAPACITY;
- }
-
- Genode::size_t write_avail() const
- {
- if (wpos > rpos) return ((rpos - wpos + CAPACITY) % CAPACITY) - 2;
- else if (wpos < rpos) return rpos - wpos;
- else return CAPACITY - 2;
- }
-
- Genode::size_t write(void const *src, Genode::size_t len)
- {
- Genode::size_t const avail = write_avail();
- if (avail == 0) return 0;
-
- Genode::size_t const limit_len = len > avail ? avail : len;
- Genode::size_t const total = wpos + len;
- Genode::size_t first, rest;
-
- if (total > CAPACITY) {
- first = CAPACITY - wpos;
- rest = total % CAPACITY;
- } else {
- first = limit_len;
- rest = 0;
- }
-
- Genode::memcpy(&_data[wpos], src, first);
- wpos = (wpos + first) % CAPACITY;
-
- if (rest) {
- Genode::memcpy(&_data[wpos], ((char const*)src) + first, rest);
- wpos = (wpos + rest) % CAPACITY;
- }
-
- return limit_len;
- }
-
- Genode::size_t read(void *dst, Genode::size_t len)
- {
- Genode::size_t const avail = read_avail();
- if (avail == 0) return 0;
-
- Genode::size_t const limit_len = len > avail ? avail : len;
- Genode::size_t const total = rpos + len;
- Genode::size_t first, rest;
-
- if (total > CAPACITY) {
- first = CAPACITY - rpos;
- rest = total % CAPACITY;
- } else {
- first = limit_len;
- rest = 0;
- }
-
- Genode::memcpy(dst, &_data[rpos], first);
- rpos = (rpos + first) % CAPACITY;
-
- if (rest) {
- Genode::memcpy(((char*)dst) + first, &_data[rpos], rest);
- rpos = (rpos + rest) % CAPACITY;
- }
-
- return limit_len;
- }
-};
-
-static Ring_buffer<4*1024> audio_frame_buffer;
-static Audio_out::Packet *audio_alloc_pos;
-
-static
-void audio_sample_noop(int16_t left, int16_t right) { }
-
-static
-void audio_sample_callback(int16_t left, int16_t right)
-{
- Audio_out::Stream *sl = global_frontend->stereo_out->left.stream();
- Audio_out::Stream *sr = global_frontend->stereo_out->right.stream();
- Audio_out::Packet *pl = 0;
- Audio_out::Packet *pr = 0;
-
- if (audio_alloc_pos == nullptr)
- audio_alloc_pos = global_frontend->stereo_out->left.stream()->next();
-
- try {
- int16_t tmp[Audio_out::PERIOD * 2];
- size_t const n = audio_frame_buffer.read(tmp, sizeof(tmp));
- (void)n;
-
- pl = sl->next(audio_alloc_pos);
- pr = sr->next(audio_alloc_pos);
-
- float *left_content = pl->content();
- float *right_content = pr->content();
-
- for (int i = 0; i < Audio_out::PERIOD; i++) {
- left_content[i] = (float)(left) / 32768.0f;
- right_content[i] = (float)(right) / 32768.0f;
- }
-
- global_frontend->stereo_out->left.submit(pl);
- global_frontend->stereo_out->right.submit(pr);
-
- audio_alloc_pos = pl;
-
- } catch (...) {
- Genode::error(__func__, " failed to submit audio frames");
- }
-}
-
-static
-size_t audio_sample_batch_noop(const int16_t *data, size_t frames) { return 0; }
-
-static
-size_t audio_sample_batch_callback(const int16_t *data, size_t frames)
-{
- audio_frame_buffer.write(data, frames * 2 * 2);
-
- if (audio_frame_buffer.read_avail() > Audio_out::PERIOD * 2 * 2) {
-
- Audio_out::Stream *sl = global_frontend->stereo_out->left.stream();
- Audio_out::Stream *sr = global_frontend->stereo_out->right.stream();
- Audio_out::Packet *pl = 0;
- Audio_out::Packet *pr = 0;
-
- if (audio_alloc_pos == nullptr) {
- audio_alloc_pos = global_frontend->stereo_out->left.stream()->next();
- }
-
- try {
- int16_t tmp[Audio_out::PERIOD * 2];
- size_t const n = audio_frame_buffer.read(tmp, sizeof(tmp));
- (void)n;
-
- pl = sl->next(audio_alloc_pos);
- pr = sr->next(audio_alloc_pos);
-
- float *left_content = pl->content();
- float *right_content = pr->content();
-
- for (int i = 0; i < Audio_out::PERIOD; i++) {
- left_content[i] = (float)(tmp[i * 2 + 0]) / 32768.0f;
- right_content[i] = (float)(tmp[i * 2 + 1]) / 32768.0f;
- }
-
- global_frontend->stereo_out->left.submit(pl);
- global_frontend->stereo_out->right.submit(pr);
-
- audio_alloc_pos = pl;
-
- } catch (...) {
- Genode::error(__func__, " failed to submit audio frames");
- }
- }
-
- return frames;
+ framebuffer->session.refresh(0, 0, width, height);
}
@@ -461,10 +289,10 @@ static
int16_t input_state_callback(unsigned port, unsigned device,
unsigned index, unsigned id)
{
+ using namespace Retro_frontend;
+
Controller *controller = &global_frontend->controller;
return controller ? controller->event(device, index, id) : 0;
}
-}
-
#endif
diff --git a/src/app/retro_frontend/component.cc b/src/app/retro_frontend/component.cc
index 4d4bf4e..1010287 100644
--- a/src/app/retro_frontend/component.cc
+++ b/src/app/retro_frontend/component.cc
@@ -11,10 +11,13 @@
* under the terms of the GNU General Public License version 2.
*/
+/* libc includes */
+#include
+
#include "frontend.h"
#include "callbacks.h"
-Libretro::Frontend::Frontend(Genode::Env &env) : env(env)
+Retro_frontend::Frontend::Frontend(Libc::Env &env) : env(env)
{
/* set the global frontend pointer for callbacks */
global_frontend = this;
@@ -55,7 +58,6 @@ Libretro::Frontend::Frontend(Genode::Env &env) : env(env)
shared_object.lookup
("retro_set_audio_sample_batch")(&audio_sample_batch_callback);
-
} catch (...) {
shared_object.lookup
@@ -143,18 +145,17 @@ Libretro::Frontend::Frontend(Genode::Env &env) : env(env)
}
-Genode::size_t Component::stack_size() { return 16*1024*sizeof(Genode::addr_t); }
+/* each core will drive the stack differently, so be generous */
+Genode::size_t Component::stack_size() { return 64*1024*sizeof(Genode::addr_t); }
-void Component::construct(Genode::Env &env)
+void Libc::Component::construct(Libc::Env &env)
{
using namespace Genode;
+ using namespace Retro_frontend;
- Libretro::init_keyboard_map();
+ init_keyboard_map();
- try {
- static Libretro::Frontend inst(env);
- return;
- }
+ try { static Frontend inst(env); }
catch (Shared_object::Invalid_rom_module) {
error("failed to load core"); }
@@ -162,6 +163,8 @@ void Component::construct(Genode::Env &env)
catch (Shared_object::Invalid_symbol) {
error("failed to load required symbols from core"); }
- catch (...) { error("failed to init core"); }
- env.parent().exit(-1);
+ catch (...) {
+ error("failed to init core");
+ env.parent().exit(-1);
+ }
}
diff --git a/src/app/retro_frontend/frontend.h b/src/app/retro_frontend/frontend.h
index 33fc1a5..78c6034 100644
--- a/src/app/retro_frontend/frontend.h
+++ b/src/app/retro_frontend/frontend.h
@@ -15,7 +15,6 @@
#define _RETRO_FRONTEND__FRONTEND_H_
/* Genode includes */
-#include
#include
#include
#include
@@ -36,20 +35,41 @@
#include
/* Local includes */
+#include "audio.h"
#include "input.h"
-namespace Libretro {
-#include
+namespace Retro_frontend {
+ #include
struct Frontend;
+ struct Framebuffer;
}
/* Global frontend instance */
-static Libretro::Frontend *global_frontend = (Libretro::Frontend*)(Genode::addr_t)666;
+static Retro_frontend::Frontend *global_frontend = nullptr;
+
+struct Retro_frontend::Framebuffer
+{
+ ::Framebuffer::Connection session;
+
+ ::Framebuffer::Mode mode;
+
+ Genode::Attached_dataspace ds;
+
+ Framebuffer(Genode::Env &env, ::Framebuffer::Mode mode)
+ : session(env, mode), ds(env.rm(), session.dataspace())
+ { update_mode(); }
+
+ void update_mode() { mode = session.mode(); }
+};
+
+
+static Genode::Constructible framebuffer;
+
/**
* Object to encapsulate Genode services
*/
-struct Libretro::Frontend
+struct Retro_frontend::Frontend
{
typedef void (*Retro_set_environment)(retro_environment_t);
typedef void (*Retro_set_video_refresh)(retro_video_refresh_t);
@@ -80,11 +100,12 @@ struct Libretro::Frontend
typedef void *(*Retro_get_memory_data)(unsigned id);
typedef size_t (*Retro_get_memory_size)(unsigned id);
- Genode::Env &env;
- Genode::Heap heap { env.ram(), env.rm() };
+ Libc::Env &env;
Genode::Attached_rom_dataspace config_rom { env, "config" };
+ Genode::Heap heap { env.ram(), env.rm() };
+
typedef Genode::String<128> Name;
Name const name { config_rom.xml().attribute_value("core", Name()) };
@@ -284,42 +305,11 @@ struct Libretro::Frontend
Genode::Signal_handler core_runner
{ env.ep(), *this, &Frontend::run };
- Timer::Connection timer { env };
+ Timer::Connection timer { env };
- struct Framebuffer
- {
- ::Framebuffer::Connection session;
-
- ::Framebuffer::Mode mode;
-
- Genode::Attached_dataspace ds;
-
- Framebuffer(Genode::Env &env, ::Framebuffer::Mode mode)
- : session(env, mode), ds(env.rm(), session.dataspace())
- { update_mode(); }
-
- void update_mode() { mode = session.mode(); }
- };
-
- Genode::Constructible framebuffer;
-
- struct Stereo_out
- {
- Audio_out::Connection left;
- Audio_out::Connection right;
-
- Stereo_out(Genode::Env &env)
- :
- left(env, "left", false, false),
- right(env, "right", false, false)
- { }
- };
-
- Genode::Constructible stereo_out;
-
- Genode::Reporter variable_reporter { "variables" };
- Genode::Reporter subsystem_reporter { "subsystems" };
- Genode::Reporter controller_reporter { "controllers" };
+ Genode::Reporter variable_reporter { env, "variables" };
+ Genode::Reporter subsystem_reporter { env, "subsystems" };
+ Genode::Reporter controller_reporter { env, "controllers" };
Controller controller { env };
@@ -361,6 +351,10 @@ struct Libretro::Frontend
Genode::log("using framebuffer sync as timing source");
framebuffer->session.sync_sigh(core_runner);
}
+
+ /* start the audio streams */
+ if (stereo_out.constructed())
+ stereo_out->start_stream();
}
}
@@ -384,7 +378,7 @@ struct Libretro::Frontend
Genode::Signal_handler resume_handler
{ env.ep(), *this, &Frontend::handle_input };
- Frontend(Genode::Env &env);
+ Frontend(Libc::Env &env);
~Frontend()
{
@@ -394,6 +388,8 @@ struct Libretro::Frontend
void set_av_info(retro_system_av_info &av_info)
{
+ using namespace Retro_frontend;
+
framebuffer.construct(
env, ::Framebuffer::Mode(av_info.geometry.base_width,
av_info.geometry.base_height,
@@ -401,14 +397,16 @@ struct Libretro::Frontend
framebuffer->session.mode_sigh(mode_handler);
- /* start audio streams */
if (stereo_out.constructed()) {
- stereo_out->left.start();
- stereo_out->right.start();
+ double ratio = (double)Audio_out::SAMPLE_RATE / av_info.timing.sample_rate;
+
+ audio_shift_factor = SHIFT_ONE / ratio;
+ audio_input_period = Audio_out::PERIOD * (1.0f / ratio);
}
quarter_fps = av_info.timing.fps / 4;
fb_sync_sample_count = 0;
+
framebuffer->session.sync_sigh(fb_sync_sampler);
}
@@ -420,6 +418,9 @@ struct Libretro::Frontend
framebuffer->session.sync_sigh(Genode::Signal_context_capability());
timer.sigh(Genode::Signal_context_capability());
+ /* stop playpack */
+ stereo_out->stop_stream();
+
/* set signal handler for unpausing */
controller.input.sigh(resume_handler);
diff --git a/src/app/retro_frontend/input.h b/src/app/retro_frontend/input.h
index ebe9d2e..aafd598 100644
--- a/src/app/retro_frontend/input.h
+++ b/src/app/retro_frontend/input.h
@@ -18,7 +18,7 @@
#include
#include
-namespace Libretro {
+namespace Retro_frontend {
#include
struct Controller;
@@ -27,7 +27,7 @@ namespace Libretro {
}
-struct Libretro::Controller
+struct Retro_frontend::Controller
{
enum {
RETRO_JOYPAD_MAX = RETRO_DEVICE_ID_JOYPAD_R3+1,
@@ -152,7 +152,7 @@ struct Libretro::Controller
};
-namespace Libretro {
+namespace Retro_frontend {
void init_keyboard_map()
{