From 89a77be73df04adbf56296d0b5c684833b2b8454 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 12 Jan 2017 20:00:06 +0100 Subject: [PATCH] retro_frontend: get core variables by ROM Ref #60 --- src/app/retro_frontend/callbacks.h | 54 ++++++++++++++++++----------- src/app/retro_frontend/component.cc | 15 ++++---- src/app/retro_frontend/frontend.h | 13 +++++++ 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/app/retro_frontend/callbacks.h b/src/app/retro_frontend/callbacks.h index 3e67e1f..58d948f 100644 --- a/src/app/retro_frontend/callbacks.h +++ b/src/app/retro_frontend/callbacks.h @@ -16,17 +16,20 @@ #include "frontend.h" -/** - * Doesn't work +/* vsnprintf */ +#include + static -void log_callback(enum retro_log_level level, const char *fmt, ...) +void log_printf_callback(Retro_frontend::retro_log_level level, const char *fmt, ...) { + using namespace Retro_frontend; + char buf[Genode::Log_session::MAX_STRING_LEN]; va_list vp; va_start(vp, fmt); - Genode::snprintf(buf, sizeof(buf), fmt, vp); + ::vsnprintf(buf, sizeof(buf), fmt, vp); va_end(vp); char const *msg = buf; @@ -39,7 +42,6 @@ void log_callback(enum retro_log_level level, const char *fmt, ...) case RETRO_LOG_DUMMY: Genode::log("Dummy: ", msg); return; } } -*/ static @@ -101,13 +103,26 @@ bool environment_callback(unsigned cmd, void *data) case RETRO_ENVIRONMENT_GET_VARIABLE: { - /******************************************** - ** TODO: Retrieve variables set by parent ** - ********************************************/ + retro_variable *out = (retro_variable*)data; + Genode::warning("RETRO_ENVIRONMENT_GET_VARIABLE ", out->key); - const retro_variable *var = (retro_variable*)data; - Genode::warning("RETRO_ENVIRONMENT_GET_VARIABLE ", var->key); - return false; + out->value = NULL; + + static char var_buf[256]; + + typedef Genode::String<32> String; + auto const f = [&] (Genode::Xml_node const &in) { + if (in.attribute_value("key", String()) == out->key && + in.has_attribute("value")) + { + in.attribute("value").value(var_buf, sizeof(var_buf)); + out->value = var_buf; + } + }; + + global_frontend->variables().for_each_sub_node("variable", f); + + return out->value != NULL; } case RETRO_ENVIRONMENT_SET_VARIABLES: @@ -144,14 +159,12 @@ bool environment_callback(unsigned cmd, void *data) // global_frontend->core.supports_null_load = data; // return true; - /* case RETRO_ENVIRONMENT_GET_LOG_INTERFACE: { - retro_log_callback *cb = ( retro_log_callback*)data; - cb->log = log_callback; + retro_log_callback *cb = (retro_log_callback*)data; + cb->log = log_printf_callback; return true; } - */ case RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO: { @@ -255,11 +268,15 @@ void video_refresh_callback(const void *data, unsigned src_width, unsigned src_height, size_t src_pitch) { + if (!framebuffer.constructed()) + return; /* tyrquake does this during 'retro_load_game' */ + using namespace Retro_frontend; using namespace Genode; - if (data == NULL) /* frame duping? */ + if (data == NULL) /* frame duping? */ { return; + } uint8_t const *src = (uint8_t const*)data; uint8_t *dst = framebuffer->ds.local_addr(); @@ -289,10 +306,7 @@ 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; + return global_frontend->controller.event(device, index, id); } #endif diff --git a/src/app/retro_frontend/component.cc b/src/app/retro_frontend/component.cc index 1010287..bc4263c 100644 --- a/src/app/retro_frontend/component.cc +++ b/src/app/retro_frontend/component.cc @@ -22,7 +22,6 @@ Retro_frontend::Frontend::Frontend(Libc::Env &env) : env(env) /* set the global frontend pointer for callbacks */ global_frontend = this; - /**************** ** Initialize ** ****************/ @@ -38,7 +37,7 @@ Retro_frontend::Frontend::Frontend(Libc::Env &env) : env(env) sys_info.valid_extensions : ""); shared_object.lookup - ("retro_set_environment")(&environment_callback); + ("retro_set_environment")(environment_callback); shared_object.lookup("retro_init")(); @@ -54,24 +53,24 @@ Retro_frontend::Frontend::Frontend(Libc::Env &env) : env(env) stereo_out.construct(env); shared_object.lookup - ("retro_set_audio_sample")(&audio_sample_callback); + ("retro_set_audio_sample")(audio_sample_callback); shared_object.lookup - ("retro_set_audio_sample_batch")(&audio_sample_batch_callback); + ("retro_set_audio_sample_batch")(audio_sample_batch_callback); } catch (...) { shared_object.lookup - ("retro_set_audio_sample")(&audio_sample_noop); + ("retro_set_audio_sample")(audio_sample_noop); shared_object.lookup - ("retro_set_audio_sample_batch")(&audio_sample_batch_noop); + ("retro_set_audio_sample_batch")(audio_sample_batch_noop); } shared_object.lookup - ("retro_set_input_poll")(&input_poll_callback); + ("retro_set_input_poll")(input_poll_callback); shared_object.lookup - ("retro_set_input_state")(&input_state_callback); + ("retro_set_input_state")(input_state_callback); /******************** diff --git a/src/app/retro_frontend/frontend.h b/src/app/retro_frontend/frontend.h index 78c6034..720ae89 100644 --- a/src/app/retro_frontend/frontend.h +++ b/src/app/retro_frontend/frontend.h @@ -104,6 +104,8 @@ struct Retro_frontend::Frontend Genode::Attached_rom_dataspace config_rom { env, "config" }; + Genode::Constructible var_rom; + Genode::Heap heap { env.ram(), env.rm() }; typedef Genode::String<128> Name; @@ -429,6 +431,17 @@ struct Retro_frontend::Frontend } } + Genode::Xml_node variables() + { + try { + if (!var_rom.constructed()) + var_rom.construct(env, "variables"); + return var_rom->xml(); + } catch (...) { + return Genode::Xml_node(""); + } + } + }; #endif