예제 #1
0
static void init_video_input(const input_driver_t *tmp)
{
   driver_t *driver = driver_get_ptr();

   /* Reset video frame count */
   video_frame_count = 0;

   /* Video driver didn't provide an input driver,
    * so we use configured one. */
   RARCH_LOG("Graphics driver did not initialize an input driver. Attempting to pick a suitable driver.\n");

   if (tmp)
      driver->input = tmp;
   else
      find_input_driver();

   if (!driver->input)
   {
      /* This should never really happen as tmp (driver.input) is always
       * found before this in find_driver_input(), or we have aborted
       * in a similar fashion anyways. */
      retro_fail(1, "init_video_input()");
   }

   driver->input_data = input_driver_init();

   if (driver->input_data)
      return;

   RARCH_ERR("Cannot initialize input driver. Exiting ...\n");
   retro_fail(1, "init_video_input()");
}
예제 #2
0
void init_menu(void)
{
   if (menu_driver_data)
      return;

   find_menu_driver();

   if (!(menu_driver_data = (menu_handle_t*)menu_init(menu_driver_ctx)))
      retro_fail(1, "init_menu()");

   if (menu_driver_ctx->lists_init)
      if (!menu_driver_ctx->lists_init(menu_driver_data))
         retro_fail(1, "init_menu()");
}
예제 #3
0
void find_location_driver(void)
{
   int i;
   driver_ctx_info_t drv;
   settings_t *settings = config_get_ptr();

   drv.label = "location_driver";
   drv.s     = settings->location.driver;

   driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

   i = drv.len;

   if (i >= 0)
      location_driver = (const location_driver_t*)location_driver_find_handle(i);
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any location driver named \"%s\"\n",
            settings->location.driver);
      RARCH_LOG_OUTPUT("Available location drivers are:\n");
      for (d = 0; location_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", location_driver_find_ident(d));
       
      RARCH_WARN("Going to default to first location driver...\n");
       
      location_driver = (const location_driver_t*)location_driver_find_handle(0);

      if (!location_driver)
         retro_fail(1, "find_location_driver()");
   }
}
예제 #4
0
void find_camera_driver(void)
{
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();
   int i = find_driver_index("camera_driver", settings->camera.driver);

   if (i >= 0)
      driver->camera = (const camera_driver_t*)camera_driver_find_handle(i);
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any camera driver named \"%s\"\n",
            settings->camera.driver);
      RARCH_LOG_OUTPUT("Available camera drivers are:\n");
      for (d = 0; camera_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", camera_driver_find_ident(d));
       
      RARCH_WARN("Going to default to first camera driver...\n");
       
      driver->camera = (const camera_driver_t*)camera_driver_find_handle(0);
       
      if (!driver->camera)
         retro_fail(1, "find_camera_driver()");
   }
}
예제 #5
0
void init_menu(void)
{
   driver_t *driver     = driver_get_ptr();

   if (driver->menu)
      return;

   find_menu_driver();

   if (!menu_display_check_compatibility((enum menu_display_driver_type)driver->menu_ctx->type))
      init_menu_fallback();

   if (!(driver->menu = (menu_handle_t*)menu_init(driver->menu_ctx)))
      retro_fail(1, "init_menu()");

   if (driver->menu_ctx->lists_init)
      if (!driver->menu_ctx->lists_init(driver->menu))
         retro_fail(1, "init_menu()");
}
예제 #6
0
static void load_dynamic_core(void)
{
   settings_t *settings = config_get_ptr();
   function_t sym       = dylib_proc(NULL, "retro_init");

   if (sym)
   {
      /* Try to verify that -lretro was not linked in from other modules
       * since loading it dynamically and with -l will fail hard. */
      RARCH_ERR("Serious problem. RetroArch wants to load libretro cores dyamically, but it is already linked.\n");
      RARCH_ERR("This could happen if other modules RetroArch depends on link against libretro directly.\n");
      RARCH_ERR("Proceeding could cause a crash. Aborting ...\n");
      retro_fail(1, "init_libretro_sym()");
   }

   if (!*settings->libretro)
   {
      RARCH_ERR("RetroArch is built for dynamic libretro cores, but libretro_path is not set. Cannot continue.\n");
      retro_fail(1, "init_libretro_sym()");
   }

   /* Need to use absolute path for this setting. It can be
    * saved to content history, and a relative path would
    * break in that scenario. */
   path_resolve_realpath(settings->libretro, sizeof(settings->libretro));

   RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
         settings->libretro);
   lib_handle = dylib_load(settings->libretro);
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open libretro core: \"%s\"\n",
            settings->libretro);
      RARCH_ERR("Error(s): %s\n", dylib_error());
      retro_fail(1, "load_dynamic()");
   }
}
예제 #7
0
static void bsv_movie_init_state(void)
{
   settings_t *settings = config_get_ptr();

   if (bsv_movie_ctl(BSV_MOVIE_CTL_START_PLAYBACK, NULL))
   {
      if (!(bsv_movie_init_handle(bsv_movie_state.movie_start_path,
                  RARCH_MOVIE_PLAYBACK)))
      {
         RARCH_ERR("%s: \"%s\".\n",
               msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE),
               bsv_movie_state.movie_start_path);
         retro_fail(1, "event_init_movie()");
      }

      bsv_movie_state.movie_playback = true;
      runloop_msg_queue_push(msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK),
            2, 180, false);
      RARCH_LOG("%s.\n", msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK));
      settings->rewind_granularity = 1;
   }
   else if (bsv_movie_ctl(BSV_MOVIE_CTL_START_RECORDING, NULL))
   {
      char msg[256];
      snprintf(msg, sizeof(msg),
            "%s \"%s\".",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            bsv_movie_state.movie_start_path);

      if (!(bsv_movie_init_handle(bsv_movie_state.movie_start_path,
                  RARCH_MOVIE_RECORD)))
      {
         runloop_msg_queue_push(
               msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD),
               1, 180, true);
         RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD));
         return;
      }

      runloop_msg_queue_push(msg, 1, 180, true);
      RARCH_LOG("%s \"%s\".\n",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            bsv_movie_state.movie_start_path);
      settings->rewind_granularity = 1;
   }
}
예제 #8
0
void find_video_driver(void)
{
   int i;
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();

#if defined(HAVE_OPENGL) && defined(HAVE_FBO)
   if (video_state.hw_render_callback.context_type)
   {
      RARCH_LOG("Using HW render, OpenGL driver forced.\n");
      driver->video = &video_gl;
      return;
   }
#endif

   if (driver->frontend_ctx &&
       driver->frontend_ctx->get_video_driver)
   {
      driver->video = driver->frontend_ctx->get_video_driver();

      if (driver->video)
         return;
      RARCH_WARN("Frontend supports get_video_driver() but did not specify one.\n");
   }

   i = find_driver_index("video_driver", settings->video.driver);
   if (i >= 0)
      driver->video = (const video_driver_t*)video_driver_find_handle(i);
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any video driver named \"%s\"\n",
            settings->video.driver);
      RARCH_LOG_OUTPUT("Available video drivers are:\n");
      for (d = 0; video_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", video_driver_find_ident(d));
      RARCH_WARN("Going to default to first video driver...\n");

      driver->video = (const video_driver_t*)video_driver_find_handle(0);

      if (!driver->video)
         retro_fail(1, "find_video_driver()");
   }
}
예제 #9
0
void find_menu_driver(void)
{
   settings_t *settings = config_get_ptr();

   int i = find_driver_index("menu_driver", settings->menu.driver);
   if (i >= 0)
      menu_driver_ctx = (const menu_ctx_driver_t*)menu_driver_find_handle(i);
   else
   {
      unsigned d;
      RARCH_WARN("Couldn't find any menu driver named \"%s\"\n",
            settings->menu.driver);
      RARCH_LOG_OUTPUT("Available menu drivers are:\n");
      for (d = 0; menu_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d));
      RARCH_WARN("Going to default to first menu driver...\n");

      menu_driver_ctx = (const menu_ctx_driver_t*)menu_driver_find_handle(0);

      if (!menu_driver_ctx)
         retro_fail(1, "find_menu_driver()");
   }
}
예제 #10
0
void find_record_driver(void)
{
   settings_t *settings = config_get_ptr();
   int                i = find_driver_index("record_driver", settings->record.driver);

   if (i >= 0)
      recording_driver = (const record_driver_t*)record_driver_find_handle(i);
   else
   {
      unsigned d;

      RARCH_ERR("Couldn't find any record driver named \"%s\"\n",
            settings->audio.driver);
      RARCH_LOG_OUTPUT("Available record drivers are:\n");
      for (d = 0; record_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", record_driver_find_ident(d));
      RARCH_WARN("Going to default to first record driver...\n");

      recording_driver = (const record_driver_t*)record_driver_find_handle(0);

      if (!recording_driver)
         retro_fail(1, "find_record_driver()");
   }
}
예제 #11
0
void find_location_driver(void)
{
   settings_t *settings = config_get_ptr();
   int i                = find_driver_index("location_driver", settings->location.driver);

   if (i >= 0)
      location_driver = (const location_driver_t*)location_driver_find_handle(i);
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any location driver named \"%s\"\n",
            settings->location.driver);
      RARCH_LOG_OUTPUT("Available location drivers are:\n");
      for (d = 0; location_driver_find_handle(d); d++)
         RARCH_LOG_OUTPUT("\t%s\n", location_driver_find_ident(d));
       
      RARCH_WARN("Going to default to first location driver...\n");
       
      location_driver = (const location_driver_t*)location_driver_find_handle(0);

      if (!location_driver)
         retro_fail(1, "find_location_driver()");
   }
}
예제 #12
0
bool input_driver_ctl(enum rarch_input_ctl_state state, void *data)
{
   static bool input_driver_block_hotkey             = false;
   static bool input_driver_block_libretro_input     = false;
   static bool input_driver_osk_enabled              = false;
   static bool input_driver_keyboard_linefeed_enable = false;
   static bool input_driver_nonblock_state           = false;
   static bool input_driver_flushing_input           = false;
   static bool input_driver_data_own                 = false;

   switch (state)
   {
      case RARCH_INPUT_CTL_KEY_PRESSED:
         {
            unsigned *key = (unsigned*)data;
            if (key && current_input->key_pressed)
               return current_input->key_pressed(current_input_data, *key);
         }
         return false;
      case RARCH_INPUT_CTL_HAS_CAPABILITIES:
         if (!current_input->get_capabilities || !current_input_data)
            return false;
         break;
      case RARCH_INPUT_CTL_POLL:
         current_input->poll(current_input_data);
         break;
      case RARCH_INPUT_CTL_INIT:
         if (current_input)
            current_input_data = current_input->init();

         if (!current_input_data)
            return false;
         break;
      case RARCH_INPUT_CTL_DEINIT:
         if (current_input && current_input->free)
            current_input->free(current_input_data);
         current_input_data = NULL;
         break;
      case RARCH_INPUT_CTL_DESTROY_DATA:
         current_input_data = NULL;
         break;
      case RARCH_INPUT_CTL_DESTROY:
         input_driver_block_hotkey             = false;
         input_driver_block_libretro_input     = false;
         input_driver_keyboard_linefeed_enable = false;
         input_driver_nonblock_state           = false;
         input_driver_flushing_input           = false;
         input_driver_data_own                 = false;
         memset(&input_driver_turbo_btns, 0, sizeof(turbo_buttons_t));
         current_input                         = NULL;
         break;
      case RARCH_INPUT_CTL_GRAB_STDIN:
         if (!current_input->grab_stdin)
            return false;
         return current_input->grab_stdin(current_input_data);
      case RARCH_INPUT_CTL_KB_MAPPING_IS_BLOCKED:
         if (!current_input->keyboard_mapping_is_blocked)
            return false;
         return current_input->keyboard_mapping_is_blocked(
               current_input_data);
      case RARCH_INPUT_CTL_FIND_DRIVER:
         {
            int i;
            driver_ctx_info_t drv;
            settings_t *settings = config_get_ptr();

            drv.label = "input_driver";
            drv.s     = settings->input.driver;

            driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

            i = drv.len;

            if (i >= 0)
               current_input = (const input_driver_t*)
                  input_driver_find_handle(i);
            else
            {
               unsigned d;
               RARCH_ERR("Couldn't find any input driver named \"%s\"\n",
                     settings->input.driver);
               RARCH_LOG_OUTPUT("Available input drivers are:\n");
               for (d = 0; input_driver_find_handle(d); d++)
                  RARCH_LOG_OUTPUT("\t%s\n", input_driver_find_ident(d));
               RARCH_WARN("Going to default to first input driver...\n");

               current_input = (const input_driver_t*)
                  input_driver_find_handle(0);

               if (current_input)
                  return true;
               retro_fail(1, "find_input_driver()");
               return false;
            }
         }
         break;
      case RARCH_INPUT_CTL_SET_FLUSHING_INPUT:
         input_driver_flushing_input = true;
         break;
      case RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT:
         input_driver_flushing_input = false;
         break;
      case RARCH_INPUT_CTL_IS_FLUSHING_INPUT:
         return input_driver_flushing_input;
      case RARCH_INPUT_CTL_SET_HOTKEY_BLOCK:
         input_driver_block_hotkey = true;
         break;
      case RARCH_INPUT_CTL_UNSET_HOTKEY_BLOCK:
         input_driver_block_hotkey = false;
         break;
      case RARCH_INPUT_CTL_IS_HOTKEY_BLOCKED:
         return input_driver_block_hotkey;
      case RARCH_INPUT_CTL_SET_LIBRETRO_INPUT_BLOCKED:
         input_driver_block_libretro_input = true;
         break;
      case RARCH_INPUT_CTL_UNSET_LIBRETRO_INPUT_BLOCKED:
         input_driver_block_libretro_input = false;
         break;
      case RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED:
         return input_driver_block_libretro_input;
      case RARCH_INPUT_CTL_SET_NONBLOCK_STATE:
         input_driver_nonblock_state = true;
         break;
      case RARCH_INPUT_CTL_UNSET_NONBLOCK_STATE:
         input_driver_nonblock_state = false;
         break;
      case RARCH_INPUT_CTL_IS_NONBLOCK_STATE:
         return input_driver_nonblock_state;
      case RARCH_INPUT_CTL_SET_OWN_DRIVER:
         input_driver_data_own = true;
         break;
      case RARCH_INPUT_CTL_UNSET_OWN_DRIVER:
         input_driver_data_own = false;
         break;
      case RARCH_INPUT_CTL_OWNS_DRIVER:
         return input_driver_data_own;
      case RARCH_INPUT_CTL_SET_OSK_ENABLED:
         input_driver_osk_enabled = true;
         break;
      case RARCH_INPUT_CTL_UNSET_OSK_ENABLED:
         input_driver_osk_enabled = false;
         break;
      case RARCH_INPUT_CTL_IS_OSK_ENABLED:
         return input_driver_osk_enabled;
      case RARCH_INPUT_CTL_SET_KEYBOARD_LINEFEED_ENABLED:
         input_driver_keyboard_linefeed_enable = true;
         break;
      case RARCH_INPUT_CTL_UNSET_KEYBOARD_LINEFEED_ENABLED:
         input_driver_keyboard_linefeed_enable = false;
         break;
      case RARCH_INPUT_CTL_IS_KEYBOARD_LINEFEED_ENABLED:
         return input_driver_keyboard_linefeed_enable;
      case RARCH_INPUT_CTL_COMMAND_INIT:
#ifdef HAVE_COMMAND
         input_driver_command_init();
#endif
         break;
      case RARCH_INPUT_CTL_COMMAND_DEINIT:
#ifdef HAVE_COMMAND
         if (input_driver_command)
            rarch_cmd_free(input_driver_command);
         input_driver_command = NULL;
#endif
         break;
      case RARCH_INPUT_CTL_REMOTE_DEINIT:
#ifdef HAVE_NETWORK_GAMEPAD
         if (input_driver_remote)
            rarch_remote_free(input_driver_remote);
         input_driver_remote = NULL;
#endif
         break;
      case RARCH_INPUT_CTL_REMOTE_INIT:
#ifdef HAVE_NETWORK_GAMEPAD
         input_driver_remote_init();
#endif
         break;
      case RARCH_INPUT_CTL_NONE:
      default:
         break;
   }

   return true;
}
예제 #13
0
void init_video(void)
{
   unsigned max_dim, scale, width, height;
   video_viewport_t *custom_vp      = NULL;
   const input_driver_t *tmp        = NULL;
   const struct retro_game_geometry *geom = NULL;
   video_info_t video               = {0};
   static uint16_t dummy_pixels[32] = {0};
   driver_t *driver                 = driver_get_ptr();
   settings_t *settings             = config_get_ptr();
   rarch_system_info_t *system      = rarch_system_info_get_ptr();
   struct retro_system_av_info *av_info =
      video_viewport_get_system_av_info();

   init_video_filter(video_state.pix_fmt);
   event_command(EVENT_CMD_SHADER_DIR_INIT);

   if (av_info)
      geom      = (const struct retro_game_geometry*)&av_info->geometry;

   if (!geom)
   {
      RARCH_ERR("AV geometry not initialized, cannot initialize video driver.\n");
      retro_fail(1, "init_video()");
   }

   max_dim   = max(geom->max_width, geom->max_height);
   scale     = next_pow2(max_dim) / RARCH_SCALE_BASE;
   scale     = max(scale, 1);

   if (video_state.filter.filter)
      scale = video_state.filter.scale;

   /* Update core-dependent aspect ratio values. */
   video_viewport_set_square_pixel(geom->base_width, geom->base_height);
   video_viewport_set_core();
   video_viewport_set_config();

   /* Update CUSTOM viewport. */
   custom_vp = video_viewport_get_custom();

   if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
   {
      float default_aspect = aspectratio_lut[ASPECT_RATIO_CORE].value;
      aspectratio_lut[ASPECT_RATIO_CUSTOM].value =
         (custom_vp->width && custom_vp->height) ?
         (float)custom_vp->width / custom_vp->height : default_aspect;
   }

   video_driver_set_aspect_ratio_value(
      aspectratio_lut[settings->video.aspect_ratio_idx].value);

   if (settings->video.fullscreen)
   {
      width  = settings->video.fullscreen_x;
      height = settings->video.fullscreen_y;
   }
   else
   {
      if (settings->video.force_aspect)
      {
         /* Do rounding here to simplify integer scale correctness. */
         unsigned base_width =
            roundf(geom->base_height * video_driver_get_aspect_ratio());
         width  = roundf(base_width * settings->video.scale);
      }
      else
         width  = roundf(geom->base_width   * settings->video.scale);
      height = roundf(geom->base_height * settings->video.scale);
   }

   if (width && height)
      RARCH_LOG("Video @ %ux%u\n", width, height);
   else
      RARCH_LOG("Video @ fullscreen\n");

   driver->display_type  = RARCH_DISPLAY_NONE;
   driver->video_display = 0;
   driver->video_window  = 0;

   if (!init_video_pixel_converter(RARCH_SCALE_BASE * scale))
   {
      RARCH_ERR("Failed to initialize pixel converter.\n");
      retro_fail(1, "init_video()");
   }

   video.width        = width;
   video.height       = height;
   video.fullscreen   = settings->video.fullscreen;
   video.vsync        = settings->video.vsync && !system->force_nonblock;
   video.force_aspect = settings->video.force_aspect;
#ifdef GEKKO
   video.viwidth      = settings->video.viwidth;
   video.vfilter      = settings->video.vfilter;
#endif
   video.smooth       = settings->video.smooth;
   video.input_scale  = scale;
   video.rgb32        = video_state.filter.filter ?
      video_state.filter.out_rgb32 :
      (video_state.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888);

   tmp = (const input_driver_t*)driver->input;
   /* Need to grab the "real" video driver interface on a reinit. */
   find_video_driver();

#ifdef HAVE_THREADS
   if (settings->video.threaded && !video_state.hw_render_callback.context_type)
   {
      /* Can't do hardware rendering with threaded driver currently. */
      RARCH_LOG("Starting threaded video driver ...\n");

      if (!rarch_threaded_video_init(&driver->video, &driver->video_data,
               &driver->input, &driver->input_data,
               driver->video, &video))
      {
         RARCH_ERR("Cannot open threaded video driver ... Exiting ...\n");
         retro_fail(1, "init_video()");
      }
   }
   else
#endif
      driver->video_data = driver->video->init(&video, &driver->input,
            &driver->input_data);

   if (!driver->video_data)
   {
      RARCH_ERR("Cannot open video driver ... Exiting ...\n");
      retro_fail(1, "init_video()");
   }

   driver->video_poke = NULL;
   if (driver->video->poke_interface)
      driver->video->poke_interface(driver->video_data, &driver->video_poke);

   if (driver->video->viewport_info && (!custom_vp->width ||
            !custom_vp->height))
   {
      /* Force custom viewport to have sane parameters. */
      custom_vp->width = width;
      custom_vp->height = height;
      video_driver_viewport_info(custom_vp);
   }

   video_driver_set_rotation(
            (settings->video.rotation + system->rotation) % 4);

   video_driver_suppress_screensaver(settings->ui.suspend_screensaver_enable);

   if (!driver->input)
      init_video_input(tmp);

   event_command(EVENT_CMD_OVERLAY_DEINIT);
   event_command(EVENT_CMD_OVERLAY_INIT);

   video_driver_cached_frame_set(&dummy_pixels, 4, 4, 8);

#if defined(PSP)
   video_driver_set_texture_frame(&dummy_pixels, false, 1, 1, 1.0f);
#endif
}
예제 #14
0
파일: dynamic.c 프로젝트: Ced2911/RetroArch
/**
 * load_symbols:
 * @type                        : Type of core to be loaded.
 *                                If CORE_TYPE_DUMMY, will
 *                                load dummy symbols.
 *
 * Setup libretro callback symbols.
 **/
static void load_symbols(enum rarch_core_type type)
{
   switch (type)
   {
      case CORE_TYPE_PLAIN:
         {
#ifdef HAVE_DYNAMIC
            settings_t *settings = config_get_ptr();
            function_t sym       = dylib_proc(NULL, "retro_init");

            if (sym)
            {
               /* Try to verify that -lretro was not linked in from other modules
                * since loading it dynamically and with -l will fail hard. */
               RARCH_ERR("Serious problem. RetroArch wants to load libretro cores dyamically, but it is already linked.\n");
               RARCH_ERR("This could happen if other modules RetroArch depends on link against libretro directly.\n");
               RARCH_ERR("Proceeding could cause a crash. Aborting ...\n");
               retro_fail(1, "init_libretro_sym()");
            }

            if (!*settings->libretro)
            {
               RARCH_ERR("RetroArch is built for dynamic libretro cores, but libretro_path is not set. Cannot continue.\n");
               retro_fail(1, "init_libretro_sym()");
            }

            /* Need to use absolute path for this setting. It can be
             * saved to content history, and a relative path would
             * break in that scenario. */
            path_resolve_realpath(settings->libretro,
                  sizeof(settings->libretro));

            RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
                  settings->libretro);
            lib_handle = dylib_load(settings->libretro);
            if (!lib_handle)
            {
               RARCH_ERR("Failed to open libretro core: \"%s\"\n",
                     settings->libretro);
               RARCH_ERR("Error(s): %s\n", dylib_error());
               retro_fail(1, "load_dynamic()");
            }
#endif
         }

         SYMBOL(retro_init);
         SYMBOL(retro_deinit);

         SYMBOL(retro_api_version);
         SYMBOL(retro_get_system_info);
         SYMBOL(retro_get_system_av_info);

         SYMBOL(retro_set_environment);
         SYMBOL(retro_set_video_refresh);
         SYMBOL(retro_set_audio_sample);
         SYMBOL(retro_set_audio_sample_batch);
         SYMBOL(retro_set_input_poll);
         SYMBOL(retro_set_input_state);

         SYMBOL(retro_set_controller_port_device);

         SYMBOL(retro_reset);
         SYMBOL(retro_run);

         SYMBOL(retro_serialize_size);
         SYMBOL(retro_serialize);
         SYMBOL(retro_unserialize);

         SYMBOL(retro_cheat_reset);
         SYMBOL(retro_cheat_set);

         SYMBOL(retro_load_game);
         SYMBOL(retro_load_game_special);

         SYMBOL(retro_unload_game);
         SYMBOL(retro_get_region);
         SYMBOL(retro_get_memory_data);
         SYMBOL(retro_get_memory_size);
         break;
      case CORE_TYPE_DUMMY:
         SYMBOL_DUMMY(retro_init);
         SYMBOL_DUMMY(retro_deinit);

         SYMBOL_DUMMY(retro_api_version);
         SYMBOL_DUMMY(retro_get_system_info);
         SYMBOL_DUMMY(retro_get_system_av_info);

         SYMBOL_DUMMY(retro_set_environment);
         SYMBOL_DUMMY(retro_set_video_refresh);
         SYMBOL_DUMMY(retro_set_audio_sample);
         SYMBOL_DUMMY(retro_set_audio_sample_batch);
         SYMBOL_DUMMY(retro_set_input_poll);
         SYMBOL_DUMMY(retro_set_input_state);

         SYMBOL_DUMMY(retro_set_controller_port_device);

         SYMBOL_DUMMY(retro_reset);
         SYMBOL_DUMMY(retro_run);

         SYMBOL_DUMMY(retro_serialize_size);
         SYMBOL_DUMMY(retro_serialize);
         SYMBOL_DUMMY(retro_unserialize);

         SYMBOL_DUMMY(retro_cheat_reset);
         SYMBOL_DUMMY(retro_cheat_set);

         SYMBOL_DUMMY(retro_load_game);
         SYMBOL_DUMMY(retro_load_game_special);

         SYMBOL_DUMMY(retro_unload_game);
         SYMBOL_DUMMY(retro_get_region);
         SYMBOL_DUMMY(retro_get_memory_data);
         SYMBOL_DUMMY(retro_get_memory_size);
         break;
#ifdef HAVE_FFMPEG
      case CORE_TYPE_FFMPEG:
         SYMBOL_FFMPEG(retro_init);
         SYMBOL_FFMPEG(retro_deinit);

         SYMBOL_FFMPEG(retro_api_version);
         SYMBOL_FFMPEG(retro_get_system_info);
         SYMBOL_FFMPEG(retro_get_system_av_info);

         SYMBOL_FFMPEG(retro_set_environment);
         SYMBOL_FFMPEG(retro_set_video_refresh);
         SYMBOL_FFMPEG(retro_set_audio_sample);
         SYMBOL_FFMPEG(retro_set_audio_sample_batch);
         SYMBOL_FFMPEG(retro_set_input_poll);
         SYMBOL_FFMPEG(retro_set_input_state);

         SYMBOL_FFMPEG(retro_set_controller_port_device);

         SYMBOL_FFMPEG(retro_reset);
         SYMBOL_FFMPEG(retro_run);

         SYMBOL_FFMPEG(retro_serialize_size);
         SYMBOL_FFMPEG(retro_serialize);
         SYMBOL_FFMPEG(retro_unserialize);

         SYMBOL_FFMPEG(retro_cheat_reset);
         SYMBOL_FFMPEG(retro_cheat_set);

         SYMBOL_FFMPEG(retro_load_game);
         SYMBOL_FFMPEG(retro_load_game_special);

         SYMBOL_FFMPEG(retro_unload_game);
         SYMBOL_FFMPEG(retro_get_region);
         SYMBOL_FFMPEG(retro_get_memory_data);
         SYMBOL_FFMPEG(retro_get_memory_size);
         break;
#endif
      case CORE_TYPE_IMAGEVIEWER:
#ifdef HAVE_IMAGEVIEWER
         SYMBOL_IMAGEVIEWER(retro_init);
         SYMBOL_IMAGEVIEWER(retro_deinit);

         SYMBOL_IMAGEVIEWER(retro_api_version);
         SYMBOL_IMAGEVIEWER(retro_get_system_info);
         SYMBOL_IMAGEVIEWER(retro_get_system_av_info);

         SYMBOL_IMAGEVIEWER(retro_set_environment);
         SYMBOL_IMAGEVIEWER(retro_set_video_refresh);
         SYMBOL_IMAGEVIEWER(retro_set_audio_sample);
         SYMBOL_IMAGEVIEWER(retro_set_audio_sample_batch);
         SYMBOL_IMAGEVIEWER(retro_set_input_poll);
         SYMBOL_IMAGEVIEWER(retro_set_input_state);

         SYMBOL_IMAGEVIEWER(retro_set_controller_port_device);

         SYMBOL_IMAGEVIEWER(retro_reset);
         SYMBOL_IMAGEVIEWER(retro_run);

         SYMBOL_IMAGEVIEWER(retro_serialize_size);
         SYMBOL_IMAGEVIEWER(retro_serialize);
         SYMBOL_IMAGEVIEWER(retro_unserialize);

         SYMBOL_IMAGEVIEWER(retro_cheat_reset);
         SYMBOL_IMAGEVIEWER(retro_cheat_set);

         SYMBOL_IMAGEVIEWER(retro_load_game);
         SYMBOL_IMAGEVIEWER(retro_load_game_special);

         SYMBOL_IMAGEVIEWER(retro_unload_game);
         SYMBOL_IMAGEVIEWER(retro_get_region);
         SYMBOL_IMAGEVIEWER(retro_get_memory_data);
         SYMBOL_IMAGEVIEWER(retro_get_memory_size);
#endif
         break;
   }
}
예제 #15
0
bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data)
{
   settings_t        *settings = config_get_ptr();
   static struct retro_camera_callback camera_cb;
   static const camera_driver_t *camera_driver   = NULL;
   static void *camera_data                      = NULL;
   static bool camera_driver_active              = false;
   static bool camera_driver_data_own            = false;

   switch (state)
   {
      case RARCH_CAMERA_CTL_DESTROY:
         camera_driver_active   = false;
         camera_driver_data_own = false;
         camera_driver          = NULL;
         camera_data            = NULL;
         break;
      case RARCH_CAMERA_CTL_SET_OWN_DRIVER:
         camera_driver_data_own = true;
         break;
      case RARCH_CAMERA_CTL_UNSET_OWN_DRIVER:
         camera_driver_data_own = false;
         break;
      case RARCH_CAMERA_CTL_OWNS_DRIVER:
         return camera_driver_data_own;
      case RARCH_CAMERA_CTL_SET_ACTIVE:
         camera_driver_active = true; 
         break;
      case RARCH_CAMERA_CTL_FIND_DRIVER:
         {
            int i;
            driver_ctx_info_t drv;

            drv.label = "camera_driver";
            drv.s     = settings->camera.driver;

            driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

            i = drv.len;

            if (i >= 0)
               camera_driver = (const camera_driver_t*)camera_driver_find_handle(i);
            else
            {
               unsigned d;
               RARCH_ERR("Couldn't find any camera driver named \"%s\"\n",
                     settings->camera.driver);
               RARCH_LOG_OUTPUT("Available camera drivers are:\n");
               for (d = 0; camera_driver_find_handle(d); d++)
                  RARCH_LOG_OUTPUT("\t%s\n", camera_driver_find_ident(d));

               RARCH_WARN("Going to default to first camera driver...\n");

               camera_driver = (const camera_driver_t*)camera_driver_find_handle(0);

               if (!camera_driver)
                  retro_fail(1, "find_camera_driver()");
            }
         }
         break;
      case RARCH_CAMERA_CTL_UNSET_ACTIVE:
         camera_driver_active = false; 
         break;
      case RARCH_CAMERA_CTL_IS_ACTIVE:
        return camera_driver_active; 
      case RARCH_CAMERA_CTL_DEINIT:
        if (camera_data && camera_driver)
        {
           if (camera_cb.deinitialized)
              camera_cb.deinitialized();

           if (camera_driver->free)
              camera_driver->free(camera_data);
        }

        camera_data = NULL;
        break;
      case RARCH_CAMERA_CTL_STOP:
        if (     camera_driver 
              && camera_driver->stop 
              && camera_data)
           camera_driver->stop(camera_data);
        break;
      case RARCH_CAMERA_CTL_START:
        if (camera_driver && camera_data && camera_driver->start)
        {
           if (settings->camera.allow)
              return camera_driver->start(camera_data);

           runloop_msg_queue_push(
                 "Camera is explicitly disabled.\n", 1, 180, false);
        }
        return false;
      case RARCH_CAMERA_CTL_POLL:
        if (!camera_cb.caps)
           return false;
        if (!camera_driver || !camera_driver->poll || !camera_data)
           return false;
        camera_driver->poll(camera_data,
              camera_cb.frame_raw_framebuffer,
              camera_cb.frame_opengl_texture);
        break;
      case RARCH_CAMERA_CTL_SET_CB:
        {
           struct retro_camera_callback *cb =
              (struct retro_camera_callback*)data;
           camera_cb          = *cb;
        }
        break;
      case RARCH_CAMERA_CTL_INIT:
        /* Resource leaks will follow if camera is initialized twice. */
        if (camera_data)
           return false;

        camera_driver_ctl(RARCH_CAMERA_CTL_FIND_DRIVER, NULL);

        camera_data = camera_driver->init(
              *settings->camera.device ? settings->camera.device : NULL,
              camera_cb.caps,
              settings->camera.width ?
              settings->camera.width : camera_cb.width,
              settings->camera.height ?
              settings->camera.height : camera_cb.height);

        if (!camera_data)
        {
           RARCH_ERR("Failed to initialize camera driver. Will continue without camera.\n");
           camera_driver_ctl(RARCH_CAMERA_CTL_UNSET_ACTIVE, NULL);
        }

        if (camera_cb.initialized)
           camera_cb.initialized();
        break;
      default:
         break;
   }
   
   return false;
}
예제 #16
0
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
{
   static struct retro_system_info menu_driver_system;
   static bool menu_driver_pending_quick_menu      = false;
   static bool menu_driver_pending_action          = false;
   static bool menu_driver_prevent_populate        = false;
   static bool menu_driver_load_no_content         = false;
   static bool menu_driver_alive                   = false;
   static bool menu_driver_data_own                = false;
   static bool menu_driver_pending_quit            = false;
   static bool menu_driver_pending_shutdown        = false;
   static content_playlist_t *menu_driver_playlist = NULL;
   static struct video_shader *menu_driver_shader  = NULL;
   static menu_handle_t *menu_driver_data          = NULL;
   static const menu_ctx_driver_t *menu_driver_ctx = NULL;
   static void *menu_userdata                      = NULL;
   settings_t *settings                            = config_get_ptr();

   switch (state)
   {
      case RARCH_MENU_CTL_IS_PENDING_ACTION:
         if (!menu_driver_pending_action)
            return false;
         menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_ACTION, NULL);
         break;
      case RARCH_MENU_CTL_SET_PENDING_ACTION:
         menu_driver_pending_action = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_ACTION:
         menu_driver_pending_action = false;
         break;
      case RARCH_MENU_CTL_DRIVER_DATA_GET:
         {
            menu_handle_t **driver_data = (menu_handle_t**)data;
            if (!driver_data)
               return false;
            *driver_data = menu_driver_data;
         }
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUICK_MENU:
         return menu_driver_pending_quick_menu;
      case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUIT:
         return menu_driver_pending_quit;
      case RARCH_MENU_CTL_SET_PENDING_QUIT:
         menu_driver_pending_quit     = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUIT:
         menu_driver_pending_quit     = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_SHUTDOWN:
         return menu_driver_pending_shutdown;
      case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = false;
         break;
      case RARCH_MENU_CTL_DESTROY:
         menu_driver_pending_quick_menu = false;
         menu_driver_pending_action     = false;
         menu_driver_pending_quit       = false;
         menu_driver_pending_shutdown   = false;
         menu_driver_prevent_populate   = false;
         menu_driver_load_no_content    = false;
         menu_driver_alive              = false;
         menu_driver_data_own           = false;
         menu_driver_ctx                = NULL;
         menu_userdata                  = NULL;
         break;
      case RARCH_MENU_CTL_PLAYLIST_FREE:
         if (menu_driver_playlist)
            content_playlist_free(menu_driver_playlist);
         menu_driver_playlist = NULL;
         break;
      case RARCH_MENU_CTL_FIND_DRIVER:
         {
            int i;
            driver_ctx_info_t drv;
            settings_t *settings = config_get_ptr();

            drv.label = "menu_driver";
            drv.s     = settings->menu.driver;

            driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

            i = drv.len;

            if (i >= 0)
               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(i);
            else
            {
               unsigned d;
               RARCH_WARN("Couldn't find any menu driver named \"%s\"\n",
                     settings->menu.driver);
               RARCH_LOG_OUTPUT("Available menu drivers are:\n");
               for (d = 0; menu_driver_find_handle(d); d++)
                  RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d));
               RARCH_WARN("Going to default to first menu driver...\n");

               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(0);

               if (!menu_driver_ctx)
               {
                  retro_fail(1, "find_menu_driver()");
                  return false;
               }
            }
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_INIT:
         {
            const char *path = (const char*)data;
            if (string_is_empty(path))
               return false;
            menu_driver_playlist  = content_playlist_init(path,
                  COLLECTION_SIZE);
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_GET:
         {
            content_playlist_t **playlist = (content_playlist_t**)data;
            if (!playlist)
               return false;
            *playlist = menu_driver_playlist;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_GET:
         {
            struct retro_system_info **system = 
               (struct retro_system_info**)data;
            if (!system)
               return false;
            *system = &menu_driver_system;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_DEINIT:
#ifdef HAVE_DYNAMIC
         libretro_free_system_info(&menu_driver_system);
         memset(&menu_driver_system, 0, sizeof(struct retro_system_info));
#endif
         break;
      case RARCH_MENU_CTL_RENDER_MESSAGEBOX:
         if (menu_driver_ctx->render_messagebox)
            menu_driver_ctx->render_messagebox(menu_userdata,
                  menu_driver_data->menu_state.msg);
         break;
      case RARCH_MENU_CTL_BLIT_RENDER:
         if (menu_driver_ctx->render)
            menu_driver_ctx->render(menu_userdata);
         break;
      case RARCH_MENU_CTL_RENDER:
         if (!menu_driver_data)
            return false;

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER) 
               != BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX))
            BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER);

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER))
            menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL);

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) 
               && !string_is_empty(menu_driver_data->menu_state.msg))
         {
            menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL);

            if (ui_companion_is_on_foreground())
            {
               const ui_companion_driver_t *ui = ui_companion_get_ptr();
               if (ui->render_messagebox)
                  ui->render_messagebox(menu_driver_data->menu_state.msg);
            }
         }

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_BLIT))
         {
            menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL);
            menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL);
         }

         if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) 
               && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL);

         menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL);

         menu_driver_data->state               = 0;
         break;
      case RARCH_MENU_CTL_SHADER_DEINIT:
#ifdef HAVE_SHADER_MANAGER
         if (menu_driver_shader)
            free(menu_driver_shader);
         menu_driver_shader = NULL;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_INIT:
#ifdef HAVE_SHADER_MANAGER
         menu_driver_shader = (struct video_shader*)
            calloc(1, sizeof(struct video_shader));
         if (!menu_driver_shader)
            return false;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_GET:
         {
            struct video_shader **shader = (struct video_shader**)data;
            if (!shader)
               return false;
            *shader = menu_driver_shader;
         }
         break;
      case RARCH_MENU_CTL_FRAME:
         if (!menu_driver_alive)
            return false;
         if (menu_driver_ctx->frame)
            menu_driver_ctx->frame(menu_userdata);
         break;
      case RARCH_MENU_CTL_SET_PREVENT_POPULATE:
         menu_driver_prevent_populate = true;
         break;
      case RARCH_MENU_CTL_UNSET_PREVENT_POPULATE:
         menu_driver_prevent_populate = false;
         break;
      case RARCH_MENU_CTL_IS_PREVENT_POPULATE:
         return menu_driver_prevent_populate;
      case RARCH_MENU_CTL_SET_TOGGLE:
         menu_driver_toggle(true);
         break;
      case RARCH_MENU_CTL_UNSET_TOGGLE:
         menu_driver_toggle(false);
         break;
      case RARCH_MENU_CTL_SET_ALIVE:
         menu_driver_alive = true;
         break;
      case RARCH_MENU_CTL_UNSET_ALIVE:
         menu_driver_alive = false;
         break;
      case RARCH_MENU_CTL_IS_ALIVE:
         return menu_driver_alive;
      case RARCH_MENU_CTL_SET_OWN_DRIVER:
         menu_driver_data_own = true;
         break;
      case RARCH_MENU_CTL_UNSET_OWN_DRIVER:
         if (!content_ctl(CONTENT_CTL_IS_INITED, NULL))
            return false;
         menu_driver_data_own = false;
         break;
      case RARCH_MENU_CTL_SET_TEXTURE:
         if (menu_driver_ctx->set_texture)
            menu_driver_ctx->set_texture();
         break;
      case RARCH_MENU_CTL_IS_SET_TEXTURE:
         if (!menu_driver_ctx)
            return false;
         return menu_driver_ctx->set_texture;
      case RARCH_MENU_CTL_OWNS_DRIVER:
         return menu_driver_data_own;
      case RARCH_MENU_CTL_DEINIT:
         menu_driver_ctl(RARCH_MENU_CTL_CONTEXT_DESTROY, NULL);
         if (menu_driver_ctl(RARCH_MENU_CTL_OWNS_DRIVER, NULL))
            return true;
         if (menu_driver_data)
         {
            menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL);
            menu_shader_free(menu_driver_data);
            menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_DEINIT, NULL);

            if (menu_driver_ctx && menu_driver_ctx->free)
               menu_driver_ctx->free(menu_userdata);

            if (menu_userdata)
               free(menu_userdata);
            menu_userdata = NULL;

            menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL);
            menu_display_ctl(MENU_DISPLAY_CTL_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL);

            event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL);

            core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL);
            core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_FREE, NULL);

            free(menu_driver_data);
         }
         menu_driver_data = NULL;
         break;
      case RARCH_MENU_CTL_INIT:
         if (menu_driver_data)
            return true;

         menu_driver_data = (menu_handle_t*)
            menu_driver_ctx->init(&menu_userdata);

         if (!menu_driver_data || !menu_init(menu_driver_data))
         {
            retro_fail(1, "init_menu()");
            return false;
         }

         strlcpy(settings->menu.driver, menu_driver_ctx->ident,
               sizeof(settings->menu.driver));

         if (menu_driver_ctx->lists_init)
         {
            if (!menu_driver_ctx->lists_init(menu_driver_data))
            {
               retro_fail(1, "init_menu()");
               return false;
            }
         }
         break;
      case RARCH_MENU_CTL_LOAD_NO_CONTENT_GET:
         {
            bool **ptr = (bool**)data;
            if (!ptr)
               return false;
            *ptr = (bool*)&menu_driver_load_no_content;
         }
         break;
      case RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT:
         return menu_driver_load_no_content;
      case RARCH_MENU_CTL_SET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = true;
         break;
      case RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = false;
         break;
      case RARCH_MENU_CTL_NAVIGATION_INCREMENT:
         if (menu_driver_ctx->navigation_increment)
            menu_driver_ctx->navigation_increment(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_DECREMENT:
         if (menu_driver_ctx->navigation_decrement)
            menu_driver_ctx->navigation_decrement(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET:
         {
            bool *scroll = (bool*)data;

            if (!scroll)
               return false;
            if (menu_driver_ctx->navigation_set)
               menu_driver_ctx->navigation_set(menu_userdata, *scroll);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET_LAST:
         if (menu_driver_ctx->navigation_set_last)
            menu_driver_ctx->navigation_set_last(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_ASCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_ascend_alphabet)
               menu_driver_ctx->navigation_ascend_alphabet(
                     menu_userdata, ptr_out);
         }
      case RARCH_MENU_CTL_NAVIGATION_DESCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_descend_alphabet)
               menu_driver_ctx->navigation_descend_alphabet(
                     menu_userdata, ptr_out);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_CLEAR:
         {
            bool *pending_push = (bool*)data;

            if (!pending_push)
               return false;
            if (menu_driver_ctx->navigation_clear)
               menu_driver_ctx->navigation_clear(
                     menu_userdata, pending_push);
         }
         break;
      case RARCH_MENU_CTL_POPULATE_ENTRIES:
         {
            menu_displaylist_info_t *info = (menu_displaylist_info_t*)data;

            if (!info)
               return false;
            if (menu_driver_ctx->populate_entries)
               menu_driver_ctx->populate_entries(
                     menu_userdata, info->path,
                     info->label, info->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_ENTRY:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_entry)
            {
               list->entry = NULL;
               return false;
            }
            list->entry = menu_driver_ctx->list_get_entry(menu_userdata,
                  list->type, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SIZE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->list_get_size)
            {
               list->size = 0;
               return false;
            }
            list->size = menu_driver_ctx->list_get_size(menu_userdata, list->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SELECTION:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_selection)
            {
               list->selection = 0;
               return false;
            }
            list->selection = menu_driver_ctx->list_get_selection(menu_userdata);
         }
         break;
      case RARCH_MENU_CTL_LIST_FREE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (menu_driver_ctx)
            {
               if (menu_driver_ctx->list_free)
                  menu_driver_ctx->list_free(list->list, list->idx, list->list_size);
            }

            if (list->list)
            {
               file_list_free_userdata  (list->list, list->idx);
               file_list_free_actiondata(list->list, list->idx);
            }
         }
         break;
      case RARCH_MENU_CTL_LIST_PUSH:
         {
            menu_ctx_displaylist_t *disp_list = (menu_ctx_displaylist_t*)data;

            if (menu_driver_ctx->list_push)
               if (menu_driver_ctx->list_push(menu_driver_data,
                        menu_userdata, disp_list->info, disp_list->type) == 0)
                  return true;
         }
         return false;
      case RARCH_MENU_CTL_LIST_CLEAR:
         {
            file_list_t *list = (file_list_t*)data;
            if (!list)
               return false;
            if (menu_driver_ctx->list_clear)
               menu_driver_ctx->list_clear(list);
         }
         break;
      case RARCH_MENU_CTL_TOGGLE:
         {
            bool *latch = (bool*)data;
            if (!latch)
               return false;

            if (menu_driver_ctx->toggle)
               menu_driver_ctx->toggle(menu_userdata, *latch);
         }
         break;
      case RARCH_MENU_CTL_REFRESH:
         {
#if 0
            bool refresh = false;
            menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
#endif
         }
         break;
      case RARCH_MENU_CTL_CONTEXT_RESET:
         if (!menu_driver_ctx || !menu_driver_ctx->context_reset)
            return false;
         menu_driver_ctx->context_reset(menu_userdata);
         break;
      case RARCH_MENU_CTL_CONTEXT_DESTROY:
         if (!menu_driver_ctx || !menu_driver_ctx->context_destroy)
            return false;
         menu_driver_ctx->context_destroy(menu_userdata);
         break;
      case RARCH_MENU_CTL_SHADER_MANAGER_INIT:
         menu_shader_manager_init(menu_driver_data);
         break;
      case RARCH_MENU_CTL_LIST_SET_SELECTION:
         {
            file_list_t *list = (file_list_t*)data;

            if (!list)
               return false;

            if (!menu_driver_ctx || !menu_driver_ctx->list_set_selection)
               return false;

            menu_driver_ctx->list_set_selection(menu_userdata, list);
         }
         break;
      case RARCH_MENU_CTL_LIST_CACHE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_cache)
               return false;
            menu_driver_ctx->list_cache(menu_userdata,
                  list->type, list->action);
         }
         break;
      case RARCH_MENU_CTL_LIST_INSERT:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_insert)
               return false;
            menu_driver_ctx->list_insert(menu_userdata,
                  list->list, list->path, list->label, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LOAD_IMAGE:
         {
            menu_ctx_load_image_t *load_image_info = 
               (menu_ctx_load_image_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->load_image)
               return false;
            return menu_driver_ctx->load_image(menu_userdata,
                  load_image_info->data, load_image_info->type);
         }
      case RARCH_MENU_CTL_ITERATE:
         {
            bool retcode = false;
            menu_ctx_iterate_t *iterate = (menu_ctx_iterate_t*)data;

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL))
            {
               bool msg_force               = true;

               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL);
               menu_entries_flush_stack(NULL, MENU_SETTINGS);
               menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force);

               generic_action_ok_displaylist_push("",
                     "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS);

               if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
               {
                  menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
                  return false;
               }

               return true;
            }

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
               return false;
            }
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL);
               if (!event_cmd_ctl(EVENT_CMD_QUIT, NULL))
                  return false;
               return true;
            }
            if (!menu_driver_ctx || !menu_driver_ctx->iterate)
               return false;
             
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_ACTION, &retcode))
            {
                iterate->action = pending_iter.action;
                pending_iter.action = MENU_ACTION_NOOP;
            }
            if (menu_driver_ctx->iterate(menu_driver_data,
                     menu_userdata, iterate->action) == -1)
               return false;
         }
         break;
      case RARCH_MENU_CTL_ENVIRONMENT:
         {
            menu_ctx_environment_t *menu_environ = 
               (menu_ctx_environment_t*)data;

            if (menu_driver_ctx->environ_cb)
            {
               if (menu_driver_ctx->environ_cb(menu_environ->type,
                        menu_environ->data, menu_userdata) == 0)
                  return true;
            }
         }
         return false;
      case RARCH_MENU_CTL_POINTER_TAP:
         {
            menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap)
            {
               point->retcode = 0;
               return false;
            }
            point->retcode = menu_driver_ctx->pointer_tap(menu_userdata,
                  point->x, point->y, point->ptr,
                  point->cbs, point->entry, point->action);
         }
         break;
      case RARCH_MENU_CTL_BIND_INIT:
         {
            menu_ctx_bind_t *bind = (menu_ctx_bind_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->bind_init)
            {
               bind->retcode = 0;
               return false;
            }
            bind->retcode = menu_driver_ctx->bind_init(
                  bind->cbs,
                  bind->path,
                  bind->label,
                  bind->type,
                  bind->idx,
                  bind->elem0,
                  bind->elem1,
                  bind->label_hash,
                  bind->menu_label_hash);
         }
         break;
      default:
      case RARCH_MENU_CTL_NONE:
         break;
   }

   return true;
}