예제 #1
0
void rarch_set_paths(const char *path)
{
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   set_basename(path);

   if (!global->has_set_save_path)
      fill_pathname_noext(global->savefile_name, global->basename,
            ".srm", sizeof(global->savefile_name));
   if (!global->has_set_state_path)
      fill_pathname_noext(global->savestate_name, global->basename,
            ".state", sizeof(global->savestate_name));
   fill_pathname_noext(global->cheatfile_name, global->basename,
         ".cht", sizeof(global->cheatfile_name));

   set_paths_redirect(path);

   /* If this is already set, do not overwrite it
    * as this was initialized before in a menu or otherwise. */
   if (*settings->system_directory)
      return;

   fill_pathname_basedir(settings->system_directory, path,
         sizeof(settings->system_directory));
}
예제 #2
0
void path_fill_names(void)
{
   global_t *global = global_get_ptr();

   path_init_savefile_internal();
   
   if (global)
      bsv_movie_set_path(global->name.savefile);

   if (string_is_empty(path_main_basename))
      return;

   if (global)
   {
      if (string_is_empty(global->name.ups))
         fill_pathname_noext(global->name.ups, path_main_basename,
               file_path_str(FILE_PATH_UPS_EXTENSION),
               sizeof(global->name.ups));

      if (string_is_empty(global->name.bps))
         fill_pathname_noext(global->name.bps, path_main_basename,
               file_path_str(FILE_PATH_BPS_EXTENSION),
               sizeof(global->name.bps));

      if (string_is_empty(global->name.ips))
         fill_pathname_noext(global->name.ips, path_main_basename,
               file_path_str(FILE_PATH_IPS_EXTENSION),
               sizeof(global->name.ips));
   }
}
예제 #3
0
static bool event_save_auto_state(void)
{
   bool ret;
   char savestate_name_auto[PATH_MAX_LENGTH] = {0};
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (!settings->savestate_auto_save)
      return false;
   if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
      return false;
   if (content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL))
      return false;

#ifdef HAVE_CHEEVOS
   if (settings->cheevos.hardcore_mode_enable)
      return false;
#endif

   fill_pathname_noext(savestate_name_auto, global->name.savestate,
         ".auto", sizeof(savestate_name_auto));

   ret = content_ctl(CONTENT_CTL_SAVE_STATE, (void*)savestate_name_auto);
   RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ?
         "succeeded" : "failed");

   return true;
}
예제 #4
0
static void event_load_auto_state(void)
{
   bool ret;
   char msg[PATH_MAX_LENGTH]                 = {0};
   char savestate_name_auto[PATH_MAX_LENGTH] = {0};
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

#ifdef HAVE_NETPLAY
   if (global->netplay_enable && !global->netplay_is_spectate)
      return;
#endif

   if (!settings->savestate_auto_load)
      return;

   fill_pathname_noext(savestate_name_auto, global->savestate_name,
         ".auto", sizeof(savestate_name_auto));

   if (!path_file_exists(savestate_name_auto))
      return;

   ret = load_state(savestate_name_auto);

   RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto);

   snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.",
         savestate_name_auto, ret ? "succeeded" : "failed");
   rarch_main_msg_queue_push(msg, 1, 180, false);
   RARCH_LOG("%s\n", msg);
}
예제 #5
0
void rarch_set_paths(const char *path)
{
   global_t   *global   = global_get_ptr();

   set_basename(path);

   if (!global->has_set.save_path)
      fill_pathname_noext(global->name.savefile, global->name.base,
            ".srm", sizeof(global->name.savefile));
   if (!global->has_set.state_path)
      fill_pathname_noext(global->name.savestate, global->name.base,
            ".state", sizeof(global->name.savestate));
   fill_pathname_noext(global->name.cheatfile, global->name.base,
         ".cht", sizeof(global->name.cheatfile));

   set_paths_redirect(path);
}
예제 #6
0
void fill_pathname_join_concat_noext(
      char *out_path,
      const char *dir, const char *path,
      const char *concat,
      size_t size)
{
   fill_pathname_noext(out_path, dir, path, size);
   strlcat(out_path, concat, size);
}
예제 #7
0
static void menu_action_setting_disp_set_label_playlist_associations(file_list_t* list,
      unsigned *w, unsigned type, unsigned i,
      const char *label,
      char *s, size_t len,
      const char *entry_label,
      const char *path,
      char *s2, size_t len2)
{
   char playlist_name_with_ext[255];
   bool found_matching_core_association         = false;
   settings_t         *settings                 = config_get_ptr();
   struct string_list *str_list                 = string_split(settings->arrays.playlist_names, ";");
   struct string_list *str_list2                = string_split(settings->arrays.playlist_cores, ";");

   strlcpy(s2, path, len2);

   playlist_name_with_ext[0] = '\0';
   *s = '\0';
   *w = 19;

   fill_pathname_noext(playlist_name_with_ext, path,
         file_path_str(FILE_PATH_LPL_EXTENSION),
         sizeof(playlist_name_with_ext));

   for (i = 0; i < str_list->size; i++)
   {
      if (string_is_equal(str_list->elems[i].data, playlist_name_with_ext))
      {
         if (str_list->size != str_list2->size)
            break;

         if (!str_list2->elems[i].data)
            break;

         found_matching_core_association = true;
         strlcpy(s, str_list2->elems[i].data, len);
      }
   }

   string_list_free(str_list);
   string_list_free(str_list2);

   if (string_is_equal(s, file_path_str(FILE_PATH_DETECT)) || !found_matching_core_association)
      strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), len);
   else
   {
      char buf[PATH_MAX_LENGTH];
      core_info_list_t *list = NULL;

      core_info_get_list(&list);

      if (core_info_list_get_display_name(list, s, buf, sizeof(buf)))
         strlcpy(s, buf, len);
   }

   strlcpy(s2, path, len2);
}
예제 #8
0
/**
 * cheat_manager_save:
 * @path                      : Path to cheats file (relative path).
 *
 * Saves cheats to file on disk.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool cheat_manager_save(const char *path)
{
    bool ret;
    unsigned i;
    config_file_t *conf               = NULL;
    char buf[PATH_MAX_LENGTH]         = {0};
    char cheats_file[PATH_MAX_LENGTH] = {0};
    settings_t              *settings = config_get_ptr();
    cheat_manager_t *handle = cheat_manager_state;

    fill_pathname_join(buf, settings->path.cheat_database,
                       path, sizeof(buf));

    fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file));

    conf = config_file_new(cheats_file);

    if (!conf)
        conf = config_file_new(NULL);

    if (!conf)
        return false;

    if (!handle)
    {
        config_file_free(conf);
        return false;
    }

    config_set_int(conf, "cheats", handle->size);

    for (i = 0; i < handle->size; i++)
    {
        char key[64]         = {0};
        char desc_key[256]   = {0};
        char code_key[256]   = {0};
        char enable_key[256] = {0};

        snprintf(key,        sizeof(key),        "cheat%u",        i);
        snprintf(desc_key,   sizeof(desc_key),   "cheat%u_desc",   i);
        snprintf(code_key,   sizeof(code_key),   "cheat%u_code",   i);
        snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i);

        if (handle->cheats[i].desc)
            config_set_string(conf, desc_key,   handle->cheats[i].desc);
        else
            config_set_string(conf, desc_key,   handle->cheats[i].code);
        config_set_string(conf,    code_key,   handle->cheats[i].code);
        config_set_bool(conf,      enable_key, handle->cheats[i].state);
    }

    ret = config_file_write(conf, cheats_file);
    config_file_free(conf);

    return ret;
}
예제 #9
0
void rarch_fill_pathnames(void)
{
   global_t   *global   = global_get_ptr();

   rarch_init_savefile_paths();
   fill_pathname(global->bsv.movie_path, global->savefile_name, "",
         sizeof(global->bsv.movie_path));

   if (!*global->basename)
      return;

   if (!*global->ups_name)
      fill_pathname_noext(global->ups_name, global->basename, ".ups",
            sizeof(global->ups_name));
   if (!*global->bps_name)
      fill_pathname_noext(global->bps_name, global->basename, ".bps",
            sizeof(global->bps_name));
   if (!*global->ips_name)
      fill_pathname_noext(global->ips_name, global->basename, ".ips",
            sizeof(global->ips_name));
}
예제 #10
0
static void path_set_names(const char *path)
{
   global_t *global = global_get_ptr();

   path_set_basename(path);

   if (global)
   {
      if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL))
         fill_pathname_noext(global->name.savefile, path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION), sizeof(global->name.savefile));

      if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL))
         fill_pathname_noext(global->name.savestate, path_main_basename,
               file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate));

      fill_pathname_noext(global->name.cheatfile, path_main_basename,
            file_path_str(FILE_PATH_CHT_EXTENSION), sizeof(global->name.cheatfile));
   }

   path_set_redirect();
}
예제 #11
0
/**
 * fill_pathname:
 * @out_path           : output path
 * @in_path            : input  path
 * @replace            : what to replace
 * @size               : buffer size of output path
 *
 * FIXME: Verify
 *
 * Replaces filename extension with 'replace' and outputs result to out_path.
 * The extension here is considered to be the string from the last '.'
 * to the end.
 *
 * Only '.'s after the last slash are considered as extensions.
 * If no '.' is present, in_path and replace will simply be concatenated.
 * 'size' is buffer size of 'out_path'.
 * E.g.: in_path = "/foo/bar/baz/boo.c", replace = ".asm" =>
 * out_path = "/foo/bar/baz/boo.asm"
 * E.g.: in_path = "/foo/bar/baz/boo.c", replace = ""     =>
 * out_path = "/foo/bar/baz/boo"
 */
void fill_pathname(char *out_path, const char *in_path,
      const char *replace, size_t size)
{
   char tmp_path[PATH_MAX_LENGTH];
   char *tok                      = NULL;

   tmp_path[0] = '\0';

   strlcpy(tmp_path, in_path, sizeof(tmp_path));
   if ((tok = (char*)strrchr(path_basename(tmp_path), '.')))
      *tok = '\0';

   fill_pathname_noext(out_path, tmp_path, replace, size);
}
예제 #12
0
static void set_special_paths(char **argv, unsigned num_content)
{
   unsigned i;
   union string_list_elem_attr attr;
   global_t   *global   = global_get_ptr();
   settings_t *settings = config_get_ptr();

   /* First content file is the significant one. */
   set_basename(argv[0]);

   global->subsystem_fullpaths = string_list_new();
   rarch_assert(global->subsystem_fullpaths);

   attr.i = 0;

   for (i = 0; i < num_content; i++)
      string_list_append(global->subsystem_fullpaths, argv[i], attr);

   /* We defer SRAM path updates until we can resolve it.
    * It is more complicated for special content types. */

   if (!global->has_set.state_path)
      fill_pathname_noext(global->name.savestate, global->name.base,
            ".state", sizeof(global->name.savestate));

   if (path_is_directory(global->name.savestate))
   {
      fill_pathname_dir(global->name.savestate, global->name.base,
            ".state", sizeof(global->name.savestate));
      RARCH_LOG("%s \"%s\".\n",
            msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO),
            global->name.savestate);
   }

   /* If this is already set,
    * do not overwrite it as this was initialized before in
    * a menu or otherwise. */
   if (settings->system_directory[0] == '\0')
   {
      RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n",argv[0]);
      /*fill_pathname_basedir(settings->system_directory, argv[0],
            sizeof(settings->system_directory));*/
   }

}
예제 #13
0
static bool event_save_auto_state(void)
{
   bool ret;
   char savestate_name_auto[PATH_MAX_LENGTH];
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (!settings->savestate_auto_save || global->libretro_dummy ||
       global->libretro_no_content)
       return false;

   fill_pathname_noext(savestate_name_auto, global->savestate_name,
         ".auto", sizeof(savestate_name_auto));

   ret = save_state(savestate_name_auto);
   RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ?
         "succeeded" : "failed");

   return true;
}
예제 #14
0
bool input_remapping_remove_file(const char *path)
{
   bool ret                = false;
   size_t path_size        = PATH_MAX_LENGTH * sizeof(char);
   char *buf               = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *remap_file        = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   settings_t    *settings = config_get_ptr();

   buf[0] = remap_file[0]            = '\0';

   fill_pathname_join(buf, settings->paths.directory_input_remapping,
         path, path_size);

   fill_pathname_noext(remap_file, buf, ".rmp", path_size);

   ret = filestream_delete(remap_file) == 0 ? true : false;
   free(buf);
   free(remap_file);
   return ret;
}
예제 #15
0
static bool event_save_auto_state(void)
{
   bool ret;
   char savestate_name_auto[PATH_MAX_LENGTH] = {0};
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (!settings->savestate_auto_save ||
         (global->inited.core.type == CORE_TYPE_DUMMY) ||
       global->inited.core.no_content)
       return false;

   fill_pathname_noext(savestate_name_auto, global->name.savestate,
         ".auto", sizeof(savestate_name_auto));

   ret = save_state(savestate_name_auto);
   RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ?
         "succeeded" : "failed");

   return true;
}
예제 #16
0
static void set_special_paths(char **argv, unsigned num_content)
{
   unsigned i;
   union string_list_elem_attr attr;
   global_t   *global   = global_get_ptr();
   settings_t *settings = config_get_ptr();

   /* First content file is the significant one. */
   set_basename(argv[0]);

   global->subsystem_fullpaths = string_list_new();
   rarch_assert(global->subsystem_fullpaths);

   attr.i = 0;

   for (i = 0; i < num_content; i++)
      string_list_append(global->subsystem_fullpaths, argv[i], attr);

   /* We defer SRAM path updates until we can resolve it.
    * It is more complicated for special content types. */

   if (!global->has_set_state_path)
      fill_pathname_noext(global->savestate_name, global->basename,
            ".state", sizeof(global->savestate_name));

   if (path_is_directory(global->savestate_name))
   {
      fill_pathname_dir(global->savestate_name, global->basename,
            ".state", sizeof(global->savestate_name));
      RARCH_LOG("Redirecting save state to \"%s\".\n",
            global->savestate_name);
   }

   /* If this is already set,
    * do not overwrite it as this was initialized before in
    * a menu or otherwise. */
   if (!*settings->system_directory)
      fill_pathname_basedir(settings->system_directory, argv[0],
            sizeof(settings->system_directory));
}
예제 #17
0
void path_set_special(char **argv, unsigned num_content)
{
   unsigned i;
   union string_list_elem_attr attr;
   global_t   *global   = global_get_ptr();

   /* First content file is the significant one. */
   path_set_basename(argv[0]);

   subsystem_fullpaths = string_list_new();
   retro_assert(subsystem_fullpaths);

   attr.i = 0;

   for (i = 0; i < num_content; i++)
      string_list_append(subsystem_fullpaths, argv[i], attr);

   /* We defer SRAM path updates until we can resolve it.
    * It is more complicated for special content types. */
   if (global)
   {
      if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL))
         fill_pathname_noext(global->name.savestate, path_main_basename,
               file_path_str(FILE_PATH_STATE_EXTENSION),
               sizeof(global->name.savestate));

      if (path_is_directory(global->name.savestate))
      {
         fill_pathname_dir(global->name.savestate, path_main_basename,
               file_path_str(FILE_PATH_STATE_EXTENSION),
               sizeof(global->name.savestate));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO),
               global->name.savestate);
      }
   }
}
예제 #18
0
static void event_load_auto_state(void)
{
   bool ret;
   char msg[128]                             = {0};
   char savestate_name_auto[PATH_MAX_LENGTH] = {0};
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

#ifdef HAVE_NETPLAY
   if (global->netplay.enable && !global->netplay.is_spectate)
      return;
#endif

#ifdef HAVE_CHEEVOS
   if (settings->cheevos.hardcore_mode_enable)
      return;
#endif

   if (!settings->savestate_auto_load)
      return;

   fill_pathname_noext(savestate_name_auto, global->name.savestate,
         ".auto", sizeof(savestate_name_auto));

   if (!path_file_exists(savestate_name_auto))
      return;

   ret = content_ctl(CONTENT_CTL_LOAD_STATE, (void*)savestate_name_auto);

   RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto);

   snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.",
         savestate_name_auto, ret ? "succeeded" : "failed");
   runloop_msg_queue_push(msg, 1, 180, false);
   RARCH_LOG("%s\n", msg);
}
예제 #19
0
/**
 * input_remapping_save_file:
 * @path                     : Path to remapping file (relative path).
 *
 * Saves remapping values to file.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool input_remapping_save_file(const char *path)
{
   bool ret;
   unsigned i, j;
   char buf[PATH_MAX_LENGTH]         = {0};
   char remap_file[PATH_MAX_LENGTH]  = {0};
   config_file_t               *conf = NULL;
   settings_t              *settings = config_get_ptr();

   fill_pathname_join(buf, settings->directory.input_remapping,
         path, sizeof(buf));

   fill_pathname_noext(remap_file, buf, ".rmp", sizeof(remap_file));

   conf = config_file_new(remap_file);

   if (!conf)
   {
      conf = config_file_new(NULL);
      if (!conf)
         return false;
   }

   for (i = 0; i < settings->input.max_users; i++)
   {
      char buf[64] = {0};
      char key_ident[RARCH_FIRST_CUSTOM_BIND + 4][128]   = {{0}};
      char key_strings[RARCH_FIRST_CUSTOM_BIND + 4][128] = {
         "b", "y", "select", "start",
         "up", "down", "left", "right",
         "a", "x", "l", "r", "l2", "r2",
         "l3", "r3", "l_x", "l_y", "r_x", "r_y" };

      snprintf(buf, sizeof(buf), "input_player%u", i + 1);

      for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 4; j++)
      {
         fill_pathname_join_delim(key_ident[j], buf,
               key_strings[j], '_', sizeof(key_ident[j]));

         /* only save values that have been modified */
         if(j < RARCH_FIRST_CUSTOM_BIND)
         {
            if(settings->input.remap_ids[i][j] != j)
               config_set_int(conf, key_ident[j], settings->input.remap_ids[i][j]);
            else
               config_unset(conf,key_ident[j]);
         }
         else
         {
            if(settings->input.remap_ids[i][j] != j - RARCH_FIRST_CUSTOM_BIND)
               config_set_int(conf, key_ident[j], settings->input.remap_ids[i][j]);
            else
               config_unset(conf,key_ident[j]);
         }
      }


      snprintf(buf, sizeof(buf), "input_libretro_device_p%u", i + 1);
      config_set_int(conf, buf, settings->input.libretro_device[i]);
      snprintf(buf, sizeof(buf), "input_player%u_analog_dpad_mode", i + 1);
      config_set_int(conf, buf, settings->input.analog_dpad_mode[i]);
   }

   ret = config_file_write(conf, remap_file);
   config_file_free(conf);

   return ret;
}
예제 #20
0
bool rarch_ctl(enum rarch_ctl_state state, void *data)
{
   driver_t *driver     = driver_get_ptr();
   global_t *global     = global_get_ptr();
   settings_t *settings = config_get_ptr();
   rarch_system_info_t *system = rarch_system_info_get_ptr();

   switch(state)
   {
      case RARCH_ACTION_STATE_REPLACE_CONFIG:
         {
            char *path = (char*)data;

            if (!path)
               return false;

            /* If config file to be replaced is the same as the
             * current config file, exit. */
            if (!strcmp(path, global->path.config))
               return false;

            if (settings->config_save_on_exit && *global->path.config)
               config_save_file(global->path.config);

            strlcpy(global->path.config, path, sizeof(global->path.config));
            global->block_config_read = false;
            *settings->libretro = '\0'; /* Load core in new config. */
         }
         event_command(EVENT_CMD_PREPARE_DUMMY);
         return true;
      case RARCH_ACTION_STATE_MENU_RUNNING:
#ifdef HAVE_MENU
         menu_driver_toggle(true);
#endif
#ifdef HAVE_OVERLAY
         if (settings->input.overlay_hide_in_menu)
            event_command(EVENT_CMD_OVERLAY_DEINIT);
#endif
         break;
      case RARCH_ACTION_STATE_LOAD_CONTENT:
#ifdef HAVE_MENU
         /* If content loading fails, we go back to menu. */
         if (!menu_load_content(CORE_TYPE_PLAIN))
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->content_loaded)
            driver->frontend_ctx->content_loaded();
         break;
#ifdef HAVE_FFMPEG
      case RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG:
#ifdef HAVE_MENU
         /* If content loading fails, we go back to menu. */
         if (!menu_load_content(CORE_TYPE_FFMPEG))
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->content_loaded)
            driver->frontend_ctx->content_loaded();
         break;
#endif
      case RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER:
#ifdef HAVE_MENU
         /* If content loading fails, we go back to menu. */
         if (!menu_load_content(CORE_TYPE_IMAGEVIEWER))
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->content_loaded)
            driver->frontend_ctx->content_loaded();
         break;
      case RARCH_ACTION_STATE_MENU_RUNNING_FINISHED:
#ifdef HAVE_MENU
         menu_driver_toggle(false);
#endif
         video_driver_set_texture_enable(false, false);
#ifdef HAVE_OVERLAY
         if (settings && settings->input.overlay_hide_in_menu)
            event_command(EVENT_CMD_OVERLAY_INIT);
#endif
         break;
      case RARCH_ACTION_STATE_QUIT:
         if (global)
            system->shutdown = true;
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);
         break;
      case RARCH_ACTION_STATE_FORCE_QUIT:
         rarch_ctl(RARCH_ACTION_STATE_QUIT, NULL);
         break;
      case RARCH_ACTION_STATE_VALIDATE_CPU_FEATURES:
         {
            uint64_t cpu = retro_get_cpu_features();
            (void)cpu;

#ifdef __SSE__
            if (!(cpu & RETRO_SIMD_SSE))
               FAIL_CPU("SSE");
#endif
#ifdef __SSE2__
            if (!(cpu & RETRO_SIMD_SSE2))
               FAIL_CPU("SSE2");
#endif
#ifdef __AVX__
            if (!(cpu & RETRO_SIMD_AVX))
               FAIL_CPU("AVX");
#endif
         }
         break;
      case RARCH_ACTION_STATE_VERIFY_API_VERSION:
         RARCH_LOG("Version of libretro API: %u\n", core.retro_api_version());
         RARCH_LOG("Compiled against API: %u\n",    RETRO_API_VERSION);

         if (core.retro_api_version() != RETRO_API_VERSION)
            RARCH_WARN("%s\n", msg_hash_to_str(MSG_LIBRETRO_ABI_BREAK));
         break;
      case RARCH_ACTION_STATE_FILL_PATHNAMES:
         rarch_init_savefile_paths();
         strlcpy(global->bsv.movie_path, global->name.savefile,
               sizeof(global->bsv.movie_path));

         if (!*global->name.base)
            return false;

         if (!*global->name.ups)
            fill_pathname_noext(global->name.ups, global->name.base, ".ups",
                  sizeof(global->name.ups));
         if (!*global->name.bps)
            fill_pathname_noext(global->name.bps, global->name.base, ".bps",
                  sizeof(global->name.bps));
         if (!*global->name.ips)
            fill_pathname_noext(global->name.ips, global->name.base, ".ips",
                  sizeof(global->name.ips));
         break;
      case RARCH_ACTION_STATE_NONE:
      default:
         return false;
   }

   return true;
}
예제 #21
0
static void rarch_init_savefile_paths(void)
{
   global_t *global = global_get_ptr();

   event_command(EVENT_CMD_SAVEFILES_DEINIT);

   global->savefiles = string_list_new();
   rarch_assert(global->savefiles);

   if (*global->subsystem)
   {
      /* For subsystems, we know exactly which RAM types are supported. */

      unsigned i, j;
      const struct retro_subsystem_info *info =
         libretro_find_subsystem_info(
               global->system.special, global->system.num_special,
               global->subsystem);

      /* We'll handle this error gracefully later. */
      unsigned num_content = min(info ? info->num_roms : 0,
            global->subsystem_fullpaths ?
            global->subsystem_fullpaths->size : 0);

      bool use_sram_dir = path_is_directory(global->savefile_dir);

      for (i = 0; i < num_content; i++)
      {
         for (j = 0; j < info->roms[i].num_memory; j++)
         {
            union string_list_elem_attr attr;
            char path[PATH_MAX_LENGTH], ext[32];
            const struct retro_subsystem_memory_info *mem =
               (const struct retro_subsystem_memory_info*)
               &info->roms[i].memory[j];

            snprintf(ext, sizeof(ext), ".%s", mem->extension);

            if (use_sram_dir)
            {
               /* Redirect content fullpath to save directory. */
               strlcpy(path, global->savefile_dir, sizeof(path));
               fill_pathname_dir(path,
                     global->subsystem_fullpaths->elems[i].data, ext,
                     sizeof(path));
            }
            else
            {
               fill_pathname(path, global->subsystem_fullpaths->elems[i].data,
                     ext, sizeof(path));
            }

            attr.i = mem->type;
            string_list_append(global->savefiles, path, attr);
         }
      }

      /* Let other relevant paths be inferred from the main SRAM location. */
      if (!global->has_set_save_path)
         fill_pathname_noext(global->savefile_name, global->basename, ".srm",
               sizeof(global->savefile_name));
      if (path_is_directory(global->savefile_name))
      {
         fill_pathname_dir(global->savefile_name, global->basename, ".srm",
               sizeof(global->savefile_name));
         RARCH_LOG("Redirecting save file to \"%s\".\n",
               global->savefile_name);
      }
   }
   else
   {
      char savefile_name_rtc[PATH_MAX_LENGTH];
      union string_list_elem_attr attr;

      attr.i = RETRO_MEMORY_SAVE_RAM;
      string_list_append(global->savefiles, global->savefile_name, attr);

      /* Infer .rtc save path from save ram path. */
      attr.i = RETRO_MEMORY_RTC;
      fill_pathname(savefile_name_rtc,
            global->savefile_name, ".rtc", sizeof(savefile_name_rtc));
      string_list_append(global->savefiles, savefile_name_rtc, attr);
   }
}
예제 #22
0
static bool path_init_subsystem(void)
{
   unsigned i, j;
   const struct retro_subsystem_info *info = NULL;
   rarch_system_info_t             *system = NULL;
   global_t                        *global = global_get_ptr();

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);

   if (!system)
      return false;

   if (path_is_empty(RARCH_PATH_SUBSYSTEM))
      return false;

   /* For subsystems, we know exactly which RAM types are supported. */

   info = libretro_find_subsystem_info(
         system->subsystem.data,
         system->subsystem.size,
         path_get(RARCH_PATH_SUBSYSTEM));

   /* We'll handle this error gracefully later. */

   if (info)
   {
      unsigned num_content = MIN(info->num_roms,
            path_is_empty(RARCH_PATH_SUBSYSTEM) ?
            0 : subsystem_fullpaths->size);

      for (i = 0; i < num_content; i++)
      {
         for (j = 0; j < info->roms[i].num_memory; j++)
         {
            union string_list_elem_attr attr;
            char path[PATH_MAX_LENGTH];
            char ext[32];
            const struct retro_subsystem_memory_info *mem =
               (const struct retro_subsystem_memory_info*)
               &info->roms[i].memory[j];

            path[0] = ext[0] = '\0';

            snprintf(ext, sizeof(ext), ".%s", mem->extension);

            if (path_is_directory(dir_get(RARCH_DIR_SAVEFILE)))
            {
               /* Use SRAM dir */
               /* Redirect content fullpath to save directory. */
               strlcpy(path, dir_get(RARCH_DIR_SAVEFILE), sizeof(path));
               fill_pathname_dir(path,
                     subsystem_fullpaths->elems[i].data, ext,
                     sizeof(path));
            }
            else
            {
               fill_pathname(path, subsystem_fullpaths->elems[i].data,
                     ext, sizeof(path));
            }

            attr.i = mem->type;
            string_list_append((struct string_list*)savefile_ptr_get(), path, attr);
         }
      }
   }

   if (global)
   {
      /* Let other relevant paths be inferred from the main SRAM location. */
      if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL))
         fill_pathname_noext(global->name.savefile,
               path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION),
               sizeof(global->name.savefile));

      if (path_is_directory(global->name.savefile))
      {
         fill_pathname_dir(global->name.savefile,
               path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION),
               sizeof(global->name.savefile));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO),
               global->name.savefile);
      }
   }

   return true;
}
예제 #23
0
/**
 * input_remapping_save_file:
 * @path                     : Path to remapping file (relative path).
 *
 * Saves remapping values to file.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool input_remapping_save_file(const char *path)
{
   bool ret;
   unsigned i, j, k;
   size_t path_size                  = PATH_MAX_LENGTH * sizeof(char);
   char *buf                         = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *remap_file                  = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   config_file_t               *conf = NULL;
   unsigned max_users                = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
   settings_t              *settings = config_get_ptr();

   buf[0] = remap_file[0]            = '\0';

   fill_pathname_join(buf, settings->paths.directory_input_remapping,
         path, path_size);

   fill_pathname_noext(remap_file, buf, ".rmp", path_size);

   free(buf);

   conf = config_file_new(remap_file);

   if (!conf)
   {
      conf = config_file_new(NULL);
      if (!conf)
      {
         free(remap_file);
         return false;
      }
   }

   for (i = 0; i < max_users; i++)
   {
      char s1[64], s2[64], s3[64];
      char btn_ident[RARCH_FIRST_CUSTOM_BIND][128]       = {{0}};
      char key_ident[RARCH_FIRST_CUSTOM_BIND][128]       = {{0}};
      char stk_ident[8][128]                             = {{0}};

      char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = {
         "b", "y", "select", "start",
         "up", "down", "left", "right",
         "a", "x", "l", "r", "l2", "r2",
         "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };

      s1[0] = '\0';
      s2[0] = '\0';

      snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
      snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
      snprintf(s3, sizeof(s1), "input_player%u_stk", i + 1);

      for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
      {

         if(j < RARCH_FIRST_CUSTOM_BIND)
         {
            fill_pathname_join_delim(btn_ident[j], s1,
               key_strings[j], '_', sizeof(btn_ident[j]));
            fill_pathname_join_delim(key_ident[j], s2,
               key_strings[j], '_', sizeof(btn_ident[j]));

            /* only save values that have been modified */
            if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED)
               config_set_int(conf, btn_ident[j], settings->uints.input_remap_ids[i][j]);
            else if (settings->uints.input_remap_ids[i][j] != j && 
                     settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED)
               config_set_int(conf, btn_ident[j], -1);
            else
               config_unset(conf,btn_ident[j]);

            if (settings->uints.input_keymapper_ids[i][j] != RETROK_UNKNOWN)
               config_set_int(conf, key_ident[j], 
                  settings->uints.input_keymapper_ids[i][j]);
         }
         else
         {
            k = j - RARCH_FIRST_CUSTOM_BIND;
            fill_pathname_join_delim(stk_ident[k], s3,
               key_strings[j], '_', sizeof(stk_ident[k]));
            if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED)
               config_set_int(conf, stk_ident[k], 
                  settings->uints.input_remap_ids[i][j]);
            else if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED)
               config_set_int(conf, stk_ident[k], 
                  -1);
            else
               config_unset(conf, stk_ident[k]);
         }
      }
      snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
      config_set_int(conf, s1, input_config_get_device(i));
      snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1);
      config_set_int(conf, s1, settings->uints.input_analog_dpad_mode[i]);
   }

   ret = config_file_write(conf, remap_file);
   config_file_free(conf);

   free(remap_file);
   return ret;
}