コード例 #1
0
ファイル: video_driver.c プロジェクト: lordixi/RetroArch
static void init_video_input(const input_driver_t *tmp)
{
   driver_t *driver = driver_get_ptr();

   /* 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. */
      rarch_fail(1, "init_video_input()");
   }

   driver->input_data = input_driver_init();

   if (driver->input_data)
      return;

   RARCH_ERR("Cannot initialize input driver. Exiting ...\n");
   rarch_fail(1, "init_video_input()");
}
コード例 #2
0
ファイル: menu_driver.c プロジェクト: blakekohler/RetroArch
void init_menu(void)
{
   const char *video_driver;
   driver_t *driver     = driver_get_ptr();

   if (driver->menu)
      return;

   find_menu_driver();

   video_driver = menu_video_get_ident();

   switch (driver->menu_ctx->type)
   {
      case MENU_VIDEO_DRIVER_GENERIC:
         break;
      case MENU_VIDEO_DRIVER_DIRECT3D:
         if (video_driver && (strcmp(video_driver, "d3d") != 0))
            init_menu_fallback();
         break;
      case MENU_VIDEO_DRIVER_OPENGL:
         if (video_driver && (strcmp(video_driver, "gl") != 0))
            init_menu_fallback();
         break;
   }

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

   if (driver->menu_ctx->lists_init)
      if (!driver->menu_ctx->lists_init(driver->menu))
         rarch_fail(1, "init_menu()");
}
コード例 #3
0
ファイル: dynamic.c プロジェクト: CatalystG/RetroArch
void init_libretro_sym(bool dummy)
{
   // Guarantee that we can do "dirty" casting.
   // Every OS that this program supports should pass this ...
   rarch_assert(sizeof(void*) == sizeof(void (*)(void)));

   if (!dummy)
   {
#ifdef HAVE_DYNAMIC
      // Try to verify that -lretro was not linked in from other modules
      // since loading it dynamically and with -l will fail hard.
      function_t sym = dylib_proc(NULL, "retro_init");
      if (sym)
      {
         RARCH_ERR("Serious problem. RetroArch wants to load libretro 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");
         rarch_fail(1, "init_libretro_sym()");
      }

      if (!*g_settings.libretro)
      {
         RARCH_ERR("RetroArch is built for dynamic libretro, but libretro_path is not set. Cannot continue.\n");
         rarch_fail(1, "init_libretro_sym()");
      }
#endif
   }

   load_symbols(dummy);

   pretro_set_environment(environment_cb);
}
コード例 #4
0
ファイル: driver.c プロジェクト: dturner/RetroArch
static void find_video_driver(void)
{
#if defined(HAVE_OPENGL) && defined(HAVE_FBO)
   if (g_extern.system.hw_render_callback.context_type)
   {
      RARCH_LOG("Using HW render, OpenGL driver forced.\n");
      driver.video = &video_gl;
      return;
   }
#endif

   int i = find_video_driver_index(g_settings.video.driver);
   if (i >= 0)
      driver.video = video_drivers[i];
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any video driver named \"%s\"\n", g_settings.video.driver);
      RARCH_LOG_OUTPUT("Available video drivers are:\n");
      for (d = 0; video_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", video_drivers[d]->ident);
      RARCH_WARN("Going to default to first video driver...\n");

      driver.video = video_drivers[0];

      if (!driver.video)
         rarch_fail(1, "find_video_driver()");
   }
}
コード例 #5
0
ファイル: audio_driver.c プロジェクト: SAKUJ0/RetroArch
void find_audio_driver(void)
{
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();

   int i = find_driver_index("audio_driver", settings->audio.driver);

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

      driver->audio = (const audio_driver_t*)audio_driver_find_handle(0);

      if (!driver->audio)
         rarch_fail(1, "find_audio_driver()");
   }
}
コード例 #6
0
ファイル: menu_driver.c プロジェクト: Miinky-Games/RetroArch
void init_menu(void)
{
   driver_t *driver = driver_get_ptr();
   if (driver->menu)
      return;

   find_menu_driver();
   if (!(driver->menu = (menu_handle_t*)menu_init(driver->menu_ctx)))
   {
      RARCH_ERR("Cannot initialize menu.\n");
      rarch_fail(1, "init_menu()");
   }

   if (!(menu_entries_init(driver->menu)))
   {
      RARCH_ERR("Cannot initialize menu lists.\n");
      rarch_fail(1, "init_menu()");
   }
}
コード例 #7
0
ファイル: driver.c プロジェクト: dturner/RetroArch
static void init_menu(void)
{
   if (driver.menu)
      return;

   find_menu_driver();
   if (!(driver.menu = (menu_handle_t*)menu_init(driver.menu_ctx)))
   {
      RARCH_ERR("Cannot initialize menu.\n");
      rarch_fail(1, "init_menu()");
   }
}
コード例 #8
0
ファイル: driver.c プロジェクト: isdom/RetroArch
static void find_location_driver(void)
{
   int i = find_location_driver_index(g_settings.location.driver);
   if (i >= 0)
      driver.location = location_drivers[i];
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any location driver named \"%s\"\n", g_settings.location.driver);
      RARCH_LOG_OUTPUT("Available location drivers are:\n");
      for (d = 0; location_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", location_drivers[d]->ident);

      rarch_fail(1, "find_location_driver()");
   }
}
コード例 #9
0
ファイル: driver.c プロジェクト: isdom/RetroArch
static void find_input_driver(void)
{
   int i = find_input_driver_index(g_settings.input.driver);
   if (i >= 0)
      driver.input = input_drivers[i];
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any input driver named \"%s\"\n", g_settings.input.driver);
      RARCH_LOG_OUTPUT("Available input drivers are:\n");
      for (d = 0; input_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", input_drivers[d]->ident);

      rarch_fail(1, "find_input_driver()");
   }
}
コード例 #10
0
ファイル: dynamic.c プロジェクト: mmodahl/RetroArch
static void load_symbols(void)
{
#ifdef HAVE_DYNAMIC
   RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
   lib_handle = dylib_load(g_settings.libretro);
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
      rarch_fail(1, "load_dynamic()");
   }
#endif

   SYM(retro_init);
   SYM(retro_deinit);

   SYM(retro_api_version);
   SYM(retro_get_system_info);
   SYM(retro_get_system_av_info);

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

   SYM(retro_set_controller_port_device);

   SYM(retro_reset);
   SYM(retro_run);

   SYM(retro_serialize_size);
   SYM(retro_serialize);
   SYM(retro_unserialize);

   SYM(retro_cheat_reset);
   SYM(retro_cheat_set);

   SYM(retro_load_game);
   SYM(retro_load_game_special);

   SYM(retro_unload_game);
   SYM(retro_get_region);
   SYM(retro_get_memory_data);
   SYM(retro_get_memory_size);
}
コード例 #11
0
ファイル: command_event.c プロジェクト: Gruncher/RetroArch
static void event_init_movie(void)
{
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (global->bsv.movie_start_playback)
   {
      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_PLAYBACK)))
      {
         RARCH_ERR("%s: \"%s\".\n",
               msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE),
               global->bsv.movie_start_path);
         rarch_fail(1, "event_init_movie()");
      }

      global->bsv.movie_playback = true;
      rarch_main_msg_queue_push_new(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 (global->bsv.movie_start_recording)
   {
      char msg[PATH_MAX_LENGTH] = {0};
      snprintf(msg, sizeof(msg),
            "%s \"%s\".",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            global->bsv.movie_start_path);

      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_RECORD)))
      {
         rarch_main_msg_queue_push_new(MSG_FAILED_TO_START_MOVIE_RECORD, 1, 180, true);
         RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD));
         return;
      }

      rarch_main_msg_queue_push(msg, 1, 180, true);
      RARCH_LOG("%s \"%s\".\n",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            global->bsv.movie_start_path);
      settings->rewind_granularity = 1;
   }
}
コード例 #12
0
ファイル: video_driver.c プロジェクト: lordixi/RetroArch
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)
         rarch_fail(1, "find_video_driver()");
   }
}
コード例 #13
0
ファイル: driver.c プロジェクト: dturner/RetroArch
void find_menu_driver(void)
{
   int i = find_menu_driver_index(g_settings.menu.driver);
   if (i >= 0)
      driver.menu_ctx = menu_ctx_drivers[i];
   else
   {
      unsigned d;
      RARCH_WARN("Couldn't find any menu driver named \"%s\"\n", g_settings.menu.driver);
      RARCH_LOG_OUTPUT("Available menu drivers are:\n");
      for (d = 0; menu_ctx_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", menu_ctx_drivers[d]->ident);
      RARCH_WARN("Going to default to first menu driver...\n");

      driver.menu_ctx = menu_ctx_drivers[0];

      if (!driver.menu_ctx)
         rarch_fail(1, "find_menu_driver()");
   }
}
コード例 #14
0
ファイル: driver.c プロジェクト: dturner/RetroArch
static void find_audio_driver(void)
{
   int i = find_audio_driver_index(g_settings.audio.driver);
   if (i >= 0)
      driver.audio = audio_drivers[i];
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any audio driver named \"%s\"\n", g_settings.audio.driver);
      RARCH_LOG_OUTPUT("Available audio drivers are:\n");
      for (d = 0; audio_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", audio_drivers[d]->ident);
      RARCH_WARN("Going to default to first audio driver...\n");

      driver.audio = audio_drivers[0];

      if (!driver.audio)
         rarch_fail(1, "find_audio_driver()");
   }
}
コード例 #15
0
ファイル: image_context.c プロジェクト: Rizora/RetroArch
void find_image_driver(void)
{
   int i;
   if (driver.image)
      return;

   i = find_image_driver_index(g_settings.image.driver);
   if (i >= 0)
      driver.image = image_ctx_drivers[i];
   else
   {
      unsigned d;
      RARCH_ERR("Couldn't find any image driver named \"%s\"\n", g_settings.image.driver);
      RARCH_LOG_OUTPUT("Available image drivers are:\n");
      for (d = 0; image_ctx_drivers[d]; d++)
         RARCH_LOG_OUTPUT("\t%s\n", image_ctx_drivers[d]->ident);

      rarch_fail(1, "find_image_driver()");
   }
}
コード例 #16
0
ファイル: command_event.c プロジェクト: hbfelizzola/RetroArch
static void event_init_movie(void)
{
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (global->bsv.movie_start_playback)
   {
      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_PLAYBACK)))
      {
         RARCH_ERR("Failed to load movie file: \"%s\".\n",
               global->bsv.movie_start_path);
         rarch_fail(1, "event_init_movie()");
      }

      global->bsv.movie_playback = true;
      rarch_main_msg_queue_push("Starting movie playback.", 2, 180, false);
      RARCH_LOG("Starting movie playback.\n");
      settings->rewind_granularity = 1;
   }
   else if (global->bsv.movie_start_recording)
   {
      char msg[PATH_MAX_LENGTH] = {0};
      snprintf(msg, sizeof(msg), "Starting movie record to \"%s\".",
            global->bsv.movie_start_path);

      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_RECORD)))
      {
         rarch_main_msg_queue_push("Failed to start movie record.", 1, 180, true);
         RARCH_ERR("Failed to start movie record.\n");
         return;
      }

      rarch_main_msg_queue_push(msg, 1, 180, true);
      RARCH_LOG("Starting movie record to \"%s\".\n",
            global->bsv.movie_start_path);
      settings->rewind_granularity = 1;
   }
}
コード例 #17
0
ファイル: settings.c プロジェクト: Jalle19/RetroArch
static void parse_config_file(void)
{
   bool ret;
   if (*g_extern.config_path)
   {
      RARCH_LOG("Loading config from: %s.\n", g_extern.config_path);
      ret = config_load_file(g_extern.config_path);
   }
   else
   {
      RARCH_LOG("Loading default config.\n");
      ret = config_load_file(NULL);
   }

   if (!ret)
   {
      RARCH_ERR("Couldn't find config at path: \"%s\"\n", g_extern.config_path);
#ifndef RARCH_CONSOLE
      rarch_fail(1, "parse_config_file()");
#endif
   }
}
コード例 #18
0
ファイル: menu_driver.c プロジェクト: Miinky-Games/RetroArch
void find_menu_driver(void)
{
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();

   int i = find_driver_index("menu_driver", settings->menu.driver);
   if (i >= 0)
      driver->menu_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");

      driver->menu_ctx = (const menu_ctx_driver_t*)menu_driver_find_handle(0);

      if (!driver->menu_ctx)
         rarch_fail(1, "find_menu_driver()");
   }
}
コード例 #19
0
ファイル: video_driver.c プロジェクト: lordixi/RetroArch
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();
   global_t *global                 = global_get_ptr();
   settings_t *settings             = config_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;
   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");
      rarch_fail(1, "init_video()");
   }

   video.width        = width;
   video.height       = height;
   video.fullscreen   = settings->video.fullscreen;
   video.vsync        = settings->video.vsync && !global->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");
         rarch_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");
      rarch_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 + global->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
}
コード例 #20
0
ファイル: retroarch.c プロジェクト: PCGeekBrain/RetroArch
/**
 * parse_input:
 * @argc                 : Count of (commandline) arguments.
 * @argv                 : (Commandline) arguments.
 *
 * Parses (commandline) arguments passed to RetroArch.
 *
 **/
static void parse_input(int argc, char *argv[])
{
   runloop_t *runloop = rarch_main_get_ptr();
   global_t  *global  = global_get_ptr();

   global->libretro_no_content           = false;
   global->libretro_dummy                = false;
   global->has_set_save_path             = false;
   global->has_set_state_path            = false;
   global->has_set_libretro              = false;
   global->has_set_libretro_directory    = false;
   global->has_set_verbosity             = false;

   global->has_set_netplay_mode          = false;
   global->has_set_username              = false;
   global->has_set_netplay_ip_address    = false;
   global->has_set_netplay_delay_frames  = false;
   global->has_set_netplay_ip_port       = false;

   global->has_set_ups_pref              = false;
   global->has_set_bps_pref              = false;
   global->has_set_ips_pref              = false;

   global->ups_pref                      = false;
   global->bps_pref                      = false;
   global->ips_pref                      = false;
   *global->ups_name                     = '\0';
   *global->bps_name                     = '\0';
   *global->ips_name                     = '\0';
   *global->subsystem                    = '\0';

   global->overrides_active              = false;

   if (argc < 2)
   {
      global->libretro_dummy             = true;
      return;
   }

   /* Make sure we can call parse_input several times ... */
   optind = 0;

   int val = 0;

   const struct option opts[] = {
#ifdef HAVE_DYNAMIC
      { "libretro", 1, NULL, 'L' },
#endif
      { "menu", 0, &val, 'M' },
      { "help", 0, NULL, 'h' },
      { "save", 1, NULL, 's' },
      { "fullscreen", 0, NULL, 'f' },
      { "record", 1, NULL, 'r' },
      { "recordconfig", 1, &val, 'R' },
      { "size", 1, &val, 's' },
      { "verbose", 0, NULL, 'v' },
      { "config", 1, NULL, 'c' },
      { "appendconfig", 1, &val, 'C' },
      { "nodevice", 1, NULL, 'N' },
      { "dualanalog", 1, NULL, 'A' },
      { "device", 1, NULL, 'd' },
      { "savestate", 1, NULL, 'S' },
      { "bsvplay", 1, NULL, 'P' },
      { "bsvrecord", 1, NULL, 'R' },
      { "sram-mode", 1, NULL, 'M' },
#ifdef HAVE_NETPLAY
      { "host", 0, NULL, 'H' },
      { "connect", 1, NULL, 'C' },
      { "frames", 1, NULL, 'F' },
      { "port", 1, &val, 'p' },
      { "spectate", 0, &val, 'S' },
#endif
      { "nick", 1, &val, 'N' },
#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
      { "command", 1, &val, 'c' },
#endif
      { "ups", 1, NULL, 'U' },
      { "bps", 1, &val, 'B' },
      { "ips", 1, &val, 'I' },
      { "no-patch", 0, &val, 'n' },
      { "detach", 0, NULL, 'D' },
      { "features", 0, &val, 'f' },
      { "subsystem", 1, NULL, 'Z' },
      { "max-frames", 1, NULL, 'm' },
      { "eof-exit", 0, &val, 'e' },
      { NULL, 0, NULL, 0 }
   };

#define FFMPEG_RECORD_ARG "r:"

#ifdef HAVE_DYNAMIC
#define DYNAMIC_ARG "L:"
#else
#define DYNAMIC_ARG
#endif

#ifdef HAVE_NETPLAY
#define NETPLAY_ARG "HC:F:"
#else
#define NETPLAY_ARG
#endif


#define BSV_MOVIE_ARG "P:R:M:"

   const char *optstring = "hs:fvS:A:c:U:DN:d:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG;
   settings_t *settings = config_get_ptr();

   for (;;)
   {
      int port;
      val   = 0;
      int c = getopt_long(argc, argv, optstring, opts, NULL);

      if (c == -1)
         break;

      switch (c)
      {
         case 'h':
            print_help();
            exit(0);

         case 'Z':
            strlcpy(global->subsystem, optarg, sizeof(global->subsystem));
            break;

         case 'd':
         {
            unsigned id = 0;
            struct string_list *list = string_split(optarg, ":");

            port = 0;

            if (list && list->size == 2)
            {
               port = strtol(list->elems[0].data, NULL, 0);
               id = strtoul(list->elems[1].data, NULL, 0);
            }
            string_list_free(list);

            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Connect device to a valid port.\n");
               print_help();
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = id;
            global->has_set_libretro_device[port - 1] = true;
            break;
         }

         case 'A':
            port = strtol(optarg, NULL, 0);
            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Connect dualanalog to a valid port.\n");
               print_help();
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = RETRO_DEVICE_ANALOG;
            global->has_set_libretro_device[port - 1] = true;
            break;

         case 's':
            strlcpy(global->savefile_name, optarg,
                  sizeof(global->savefile_name));
            global->has_set_save_path = true;
            break;

         case 'f':
            global->force_fullscreen = true;
            break;

         case 'S':
            strlcpy(global->savestate_name, optarg,
                  sizeof(global->savestate_name));
            global->has_set_state_path = true;
            break;

         case 'v':
            global->verbosity = true;
            global->has_set_verbosity = true;
            break;

         case 'N':
            port = strtol(optarg, NULL, 0);
            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Disconnect device from a valid port.\n");
               print_help();
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = RETRO_DEVICE_NONE;
            global->has_set_libretro_device[port - 1] = true;
            break;

         case 'c':
            strlcpy(global->config_path, optarg,
                  sizeof(global->config_path));
            break;

         case 'r':
            strlcpy(global->record.path, optarg,
                  sizeof(global->record.path));
            global->record.enable = true;
            break;

#ifdef HAVE_DYNAMIC
         case 'L':
            if (path_is_directory(optarg))
            {
               *settings->libretro = '\0';
               strlcpy(settings->libretro_directory, optarg,
                     sizeof(settings->libretro_directory));
               global->has_set_libretro = true;
               global->has_set_libretro_directory = true;
               RARCH_WARN("Using old --libretro behavior. Setting libretro_directory to \"%s\" instead.\n", optarg);
            }
            else
            {
               strlcpy(settings->libretro, optarg,
                     sizeof(settings->libretro));
               global->has_set_libretro = true;
            }
            break;
#endif
         case 'P':
         case 'R':
            strlcpy(global->bsv.movie_start_path, optarg,
                  sizeof(global->bsv.movie_start_path));
            global->bsv.movie_start_playback  = (c == 'P');
            global->bsv.movie_start_recording = (c == 'R');
            break;

         case 'M':
            if (strcmp(optarg, "noload-nosave") == 0)
            {
               global->sram_load_disable = true;
               global->sram_save_disable = true;
            }
            else if (strcmp(optarg, "noload-save") == 0)
               global->sram_load_disable = true;
            else if (strcmp(optarg, "load-nosave") == 0)
               global->sram_save_disable = true;
            else if (strcmp(optarg, "load-save") != 0)
            {
               RARCH_ERR("Invalid argument in --sram-mode.\n");
               print_help();
               rarch_fail(1, "parse_input()");
            }
            break;

#ifdef HAVE_NETPLAY
         case 'H':
            global->has_set_netplay_ip_address = true;
            global->netplay_enable = true;
            *global->netplay_server = '\0';
            break;

         case 'C':
            global->has_set_netplay_ip_address = true;
            global->netplay_enable = true;
            strlcpy(global->netplay_server, optarg,
                  sizeof(global->netplay_server));
            break;

         case 'F':
            global->netplay_sync_frames = strtol(optarg, NULL, 0);
            global->has_set_netplay_delay_frames = true;
            break;
#endif

         case 'U':
            strlcpy(global->ups_name, optarg,
                  sizeof(global->ups_name));
            global->ups_pref = true;
            global->has_set_ups_pref = true;
            break;

         case 'D':
#if defined(_WIN32) && !defined(_XBOX)
            FreeConsole();
#endif
            break;

         case 'm':
            runloop->frames.video.max = strtoul(optarg, NULL, 10);
            break;

         case 0:
            switch (val)
            {
               case 'M':
                  global->libretro_dummy = true;
                  break;

#ifdef HAVE_NETPLAY
               case 'p':
                  global->has_set_netplay_ip_port = true;
                  global->netplay_port = strtoul(optarg, NULL, 0);
                  break;

               case 'S':
                  global->has_set_netplay_mode = true;
                  global->netplay_is_spectate = true;
                  break;

#endif
               case 'N':
                  global->has_set_username = true;
                  strlcpy(settings->username, optarg,
                        sizeof(settings->username));
                  break;

#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
               case 'c':
                  if (network_cmd_send(optarg))
                     exit(0);
                  else
                     rarch_fail(1, "network_cmd_send()");
                  break;
#endif

               case 'C':
                  strlcpy(global->append_config_path, optarg,
                        sizeof(global->append_config_path));
                  break;

               case 'B':
                  strlcpy(global->bps_name, optarg,
                        sizeof(global->bps_name));
                  global->bps_pref = true;
                  global->has_set_bps_pref = true;
                  break;

               case 'I':
                  strlcpy(global->ips_name, optarg,
                        sizeof(global->ips_name));
                  global->ips_pref = true;
                  global->has_set_ips_pref = true;
                  break;

               case 'n':
                  global->block_patch = true;
                  break;

               case 's':
               {
                  if (sscanf(optarg, "%ux%u", &global->record.width,
                           &global->record.height) != 2)
                  {
                     RARCH_ERR("Wrong format for --size.\n");
                     print_help();
                     rarch_fail(1, "parse_input()");
                  }
                  break;
               }

               case 'R':
                  strlcpy(global->record.config, optarg,
                        sizeof(global->record.config));
                  break;
               case 'f':
                  print_features();
                  exit(0);

               case 'e':
                  global->bsv.eof_exit = true;
                  break;

               default:
                  break;
            }
            break;

         case '?':
            print_help();
            rarch_fail(1, "parse_input()");

         default:
            RARCH_ERR("Error parsing arguments.\n");
            rarch_fail(1, "parse_input()");
      }
   }

   if (global->libretro_dummy)
   {
      if (optind < argc)
      {
         RARCH_ERR("--menu was used, but content file was passed as well.\n");
         rarch_fail(1, "parse_input()");
      }
   }
   else if (!*global->subsystem && optind < argc)
      rarch_set_paths(argv[optind]);
   else if (*global->subsystem && optind < argc)
      set_special_paths(argv + optind, argc - optind);
   else
      global->libretro_no_content = true;

   /* Copy SRM/state dirs used, so they can be reused on reentrancy. */
   if (global->has_set_save_path &&
         path_is_directory(global->savefile_name))
      strlcpy(global->savefile_dir, global->savefile_name,
            sizeof(global->savefile_dir));

   if (global->has_set_state_path &&
         path_is_directory(global->savestate_name))
      strlcpy(global->savestate_dir, global->savestate_name,
            sizeof(global->savestate_dir));
}
コード例 #21
0
ファイル: dynamic.c プロジェクト: barnhilltrckn/RetroArch-1
static void load_symbols(void)
{
#ifdef HAVE_DYNAMIC
   const char *libretro_path = g_settings.libretro;
   char libretro_core_buffer[PATH_MAX];

   if (path_is_directory(g_settings.libretro))
   {
      if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer),
               g_settings.libretro, g_extern.fullpath))
      {
         RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n");
         rarch_fail(1, "load_dynamic()");
      }

      libretro_path = libretro_core_buffer;
   }

   RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", libretro_path);
   lib_handle = dylib_load(libretro_path);
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open dynamic library: \"%s\"\n", libretro_path);
      rarch_fail(1, "load_dynamic()");
   }
#endif

   SYM(retro_init);
   SYM(retro_deinit);

   SYM(retro_api_version);
   SYM(retro_get_system_info);
   SYM(retro_get_system_av_info);

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

   SYM(retro_set_controller_port_device);

   SYM(retro_reset);
   SYM(retro_run);

   SYM(retro_serialize_size);
   SYM(retro_serialize);
   SYM(retro_unserialize);

   SYM(retro_cheat_reset);
   SYM(retro_cheat_set);

   SYM(retro_load_game);
   SYM(retro_load_game_special);

   SYM(retro_unload_game);
   SYM(retro_get_region);
   SYM(retro_get_memory_data);
   SYM(retro_get_memory_size);
}
コード例 #22
0
ファイル: menu_common.c プロジェクト: CatalystG/RetroArch
void menu_init(void)
{
   rgui = rgui_init();

   if (rgui == NULL)
   {
      RARCH_ERR("Could not initialize menu.\n");
      rarch_fail(1, "menu_init()");
   }

   rgui->trigger_state = 0;
   rgui->old_input_state = 0;
   rgui->do_held = false;
   rgui->frame_buf_show = true;
   rgui->current_pad = 0;

#ifdef HAVE_DYNAMIC
   if (path_is_directory(g_settings.libretro))
      strlcpy(rgui->libretro_dir, g_settings.libretro, sizeof(rgui->libretro_dir));
   else if (*g_settings.libretro)
   {
      fill_pathname_basedir(rgui->libretro_dir, g_settings.libretro, sizeof(rgui->libretro_dir));
      libretro_get_system_info(g_settings.libretro, &rgui->info, NULL);
   }
#else
   retro_get_system_info(&rgui->info);
#endif

#ifdef HAVE_FILEBROWSER
   if (!(strlen(g_settings.rgui_browser_directory) > 0))
      strlcpy(g_settings.rgui_browser_directory, default_paths.filebrowser_startup_dir,
            sizeof(g_settings.rgui_browser_directory));

   rgui->browser =  (filebrowser_t*)calloc(1, sizeof(*(rgui->browser)));

   if (rgui->browser == NULL)
   {
      RARCH_ERR("Could not initialize filebrowser.\n");
      rarch_fail(1, "menu_init()");
   }

   strlcpy(rgui->browser->current_dir.extensions, rgui->info.valid_extensions,
         sizeof(rgui->browser->current_dir.extensions));

   // Look for zips to extract as well.
   if (*rgui->info.valid_extensions)
   {
      strlcat(rgui->browser->current_dir.extensions, "|zip",
         sizeof(rgui->browser->current_dir.extensions));
   }

   strlcpy(rgui->browser->current_dir.root_dir, g_settings.rgui_browser_directory,
         sizeof(rgui->browser->current_dir.root_dir));

   filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_RESET);
#endif

#ifdef HAVE_SHADER_MANAGER
   shader_manager_init(rgui);
#endif

   if (*g_extern.config_path)
   {
      char history_path[PATH_MAX];
      if (*g_settings.game_history_path)
         strlcpy(history_path, g_settings.game_history_path, sizeof(history_path));
      else
      {
         fill_pathname_resolve_relative(history_path, g_extern.config_path,
               ".retroarch-game-history.txt", sizeof(history_path));
      }

      RARCH_LOG("[RGUI]: Opening history: %s.\n", history_path);
      rgui->history = rom_history_init(history_path, g_settings.game_history_size);
   }

   rgui->last_time = rarch_get_time_usec();
}
コード例 #23
0
ファイル: dynamic.c プロジェクト: HahPagan/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");
               rarch_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");
               rarch_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_fail(1, "load_dynamic()");
            }
#endif
         }

         SYM(retro_init);
         SYM(retro_deinit);

         SYM(retro_api_version);
         SYM(retro_get_system_info);
         SYM(retro_get_system_av_info);

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

         SYM(retro_set_controller_port_device);

         SYM(retro_reset);
         SYM(retro_run);

         SYM(retro_serialize_size);
         SYM(retro_serialize);
         SYM(retro_unserialize);

         SYM(retro_cheat_reset);
         SYM(retro_cheat_set);

         SYM(retro_load_game);
         SYM(retro_load_game_special);

         SYM(retro_unload_game);
         SYM(retro_get_region);
         SYM(retro_get_memory_data);
         SYM(retro_get_memory_size);
         break;
      case CORE_TYPE_DUMMY:
         SYM_DUMMY(retro_init);
         SYM_DUMMY(retro_deinit);

         SYM_DUMMY(retro_api_version);
         SYM_DUMMY(retro_get_system_info);
         SYM_DUMMY(retro_get_system_av_info);

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

         SYM_DUMMY(retro_set_controller_port_device);

         SYM_DUMMY(retro_reset);
         SYM_DUMMY(retro_run);

         SYM_DUMMY(retro_serialize_size);
         SYM_DUMMY(retro_serialize);
         SYM_DUMMY(retro_unserialize);

         SYM_DUMMY(retro_cheat_reset);
         SYM_DUMMY(retro_cheat_set);

         SYM_DUMMY(retro_load_game);
         SYM_DUMMY(retro_load_game_special);

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

         SYM_FFMPEG(retro_api_version);
         SYM_FFMPEG(retro_get_system_info);
         SYM_FFMPEG(retro_get_system_av_info);

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

         SYM_FFMPEG(retro_set_controller_port_device);

         SYM_FFMPEG(retro_reset);
         SYM_FFMPEG(retro_run);

         SYM_FFMPEG(retro_serialize_size);
         SYM_FFMPEG(retro_serialize);
         SYM_FFMPEG(retro_unserialize);

         SYM_FFMPEG(retro_cheat_reset);
         SYM_FFMPEG(retro_cheat_set);

         SYM_FFMPEG(retro_load_game);
         SYM_FFMPEG(retro_load_game_special);

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

         SYM_IMAGEVIEWER(retro_api_version);
         SYM_IMAGEVIEWER(retro_get_system_info);
         SYM_IMAGEVIEWER(retro_get_system_av_info);

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

         SYM_IMAGEVIEWER(retro_set_controller_port_device);

         SYM_IMAGEVIEWER(retro_reset);
         SYM_IMAGEVIEWER(retro_run);

         SYM_IMAGEVIEWER(retro_serialize_size);
         SYM_IMAGEVIEWER(retro_serialize);
         SYM_IMAGEVIEWER(retro_unserialize);

         SYM_IMAGEVIEWER(retro_cheat_reset);
         SYM_IMAGEVIEWER(retro_cheat_set);

         SYM_IMAGEVIEWER(retro_load_game);
         SYM_IMAGEVIEWER(retro_load_game_special);

         SYM_IMAGEVIEWER(retro_unload_game);
         SYM_IMAGEVIEWER(retro_get_region);
         SYM_IMAGEVIEWER(retro_get_memory_data);
         SYM_IMAGEVIEWER(retro_get_memory_size);
#endif
         break;
   }
}
コード例 #24
0
ファイル: driver.c プロジェクト: dturner/RetroArch
void init_video_input(void)
{
   unsigned max_dim, scale, width, height;
   const input_driver_t *tmp = NULL;
   const struct retro_game_geometry *geom = NULL;

   rarch_init_filter(g_extern.system.pix_fmt);

   init_shader_dir();

   geom = (const struct retro_game_geometry*)&g_extern.system.av_info.geometry;
   max_dim = max(geom->max_width, geom->max_height);
   scale = next_pow2(max_dim) / RARCH_SCALE_BASE;
   scale = max(scale, 1);

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

   // Update core-dependent aspect ratio values.
   gfx_set_square_pixel_viewport(geom->base_width, geom->base_height);
   gfx_set_core_viewport();
   gfx_set_config_viewport();

   // Update CUSTOM viewport.
   rarch_viewport_t *custom_vp = &g_extern.console.screen.viewports.custom_vp;
   if (g_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;
   }

   g_extern.system.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value;

   if (g_settings.video.fullscreen)
   {
      width = g_settings.video.fullscreen_x;
      height = g_settings.video.fullscreen_y;
   }
   else
   {
      if (g_settings.video.force_aspect)
      {
         // Do rounding here to simplify integer scale correctness.
         unsigned base_width = roundf(geom->base_height * g_extern.system.aspect_ratio);
         width = roundf(base_width * g_settings.video.scale);
         height = roundf(geom->base_height * g_settings.video.scale);
      }
      else
      {
         width = roundf(geom->base_width * g_settings.video.scale);
         height = roundf(geom->base_height * g_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");
      rarch_fail(1, "init_video_input()");
   }

   video_info_t video = {0};
   video.width = width;
   video.height = height;
   video.fullscreen = g_settings.video.fullscreen;
   video.vsync = g_settings.video.vsync && !g_extern.system.force_nonblock;
   video.force_aspect = g_settings.video.force_aspect;
#ifdef GEKKO
   video.viwidth = g_settings.video.viwidth;
#endif
   video.smooth = g_settings.video.smooth;
   video.input_scale = scale;
   video.rgb32 = g_extern.filter.filter ? g_extern.filter.out_rgb32 : (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888);

   tmp = (const input_driver_t*)driver.input;
   find_video_driver(); // Need to grab the "real" video driver interface on a reinit.
#ifdef HAVE_THREADS
   if (g_settings.video.threaded && !g_extern.system.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");
         rarch_fail(1, "init_video_input()");
      }
   }
   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");
      rarch_fail(1, "init_video_input()");
   }

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

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

   if (driver.video->set_rotation)
      driver.video->set_rotation(driver.video_data, (g_settings.video.rotation + g_extern.system.rotation) % 4);

#ifdef HAVE_X11
   if (driver.display_type == RARCH_DISPLAY_X11)
   {
      RARCH_LOG("Suspending screensaver (X11).\n");
      x11_suspend_screensaver(driver.video_window);
   }
#endif

   // Video driver didn't provide an input driver so we use configured one.
   if (!driver.input)
   {

      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)
      {
         driver.input_data = driver.input->init();
         if (!driver.input_data)
         {
            RARCH_ERR("Cannot initialize input driver. Exiting ...\n");
            rarch_fail(1, "init_video_input()");
         }
      }
      else
      {
         // 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.
         rarch_fail(1, "init_video_input()");
      }
   }

   rarch_main_command(RARCH_CMD_OVERLAY_DEINIT);
   rarch_main_command(RARCH_CMD_OVERLAY_INIT);

   g_extern.measure_data.frame_time_samples_count = 0;
}
コード例 #25
0
ファイル: driver.c プロジェクト: dturner/RetroArch
void init_audio(void)
{
   audio_convert_init_simd();

   // Resource leaks will follow if audio is initialized twice.
   if (driver.audio_data)
      return;

   // Accomodate rewind since at some point we might have two full buffers.
   size_t max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2;
   size_t outsamples_max = max_bufsamples * AUDIO_MAX_RATIO * g_settings.slowmotion_ratio;

   // Used for recording even if audio isn't enabled.
   rarch_assert(g_extern.audio_data.conv_outsamples = (int16_t*)malloc(outsamples_max * sizeof(int16_t)));

   g_extern.audio_data.block_chunk_size    = AUDIO_CHUNK_SIZE_BLOCKING;
   g_extern.audio_data.nonblock_chunk_size = AUDIO_CHUNK_SIZE_NONBLOCKING;
   g_extern.audio_data.chunk_size          = g_extern.audio_data.block_chunk_size;

   // Needs to be able to hold full content of a full max_bufsamples in addition to its own.
   rarch_assert(g_extern.audio_data.rewind_buf = (int16_t*)malloc(max_bufsamples * sizeof(int16_t)));
   g_extern.audio_data.rewind_size             = max_bufsamples;

   if (!g_settings.audio.enable)
   {
      g_extern.audio_active = false;
      return;
   }

   find_audio_driver();
#ifdef HAVE_THREADS
   if (g_extern.system.audio_callback.callback)
   {
      RARCH_LOG("Starting threaded audio driver ...\n");
      if (!rarch_threaded_audio_init(&driver.audio, &driver.audio_data,
               *g_settings.audio.device ? g_settings.audio.device : NULL,
               g_settings.audio.out_rate, g_settings.audio.latency,
               driver.audio))
      {
         RARCH_ERR("Cannot open threaded audio driver ... Exiting ...\n");
         rarch_fail(1, "init_audio()");
      }
   }
   else
#endif
   {
      driver.audio_data = driver.audio->init(*g_settings.audio.device ? g_settings.audio.device : NULL,
            g_settings.audio.out_rate, g_settings.audio.latency);
   }

   if (!driver.audio_data)
   {
      RARCH_ERR("Failed to initialize audio driver. Will continue without audio.\n");
      g_extern.audio_active = false;
   }

   g_extern.audio_data.use_float = false;
   if (g_extern.audio_active && driver.audio->use_float && driver.audio->use_float(driver.audio_data))
      g_extern.audio_data.use_float = true;

   if (!g_settings.audio.sync && g_extern.audio_active)
   {
      rarch_main_command(RARCH_CMD_AUDIO_SET_NONBLOCKING_STATE);
      g_extern.audio_data.chunk_size = g_extern.audio_data.nonblock_chunk_size;
   }

   // Should never happen.
   if (g_extern.audio_data.in_rate <= 0.0f)
   {
      RARCH_WARN("Input rate is invalid (%.3f Hz). Using output rate (%u Hz).\n", g_extern.audio_data.in_rate, g_settings.audio.out_rate);
      g_extern.audio_data.in_rate = g_settings.audio.out_rate;
   }

   g_extern.audio_data.orig_src_ratio =
      g_extern.audio_data.src_ratio =
      (double)g_settings.audio.out_rate / g_extern.audio_data.in_rate;

   if (!rarch_resampler_realloc(&g_extern.audio_data.resampler_data, &g_extern.audio_data.resampler,
         g_settings.audio.resampler, g_extern.audio_data.orig_src_ratio))
   {
      RARCH_ERR("Failed to initialize resampler \"%s\".\n", g_settings.audio.resampler);
      g_extern.audio_active = false;
   }

   rarch_assert(g_extern.audio_data.data = (float*)malloc(max_bufsamples * sizeof(float)));

   g_extern.audio_data.data_ptr = 0;

   rarch_assert(g_settings.audio.out_rate < g_extern.audio_data.in_rate * AUDIO_MAX_RATIO);
   rarch_assert(g_extern.audio_data.outsamples = (float*)malloc(outsamples_max * sizeof(float)));

   g_extern.audio_data.rate_control = false;
   if (!g_extern.system.audio_callback.callback && g_extern.audio_active && g_settings.audio.rate_control)
   {
      if (driver.audio->buffer_size && driver.audio->write_avail)
      {
         g_extern.audio_data.driver_buffer_size = driver.audio->buffer_size(driver.audio_data);
         g_extern.audio_data.rate_control = true;
      }
      else
         RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n");
   }

   rarch_main_command(RARCH_CMD_DSP_FILTER_DEINIT);

   g_extern.measure_data.buffer_free_samples_count = 0;

   if (g_extern.audio_active && !g_extern.audio_data.mute && g_extern.system.audio_callback.callback) // Threaded driver is initially stopped.
      driver.audio->start(driver.audio_data);
}
コード例 #26
0
ファイル: dynamic.c プロジェクト: CatalystG/RetroArch
static void load_symbols(bool is_dummy)
{
   if (is_dummy)
   {
      SYM_DUMMY(retro_init);
      SYM_DUMMY(retro_deinit);

      SYM_DUMMY(retro_api_version);
      SYM_DUMMY(retro_get_system_info);
      SYM_DUMMY(retro_get_system_av_info);

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

      SYM_DUMMY(retro_set_controller_port_device);

      SYM_DUMMY(retro_reset);
      SYM_DUMMY(retro_run);

      SYM_DUMMY(retro_serialize_size);
      SYM_DUMMY(retro_serialize);
      SYM_DUMMY(retro_unserialize);

      SYM_DUMMY(retro_cheat_reset);
      SYM_DUMMY(retro_cheat_set);

      SYM_DUMMY(retro_load_game);
      SYM_DUMMY(retro_load_game_special);

      SYM_DUMMY(retro_unload_game);
      SYM_DUMMY(retro_get_region);
      SYM_DUMMY(retro_get_memory_data);
      SYM_DUMMY(retro_get_memory_size);
   }
   else
   {
#ifdef HAVE_DYNAMIC
      if (path_is_directory(g_settings.libretro))
      {
         char libretro_core_buffer[PATH_MAX];
         if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer),
                  g_settings.libretro, g_extern.fullpath))
         {
            RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n");
            rarch_fail(1, "load_dynamic()");
         }

         strlcpy(g_settings.libretro, libretro_core_buffer, sizeof(g_settings.libretro));
      }

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

      RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
      lib_handle = dylib_load(g_settings.libretro);
      if (!lib_handle)
      {
         RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
         rarch_fail(1, "load_dynamic()");
      }
#endif

      SYM(retro_init);
      SYM(retro_deinit);

      SYM(retro_api_version);
      SYM(retro_get_system_info);
      SYM(retro_get_system_av_info);

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

      SYM(retro_set_controller_port_device);

      SYM(retro_reset);
      SYM(retro_run);

      SYM(retro_serialize_size);
      SYM(retro_serialize);
      SYM(retro_unserialize);

      SYM(retro_cheat_reset);
      SYM(retro_cheat_set);

      SYM(retro_load_game);
      SYM(retro_load_game_special);

      SYM(retro_unload_game);
      SYM(retro_get_region);
      SYM(retro_get_memory_data);
      SYM(retro_get_memory_size);
   }
}
コード例 #27
0
ファイル: audio_driver.c プロジェクト: SAKUJ0/RetroArch
void init_audio(void)
{
   size_t outsamples_max, max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2;
   runloop_t *runloop   = rarch_main_get_ptr();
   driver_t *driver     = driver_get_ptr();
   global_t *global     = global_get_ptr();
   settings_t *settings = config_get_ptr();

   audio_convert_init_simd();

   /* Resource leaks will follow if audio is initialized twice. */
   if (driver->audio_data)
      return;

   /* Accomodate rewind since at some point we might have two full buffers. */
   outsamples_max = max_bufsamples * AUDIO_MAX_RATIO * 
      settings->slowmotion_ratio;

   /* Used for recording even if audio isn't enabled. */
   rarch_assert(global->audio_data.conv_outsamples =
         (int16_t*)malloc(outsamples_max * sizeof(int16_t)));

   if (!global->audio_data.conv_outsamples)
      goto error;

   global->audio_data.block_chunk_size    = AUDIO_CHUNK_SIZE_BLOCKING;
   global->audio_data.nonblock_chunk_size = AUDIO_CHUNK_SIZE_NONBLOCKING;
   global->audio_data.chunk_size          = global->audio_data.block_chunk_size;

   /* Needs to be able to hold full content of a full max_bufsamples
    * in addition to its own. */
   rarch_assert(global->audio_data.rewind_buf = (int16_t*)
         malloc(max_bufsamples * sizeof(int16_t)));

   if (!global->audio_data.rewind_buf)
      goto error;

   global->audio_data.rewind_size             = max_bufsamples;

   if (!settings->audio.enable)
   {
      driver->audio_active = false;
      return;
   }

   find_audio_driver();
#ifdef HAVE_THREADS
   if (global->system.audio_callback.callback)
   {
      RARCH_LOG("Starting threaded audio driver ...\n");
      if (!rarch_threaded_audio_init(&driver->audio, &driver->audio_data,
               *settings->audio.device ? settings->audio.device : NULL,
               settings->audio.out_rate, settings->audio.latency,
               driver->audio))
      {
         RARCH_ERR("Cannot open threaded audio driver ... Exiting ...\n");
         rarch_fail(1, "init_audio()");
      }
   }
   else
#endif
   {
      driver->audio_data = driver->audio->init(*settings->audio.device ?
            settings->audio.device : NULL,
            settings->audio.out_rate, settings->audio.latency);
   }

   if (!driver->audio_data)
   {
      RARCH_ERR("Failed to initialize audio driver. Will continue without audio.\n");
      driver->audio_active = false;
   }

   global->audio_data.use_float = false;
   if (driver->audio_active && driver->audio->use_float(driver->audio_data))
      global->audio_data.use_float = true;

   if (!settings->audio.sync && driver->audio_active)
   {
      rarch_main_command(RARCH_CMD_AUDIO_SET_NONBLOCKING_STATE);
      global->audio_data.chunk_size = 
         global->audio_data.nonblock_chunk_size;
   }

   if (global->audio_data.in_rate <= 0.0f)
   {
      /* Should never happen. */
      RARCH_WARN("Input rate is invalid (%.3f Hz). Using output rate (%u Hz).\n",
            global->audio_data.in_rate, settings->audio.out_rate);
      global->audio_data.in_rate = settings->audio.out_rate;
   }

   global->audio_data.orig_src_ratio =
      global->audio_data.src_ratio =
      (double)settings->audio.out_rate / global->audio_data.in_rate;

   if (!rarch_resampler_realloc(&driver->resampler_data,
            &driver->resampler,
         settings->audio.resampler, global->audio_data.orig_src_ratio))
   {
      RARCH_ERR("Failed to initialize resampler \"%s\".\n",
            settings->audio.resampler);
      driver->audio_active = false;
   }

   rarch_assert(global->audio_data.data = (float*)
         malloc(max_bufsamples * sizeof(float)));

   if (!global->audio_data.data)
      goto error;

   global->audio_data.data_ptr = 0;

   rarch_assert(settings->audio.out_rate <
         global->audio_data.in_rate * AUDIO_MAX_RATIO);
   rarch_assert(global->audio_data.outsamples = (float*)
         malloc(outsamples_max * sizeof(float)));

   if (!global->audio_data.outsamples)
      goto error;

   global->audio_data.rate_control = false;
   if (!global->system.audio_callback.callback && driver->audio_active &&
         settings->audio.rate_control)
   {
      if (driver->audio->buffer_size && driver->audio->write_avail)
      {
         global->audio_data.driver_buffer_size = 
            driver->audio->buffer_size(driver->audio_data);
         global->audio_data.rate_control = true;
      }
      else
         RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n");
   }

   rarch_main_command(RARCH_CMD_DSP_FILTER_DEINIT);

   runloop->measure_data.buffer_free_samples_count = 0;

   if (driver->audio_active && !settings->audio.mute_enable &&
         global->system.audio_callback.callback)
   {
      /* Threaded driver is initially stopped. */
      driver->audio->start(driver->audio_data);
   }

   return;

error:
   if (global->audio_data.conv_outsamples)
      free(global->audio_data.conv_outsamples);
   global->audio_data.conv_outsamples = NULL;
   if (global->audio_data.data)
      free(global->audio_data.data);
   global->audio_data.data = NULL;
   if (global->audio_data.rewind_buf)
      free(global->audio_data.rewind_buf);
   global->audio_data.rewind_buf = NULL;
   if (global->audio_data.outsamples)
      free(global->audio_data.outsamples);
   global->audio_data.outsamples = NULL;
}
コード例 #28
0
ファイル: retroarch.c プロジェクト: blackman91/RetroArch
/**
 * parse_input:
 * @argc                 : Count of (commandline) arguments.
 * @argv                 : (Commandline) arguments.
 *
 * Parses (commandline) arguments passed to program.
 *
 **/
static void parse_input(int argc, char *argv[])
{
   const char *optstring = NULL;
   global_t  *global     = global_get_ptr();
   settings_t *settings  = config_get_ptr();

   const struct option opts[] = {
#ifdef HAVE_DYNAMIC
      { "libretro",     1, NULL, 'L' },
#endif
      { "menu",         0, NULL, RA_OPT_MENU },
      { "help",         0, NULL, 'h' },
      { "save",         1, NULL, 's' },
      { "fullscreen",   0, NULL, 'f' },
      { "record",       1, NULL, 'r' },
      { "recordconfig", 1, NULL, RA_OPT_RECORDCONFIG },
      { "size",         1, NULL, RA_OPT_SIZE },
      { "verbose",      0, NULL, 'v' },
      { "config",       1, NULL, 'c' },
      { "appendconfig", 1, NULL, RA_OPT_APPENDCONFIG },
      { "nodevice",     1, NULL, 'N' },
      { "dualanalog",   1, NULL, 'A' },
      { "device",       1, NULL, 'd' },
      { "savestate",    1, NULL, 'S' },
      { "bsvplay",      1, NULL, 'P' },
      { "bsvrecord",    1, NULL, 'R' },
      { "sram-mode",    1, NULL, 'M' },
#ifdef HAVE_NETPLAY
      { "host",         0, NULL, 'H' },
      { "connect",      1, NULL, 'C' },
      { "frames",       1, NULL, 'F' },
      { "port",         1, NULL, RA_OPT_PORT },
      { "spectate",     0, NULL, RA_OPT_SPECTATE },
#endif
      { "nick",         1, NULL, RA_OPT_NICK },
#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
      { "command",      1, NULL, RA_OPT_COMMAND },
#endif
      { "ups",          1, NULL, 'U' },
      { "bps",          1, NULL, RA_OPT_BPS },
      { "ips",          1, NULL, RA_OPT_IPS },
      { "no-patch",     0, NULL, RA_OPT_NO_PATCH },
      { "detach",       0, NULL, 'D' },
      { "features",     0, NULL, RA_OPT_FEATURES },
      { "subsystem",    1, NULL, RA_OPT_SUBSYSTEM },
      { "max-frames",   1, NULL, RA_OPT_MAX_FRAMES },
      { "eof-exit",     0, NULL, RA_OPT_EOF_EXIT },
      { "version",      0, NULL, RA_OPT_VERSION },
#ifdef HAVE_FILE_LOGGER
      { "log-file",     1, NULL, RA_OPT_LOG_FILE },
#endif
      { NULL, 0, NULL, 0 }
   };

   global->inited.core.no_content        = false;
   global->inited.core.type              = CORE_TYPE_PLAIN;
   *global->subsystem                    = '\0';
   global->has_set.save_path             = false;
   global->has_set.state_path            = false;
   global->has_set.libretro              = false;
   global->has_set.libretro_directory    = false;
   global->has_set.verbosity             = false;

   global->has_set.netplay_mode          = false;
   global->has_set.username              = false;
   global->has_set.netplay_ip_address    = false;
   global->has_set.netplay_delay_frames  = false;
   global->has_set.netplay_ip_port       = false;

   global->has_set.ups_pref              = false;
   global->has_set.bps_pref              = false;
   global->has_set.ips_pref              = false;
   global->patch.ups_pref                = false;
   global->patch.bps_pref                = false;
   global->patch.ips_pref                = false;
   *global->name.ups                     = '\0';
   *global->name.bps                     = '\0';
   *global->name.ips                     = '\0';

   global->overrides_active              = false;

   if (argc < 2)
   {
      global->inited.core.type           = CORE_TYPE_DUMMY;
      return;
   }

   /* Make sure we can call parse_input several times ... */
   optind    = 0;
   optstring = "hs:fvS:A:c:U:DN:d:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG;

   for (;;)
   {
      int port;
      int c = getopt_long(argc, argv, optstring, opts, NULL);

      if (c == -1)
         break;

      switch (c)
      {
         case 'h':
            print_help(argv[0]);
            exit(0);

         case 'd':
         {
            unsigned id = 0;
            struct string_list *list = string_split(optarg, ":");

            port = 0;

            if (list && list->size == 2)
            {
               port = strtol(list->elems[0].data, NULL, 0);
               id = strtoul(list->elems[1].data, NULL, 0);
            }
            string_list_free(list);

            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Connect device to a valid port.\n");
               print_help(argv[0]);
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = id;
            global->has_set.libretro_device[port - 1] = true;
            break;
         }

         case 'A':
            port = strtol(optarg, NULL, 0);
            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Connect dualanalog to a valid port.\n");
               print_help(argv[0]);
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = RETRO_DEVICE_ANALOG;
            global->has_set.libretro_device[port - 1] = true;
            break;

         case 's':
            strlcpy(global->name.savefile, optarg,
                  sizeof(global->name.savefile));
            global->has_set.save_path = true;
            break;

         case 'f':
            global->force_fullscreen = true;
            break;

         case 'S':
            strlcpy(global->name.savestate, optarg,
                  sizeof(global->name.savestate));
            global->has_set.state_path = true;
            break;

         case 'v':
            global->verbosity = true;
            global->has_set.verbosity = true;
            break;

         case 'N':
            port = strtol(optarg, NULL, 0);
            if (port < 1 || port > MAX_USERS)
            {
               RARCH_ERR("Disconnect device from a valid port.\n");
               print_help(argv[0]);
               rarch_fail(1, "parse_input()");
            }
            settings->input.libretro_device[port - 1] = RETRO_DEVICE_NONE;
            global->has_set.libretro_device[port - 1] = true;
            break;

         case 'c':
            strlcpy(global->path.config, optarg,
                  sizeof(global->path.config));
            break;

         case 'r':
            strlcpy(global->record.path, optarg,
                  sizeof(global->record.path));
            global->record.enable = true;
            break;

#ifdef HAVE_DYNAMIC
         case 'L':
            if (path_is_directory(optarg))
            {
               *settings->libretro = '\0';
               strlcpy(settings->libretro_directory, optarg,
                     sizeof(settings->libretro_directory));
               global->has_set.libretro = true;
               global->has_set.libretro_directory = true;
               RARCH_WARN("Using old --libretro behavior. Setting libretro_directory to \"%s\" instead.\n", optarg);
            }
            else
            {
               strlcpy(settings->libretro, optarg,
                     sizeof(settings->libretro));
               global->has_set.libretro = true;
            }
            break;
#endif
         case 'P':
         case 'R':
            strlcpy(global->bsv.movie_start_path, optarg,
                  sizeof(global->bsv.movie_start_path));
            global->bsv.movie_start_playback  = (c == 'P');
            global->bsv.movie_start_recording = (c == 'R');
            break;

         case 'M':
            if (!strcmp(optarg, "noload-nosave"))
            {
               global->sram.load_disable = true;
               global->sram.save_disable = true;
            }
            else if (!strcmp(optarg, "noload-save"))
               global->sram.load_disable = true;
            else if (!strcmp(optarg, "load-nosave"))
               global->sram.save_disable = true;
            else if (strcmp(optarg, "load-save") != 0)
            {
               RARCH_ERR("Invalid argument in --sram-mode.\n");
               print_help(argv[0]);
               rarch_fail(1, "parse_input()");
            }
            break;

#ifdef HAVE_NETPLAY
         case 'H':
            global->has_set.netplay_ip_address = true;
            global->netplay.enable = true;
            *global->netplay.server = '\0';
            break;

         case 'C':
            global->has_set.netplay_ip_address = true;
            global->netplay.enable = true;
            strlcpy(global->netplay.server, optarg,
                  sizeof(global->netplay.server));
            break;

         case 'F':
            global->netplay.sync_frames = strtol(optarg, NULL, 0);
            global->has_set.netplay_delay_frames = true;
            break;
#endif

         case RA_OPT_BPS:
            strlcpy(global->name.bps, optarg,
                  sizeof(global->name.bps));
            global->patch.bps_pref   = true;
            global->has_set.bps_pref = true;
            break;

         case 'U':
            strlcpy(global->name.ups, optarg,
                  sizeof(global->name.ups));
            global->patch.ups_pref   = true;
            global->has_set.ups_pref = true;
            break;

         case RA_OPT_IPS:
            strlcpy(global->name.ips, optarg,
                  sizeof(global->name.ips));
            global->patch.ips_pref   = true;
            global->has_set.ips_pref = true;
            break;

         case RA_OPT_NO_PATCH:
            global->patch.block_patch = true;
            break;

         case 'D':
#if defined(_WIN32) && !defined(_XBOX)
            FreeConsole();
#endif
            break;
         
         case RA_OPT_MENU:
            global->inited.core.type        = CORE_TYPE_DUMMY;
            break;

#ifdef HAVE_NETPLAY
         case RA_OPT_PORT:
            global->has_set.netplay_ip_port = true;
            global->netplay.port = strtoul(optarg, NULL, 0);
            break;

         case RA_OPT_SPECTATE:
            global->has_set.netplay_mode = true;
            global->netplay.is_spectate = true;
            break;

#endif
         case RA_OPT_NICK:
            global->has_set.username = true;
            strlcpy(settings->username, optarg,
                  sizeof(settings->username));
            break;

#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
         case RA_OPT_COMMAND:
            if (network_cmd_send(optarg))
               exit(0);
            else
               rarch_fail(1, "network_cmd_send()");
            break;
#endif

         case RA_OPT_APPENDCONFIG:
            strlcpy(global->path.append_config, optarg,
                  sizeof(global->path.append_config));
            break;

         case RA_OPT_SIZE:
         {
            if (sscanf(optarg, "%ux%u", &global->record.width,
                     &global->record.height) != 2)
            {
               RARCH_ERR("Wrong format for --size.\n");
               print_help(argv[0]);
               rarch_fail(1, "parse_input()");
            }
            break;
         }

         case RA_OPT_RECORDCONFIG:
            strlcpy(global->record.config, optarg,
                  sizeof(global->record.config));
            break;

         case RA_OPT_MAX_FRAMES:
            {
               unsigned max_frames = strtoul(optarg, NULL, 10);
               rarch_main_ctl(RARCH_MAIN_CTL_SET_MAX_FRAMES, &max_frames);
            }
            break;

         case RA_OPT_SUBSYSTEM:
            strlcpy(global->subsystem, optarg, sizeof(global->subsystem));
            break;

         case RA_OPT_FEATURES:
            print_features();
            exit(0);

         case RA_OPT_EOF_EXIT:
            global->bsv.eof_exit = true;
            break;

         case RA_OPT_VERSION:
            print_version();
            exit(0);

#ifdef HAVE_FILE_LOGGER
         case RA_OPT_LOG_FILE:
            global->log_file = fopen(optarg, "wb");
            break;
#endif

         case '?':
            print_help(argv[0]);
            rarch_fail(1, "parse_input()");

         default:
            RARCH_ERR("Error parsing arguments.\n");
            rarch_fail(1, "parse_input()");
      }
   }

   if (global->inited.core.type == CORE_TYPE_DUMMY)
   {
      if (optind < argc)
      {
         RARCH_ERR("--menu was used, but content file was passed as well.\n");
         rarch_fail(1, "parse_input()");
      }
   }
   else if (!*global->subsystem && optind < argc)
      rarch_set_paths(argv[optind]);
   else if (*global->subsystem && optind < argc)
      set_special_paths(argv + optind, argc - optind);
   else
      global->inited.core.no_content = true;


   /* Copy SRM/state dirs used, so they can be reused on reentrancy. */
   if (global->has_set.save_path &&
         path_is_directory(global->name.savefile))
      strlcpy(global->dir.savefile, global->name.savefile,
            sizeof(global->dir.savefile));

   if (global->has_set.state_path &&
         path_is_directory(global->name.savestate))
      strlcpy(global->dir.savestate, global->name.savestate,
            sizeof(global->dir.savestate));
}