コード例 #1
0
static bool input_autoconfigure_joypad_from_conf_dir(
      autoconfig_params_t *params)
{
   size_t i;
   int ret          = 0;
   int index        = -1;
   int current_best = 0;
   config_file_t *conf        = NULL;
   struct string_list *list   = NULL;
   char path[PATH_MAX_LENGTH] = {0};
   settings_t *settings       = config_get_ptr();

   fill_pathname_join(path,settings->input.autoconfig_dir,
         settings->input.joypad_driver,
         sizeof(path));

   if (settings)
      list = dir_list_new(path, "cfg", false);

   if (!list || !list->size)
      list = dir_list_new(settings->input.autoconfig_dir, "cfg", false);

   if(!list)
      return false;

   RARCH_LOG("Autoconfig: %d profiles found\n", list->size);

   for (i = 0; i < list->size; i++)
   {
      conf = config_file_new(list->elems[i].data);
      ret = input_try_autoconfigure_joypad_from_conf(conf, params);
      if(ret >= current_best)
      {
         index = i;
         current_best = ret;
      }
      config_file_free(conf);
   }

   if(index >= 0 && current_best > 0)
   {
      RARCH_LOG("Autoconf: best configuration score=%d\n", current_best);
      conf = config_file_new(list->elems[index].data);
      input_autoconfigure_joypad_add(conf, params);
      config_file_free(conf);
   }
   else
      ret = 0;

   string_list_free(list);

   if (ret == 0)
      return false;
   return true;
}
コード例 #2
0
ファイル: main.c プロジェクト: magicseb/RetroArch
static void find_and_set_first_file(void)
{
   //Last fallback - we'll need to start the first executable file 
   // we can find in the RetroArch cores directory

#if defined(_XBOX)
   char ** dir_list = dir_list_new("game:\\", ".xex");
#elif defined(__CELLOS_LV2__)
   char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, ".SELF");
#endif

   if (!dir_list)
   {
      RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n");
      return;
   }

   char * first_executable = dir_list[0];

   if(first_executable)
   {
#ifdef _XBOX
      //Check if it's RetroArch Salamander itself - if so, first_executable needs to
      //be overridden
      char fname_tmp[MAX_PATH_LENGTH];

      fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));

      if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0)
      {
         RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n");
	 first_executable = dir_list[1];
	 fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));

	 if(!first_executable)
	 {
            RARCH_WARN("There is no second entry - no choice but to boot RetroArch Salamander\n");
	    first_executable = dir_list[0];
	    fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));
	 }
      }

      snprintf(first_executable, sizeof(first_executable), "game:\\%s", fname_tmp);
#endif
      RARCH_LOG("Start first entry in libretro cores dir: [%s].\n", first_executable);
      strlcpy(libretro_path, first_executable, sizeof(libretro_path));
   }
   else
   {
      RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n");
   }

   dir_list_free(dir_list);
}
コード例 #3
0
ファイル: database_info.c プロジェクト: RobLoach/RetroArch
database_info_handle_t *database_info_dir_init(const char *dir,
      enum database_type type, retro_task_t *task,
      bool show_hidden_files)
{
   core_info_list_t *core_info_list = NULL;
   struct string_list       *list   = NULL;
   database_info_handle_t     *db   = (database_info_handle_t*)
      calloc(1, sizeof(*db));

   if (!db)
      return NULL;

   core_info_get_list(&core_info_list);

   list = dir_list_new(dir, core_info_list->all_ext,
         false, show_hidden_files,
         false, true);

   if (!list)
   {
      free(db);
      return NULL;
   }

   dir_list_prioritize(list);

   db->list           = list;
   db->list_ptr       = 0;
   db->status         = DATABASE_STATUS_ITERATE;
   db->type           = type;

   return db;
}
コード例 #4
0
ファイル: lakka.c プロジェクト: mprobinson/RetroArch
static void lakka_init_items(lakka_handle_t *lakka,
      int i, menu_category_t *category,
      core_info_t *info, const char* path)
{
   int num_items, j;
   struct string_list *list = NULL;

   if (category == NULL || info == NULL)
      return;

   list = (struct string_list*)dir_list_new(path, info->supported_extensions, true);

   dir_list_sort(list, true);

   num_items = list ? list->size : 0;

   for (j = 0; j < num_items; j++)
   {
      if (list->elems[j].attr.i == RARCH_DIRECTORY) // is a directory
         lakka_init_items(lakka, i, category, info, list->elems[j].data);
      else
      {
         lakka_init_item(lakka, i, j, category, info, list, 
               path_basename(list->elems[j].data));
      }
   }

   string_list_free(list);
}
コード例 #5
0
ファイル: dynamic.c プロジェクト: barnhilltrckn/RetroArch-1
static bool find_first_libretro(char *path, size_t size,
      const char *dir, const char *rom_path)
{
   bool ret = false;
   const char *ext = path_get_extension(rom_path);
   if (!ext || !*ext)
   {
      RARCH_ERR("Path has no extension. Cannot infer libretro implementation.\n");
      return false;
   }

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir);

   struct string_list *list = dir_list_new(dir, DYNAMIC_EXT, false);
   if (!list)
   {
      RARCH_ERR("Couldn't open directory: \"%s\".\n", dir);
      return false;
   }

   for (size_t i = 0; i < list->size && !ret; i++)
   {
      RARCH_LOG("Checking library: \"%s\".\n", list->elems[i].data);
      dylib_t lib = dylib_load(list->elems[i].data);
      if (!lib)
         continue;

      void (*proc)(struct retro_system_info*) = 
         (void (*)(struct retro_system_info*))dylib_proc(lib, "retro_get_system_info");

      if (!proc)
      {
         dylib_close(lib);
         continue;
      }

      struct retro_system_info info = {0};
      proc(&info);

      if (!info.valid_extensions)
      {
         dylib_close(lib);
         continue;
      }

      struct string_list *supported_ext = string_split(info.valid_extensions, "|"); 

      if (string_list_find_elem(supported_ext, ext))
      {
         strlcpy(path, list->elems[i].data, size);
         ret = true;
      }

      string_list_free(supported_ext);
      dylib_close(lib);
   }

   dir_list_free(list);
   return ret;
}
コード例 #6
0
ファイル: menu_entries.c プロジェクト: Miinky-Games/RetroArch
static void menu_entries_content_list_push(
      file_list_t *list, core_info_t *info, const char* path)
{
   unsigned j;
   struct string_list *str_list = NULL;

   if (!info)
      return;

   str_list = (struct string_list*)dir_list_new(path,
         info->supported_extensions, true);

   if (!str_list)
      return;

   dir_list_sort(str_list, true);

   for (j = 0; j < str_list->size; j++)
   {
      const char *name = str_list->elems[j].data;
      
      if (!name)
         continue;

      if (str_list->elems[j].attr.i == RARCH_DIRECTORY)
         menu_entries_content_list_push(list, info, name);
      else
         menu_list_push(
               list, name,
               "content_actions",
               MENU_FILE_CONTENTLIST_ENTRY, 0);
   }

   string_list_free(str_list);
}
コード例 #7
0
ファイル: video_filter.c プロジェクト: bronnel/RetroArch
rarch_softfilter_t *rarch_softfilter_new(const char *filter_config,
      unsigned threads,
      enum retro_pixel_format in_pixel_format,
      unsigned max_width, unsigned max_height)
{
   softfilter_simd_mask_t cpu_features = retro_get_cpu_features();
   char basedir[PATH_MAX_LENGTH] = {0};
   struct string_list *plugs     = NULL;
   rarch_softfilter_t *filt      = NULL;

   (void)basedir;

   filt = (rarch_softfilter_t*)calloc(1, sizeof(*filt));
   if (!filt)
      return NULL;

   filt->conf = config_file_new(filter_config);
   if (!filt->conf)
   {
      RARCH_ERR("[SoftFilter]: Did not find config: %s\n", filter_config);
      goto error;
   }

#if defined(HAVE_DYLIB)
   fill_pathname_basedir(basedir, filter_config, sizeof(basedir));

   plugs = dir_list_new(basedir, EXT_EXECUTABLES, false, false);
   if (!plugs)
   {
      RARCH_ERR("[SoftFilter]: Could not build up string list...\n");
      goto error;
   }
#endif
   if (!append_softfilter_plugs(filt, plugs))
   {
      RARCH_ERR("[SoftFitler]: Failed to append softfilter plugins...\n");
      goto error;
   }

   if (plugs)
      string_list_free(plugs);
   plugs = NULL;

   if (!create_softfilter_graph(filt, in_pixel_format,
            max_width, max_height, cpu_features, threads))
   {
      RARCH_ERR("[SoftFitler]: Failed to create softfilter graph...\n");
      goto error;
   }

   return filt;

error:
   if (plugs)
      string_list_free(plugs);
   plugs = NULL;
   rarch_softfilter_free(filt);
   return NULL;
}
コード例 #8
0
ファイル: input_common.c プロジェクト: AbelFlos/RetroArch
void input_config_autoconfigure_joypad(unsigned index, const char *name, const char *driver)
{
   size_t i;

   if (!g_settings.input.autodetect_enable)
      return;

   // This will be the case if input driver is reinit. No reason to spam autoconfigure messages
   // every time (fine in log).
   bool block_osd_spam = g_settings.input.autoconfigured[index] && name;

   for (i = 0; i < RARCH_BIND_LIST_END; i++)
   {
      g_settings.input.autoconf_binds[index][i].joykey = NO_BTN;
      g_settings.input.autoconf_binds[index][i].joyaxis = AXIS_NONE;
   }
   g_settings.input.autoconfigured[index] = false;

   if (!name)
      return;

   // false = load from both cfg files and internal
   bool internal_only = !*g_settings.input.autoconfig_dir;

#ifdef HAVE_BUILTIN_AUTOCONFIG
   // First internal
   for (i = 0; input_builtin_autoconfs[i]; i++)
   {
      config_file_t *conf = config_file_new_from_string(input_builtin_autoconfs[i]);
      bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam);
      config_file_free(conf);
      if (success)
         break;
   }
#endif
   
   // Now try files
   if (!internal_only)
   {
      struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false);
      if (!list)
         return;
   
      for (i = 0; i < list->size; i++)
      {
         config_file_t *conf = config_file_new(list->elems[i].data);
         if (!conf)
            continue;
         bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam);
         config_file_free(conf);
         if (success)
            break;
      }
      
      string_list_free(list);
   }
}
コード例 #9
0
/*We need to set libretro to the first entry in the cores
 * directory so that it will be saved to the config file
 */
static void find_first_libretro_core(char *first_file,
   size_t size_of_first_file, const char *dir,
   const char * ext)
{
   size_t i;
   bool ret = false;
   struct string_list *list = dir_list_new(dir, ext, false, true, false, false);

   if (!list)
   {
      RARCH_ERR("Couldn't read directory."
            " Cannot infer default libretro core.\n");
      return;
   }

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n",
         dir);
   
   for (i = 0; i < list->size && !ret; i++)
   {
      char fname[PATH_MAX_LENGTH];
      char salamander_name[PATH_MAX_LENGTH];
      const char *libretro_elem = (const char*)list->elems[i].data;

      RARCH_LOG("Checking library: \"%s\".\n", libretro_elem);

      if (!libretro_elem)
         continue;

      fill_pathname_base(fname, libretro_elem, sizeof(fname));

      if (!frontend_driver_get_salamander_basename(
               salamander_name, sizeof(salamander_name)))
         break;

      if (!strncmp(fname, salamander_name, sizeof(fname)))
      {
         if (list->size == (i + 1))
         {
            RARCH_WARN("Entry is RetroArch Salamander itself, "
                  "but is last entry. No choice but to set it.\n");
            strlcpy(first_file, fname, size_of_first_file);
         }

         continue;
      }

      strlcpy(first_file, fname, size_of_first_file);
      RARCH_LOG("First found libretro core is: \"%s\".\n", first_file);
      ret = true;
   }

   dir_list_free(list);
}
コード例 #10
0
void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext)
{
   //We need to set libretro to the first entry in the cores
   //directory so that it will be saved to the config file

   struct string_list *dir_list = dir_list_new(libretro_path, exe_ext, false);

   const char * first_exe;

   if (!dir_list)
   {
      RARCH_ERR("Couldn't read directory.\n");
      RARCH_ERR("Failed to set first entry to libretro path.\n");
      goto end;
   }

   first_exe = dir_list->elems[0].data;

   if(first_exe)
   {
#ifdef _XBOX
      char fname_tmp[PATH_MAX];
      fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));

      if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0)
      {
         RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n");
	 first_exe = dir_list->elems[1].data;
	 fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));

	 if(!first_exe)
	 {
            RARCH_ERR("Unlikely error happened - no second entry - no choice but to set it to RetroArch Salamander\n");
	    first_exe = dir_list->elems[0].data;
	    fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));
	 }
      }

      strlcpy(first_file, fname_tmp, size_of_first_file);
#else
      strlcpy(first_file, first_exe, size_of_first_file);
#endif
      RARCH_LOG("Set first entry in libretro core dir to libretro path: [%s].\n", first_file);
   }

end:
   dir_list_free(dir_list);
}
コード例 #11
0
ファイル: main.c プロジェクト: DukedDroid/RetroArch
static int
find_rom_canonical_name(const char *hash, char *game_name, size_t max_len)
{
	// TODO: Error handling
	size_t i;
	int rv;
	int fd;
	int offs;
	char *dat_path;
	const char *dat_name;
	const char *dat_name_dot;
	struct string_list *files;

	files = dir_list_new("db", "dat", false);
	if (!files) {
		return -1;
	}

	for (i = 0; i < files->size; i++) {
		dat_path = files->elems[i].data;
		dat_name = path_basename(dat_path);

		dat_name_dot = strchr(dat_name, '.');
		if (!dat_name_dot) {
			continue;
		}

		offs = dat_name_dot - dat_name + 1;
		memcpy(game_name, dat_name, offs);

		fd = open(dat_path, O_RDONLY);
		if (fd < 0) {
			continue;
		}

		if (find_hash(fd, hash, game_name + offs, max_len - offs) == 0) {
			rv = 0;
			close(fd);
			goto clean;
		}
		close(fd);
	}
	rv = -1;
clean:
	dir_list_free(files);
	return rv;
}
コード例 #12
0
//We need to set libretro to the first entry in the cores
//directory so that it will be saved to the config file
static void find_first_libretro_core(char *first_file,
   size_t size_of_first_file, const char *dir,
   const char * ext)
{
   struct string_list *list;
   size_t i;
   bool ret = false;

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir);

   list = (struct string_list*)dir_list_new(dir, ext, false);
   if (!list)
   {
      RARCH_ERR("Couldn't read directory. Cannot infer default libretro core.\n");
      return;
   }
   
   for (i = 0; i < list->size && !ret; i++)
   {
      char fname[PATH_MAX];
      const char *libretro_elem = (const char*)list->elems[i].data;

      RARCH_LOG("Checking library: \"%s\".\n", libretro_elem);

      if (!libretro_elem)
         continue;

      fill_pathname_base(fname, libretro_elem, sizeof(fname));

      if (strncmp(fname, SALAMANDER_FILE, sizeof(fname)) == 0)
      {
         if ((i + 1) == list->size)
         {
            RARCH_WARN("Entry is RetroArch Salamander itself, but is last entry. No choice but to set it.\n");
            strlcpy(first_file, fname, size_of_first_file);
         }

         continue;
      }

      strlcpy(first_file, fname, size_of_first_file);
      RARCH_LOG("First found libretro core is: \"%s\".\n", first_file);
      ret = true;
   }

   dir_list_free(list);
}
コード例 #13
0
rarch_dsp_filter_t *rarch_dsp_filter_new(
      const char *filter_config, float sample_rate)
{
   char basedir[PATH_MAX_LENGTH] = {0};
   struct string_list *plugs     = NULL;
   rarch_dsp_filter_t *dsp       = NULL;

   (void)basedir;
   
   dsp = (rarch_dsp_filter_t*)calloc(1, sizeof(*dsp));
   if (!dsp)
      return NULL;

   dsp->conf = config_file_new(filter_config);
   if (!dsp->conf)   /* Did not find config. */
      goto error;

#if !defined(HAVE_FILTERS_BUILTIN) && defined(HAVE_DYLIB)
   fill_pathname_basedir(basedir, filter_config, sizeof(basedir));

   plugs = dir_list_new(basedir, EXT_EXECUTABLES, false, false);
   if (!plugs)
      goto error;
#endif

#if defined(HAVE_DYLIB) || defined(HAVE_FILTERS_BUILTIN)
   if (!append_plugs(dsp, plugs))
      goto error;
#endif

   if (plugs)
      string_list_free(plugs);
   plugs = NULL;

   if (!create_filter_graph(dsp, sample_rate))
      goto error;

   return dsp;

error:
   if (plugs)
      string_list_free(plugs);
   rarch_dsp_filter_free(dsp);
   return NULL;
}
コード例 #14
0
ファイル: driver.c プロジェクト: dturner/RetroArch
static void init_shader_dir(void)
{
   unsigned i;
   if (!*g_settings.video.shader_dir)
      return;

   g_extern.shader_dir.list = dir_list_new(g_settings.video.shader_dir, "cg|cgp|glsl|glslp", false);
   if (!g_extern.shader_dir.list || g_extern.shader_dir.list->size == 0)
   {
      deinit_shader_dir();
      return;
   }

   g_extern.shader_dir.ptr  = 0;
   dir_list_sort(g_extern.shader_dir.list, false);

   for (i = 0; i < g_extern.shader_dir.list->size; i++)
      RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.list->elems[i].data);
}
コード例 #15
0
ファイル: menu_common.c プロジェクト: CatalystG/RetroArch
static bool directory_parse(void *data, const char *path)
{
   filebrowser_t *filebrowser = (filebrowser_t*)data;

   struct string_list *list = dir_list_new(path,
         filebrowser->current_dir.extensions, true);
   if(!list || list->size < 1)
      return false;
   
   dir_list_sort(list, true);

   filebrowser->current_dir.ptr   = 0;
   strlcpy(filebrowser->current_dir.directory_path,
         path, sizeof(filebrowser->current_dir.directory_path));

   if (filebrowser->list)
      dir_list_free(filebrowser->list);

   filebrowser->list = list;

   return true;

}
コード例 #16
0
static void task_database_handler(retro_task_t *task)
{
   const char *name                 = NULL;
   database_info_handle_t  *dbinfo  = NULL;
   database_state_handle_t *dbstate = NULL;
   db_handle_t *db                  = NULL;

   if (!task)
      goto task_finished;

   db      = (db_handle_t*)task->state;

   if (!db)
      goto task_finished;

   if (!db->scan_started)
   {
      db->scan_started = true;

      if (!string_is_empty(db->fullpath))
      {
         if (db->is_directory)
            db->handle = database_info_dir_init(db->fullpath, DATABASE_TYPE_ITERATE, task, db->show_hidden_files);
         else
            db->handle = database_info_file_init(db->fullpath, DATABASE_TYPE_ITERATE, task);
      }

      task_free_title(task);

      if (db->handle)
         db->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
   }

   dbinfo  = db->handle;
   dbstate = &db->state;

   if (!dbinfo || task_get_cancelled(task))
      goto task_finished;

   switch (dbinfo->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (dbstate && !dbstate->list)
         {
            if (!string_is_empty(db->content_database_path))
               dbstate->list        = dir_list_new(
                     db->content_database_path,
                     "rdb", false,
                     db->show_hidden_files,
                     false, false);

            /* If the scan path matches a database path exactly then
             * save time by only processing that database. */
            if (dbstate->list && db->is_directory)
            {
               size_t i;
               char *dirname = NULL;

               if (!string_is_empty(db->fullpath))
                  dirname    = find_last_slash(db->fullpath) + 1;

               if (!string_is_empty(dirname))
               {
                  for (i = 0; i < dbstate->list->size; i++)
                  {
                     const char *data = dbstate->list->elems[i].data;
                     char *dbname     = NULL;
                     bool strmatch    = false;
                     char *dbpath     = strdup(data);

                     path_remove_extension(dbpath);

                     dbname         = find_last_slash(dbpath) + 1;
                     strmatch       = strcasecmp(dbname, dirname) == 0;

                     free(dbpath);

                     if (strmatch)
                     {
                        struct string_list *single_list = string_list_new();
                        string_list_append(single_list,
                              data,
                              dbstate->list->elems[i].attr);
                        dir_list_free(dbstate->list);
                        dbstate->list = single_list;
                        break;
                     }
                  }
               }
            }
         }
         dbinfo->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         name = database_info_get_current_element_name(dbinfo);
         task_database_cleanup_state(dbstate);
         dbstate->list_index  = 0;
         dbstate->entry_index = 0;
         task_database_iterate_start(dbinfo, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (task_database_iterate(db, dbstate, dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_NEXT;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (task_database_iterate_next(dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_START;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            const char *msg = NULL;
            if (db->is_directory)
               msg = msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED);
            else
               msg = msg_hash_to_str(MSG_SCANNING_OF_FILE_FINISHED);
#ifdef RARCH_INTERNAL
            runloop_msg_queue_push(msg, 0, 180, true);
#else
            fprintf(stderr, "msg: %s\n", msg);
#endif
            ui_companion_driver_notify_refresh();
            goto task_finished;
         }
         break;
      default:
      case DATABASE_STATUS_FREE:
      case DATABASE_STATUS_NONE:
         goto task_finished;
   }

   return;
task_finished:
   if (task)
      task_set_finished(task, true);

   if (dbstate)
   {
      if (dbstate->list)
         dir_list_free(dbstate->list);
   }

   if (db)
   {
      if (!string_is_empty(db->playlist_directory))
         free(db->playlist_directory);
      if (!string_is_empty(db->content_database_path))
         free(db->content_database_path);
      if (!string_is_empty(db->fullpath))
         free(db->fullpath);
      if (db->state.buf)
         free(db->state.buf);

      if (db->handle)
         database_info_free(db->handle);
      free(db);
   }

   if (dbinfo)
      free(dbinfo);
}
コード例 #17
0
ファイル: drm_ctx.c プロジェクト: Ezio-PS/RetroArch
static void *gfx_ctx_drm_init(void *video_driver)
{
   int fd, i;
   unsigned monitor_index;
   unsigned gpu_index                   = 0;
   const char *gpu                      = NULL;
   struct string_list *gpu_descriptors  = NULL;
   gfx_ctx_drm_data_t *drm          = (gfx_ctx_drm_data_t*)
      calloc(1, sizeof(gfx_ctx_drm_data_t));

   if (!drm)
      return NULL;

   gpu_descriptors = dir_list_new("/dev/dri", NULL, false, true, false, false);

nextgpu:
   free_drm_resources(drm);

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   drm->drm    = filestream_open(gpu, RFILE_MODE_READ_WRITE, -1);
   if (!drm->drm)
   {
      RARCH_WARN("[KMS]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   fd = filestream_get_fd(drm->drm);

   if (!drm_get_resources(fd))
      goto nextgpu;

   if (!drm_get_connector(fd))
      goto nextgpu;

   if (!drm_get_encoder(fd))
      goto nextgpu;

   drm_setup(fd);

   /* First mode is assumed to be the "optimal" 
    * one for get_video_size() purposes. */
   drm->fb_width    = g_drm_connector->modes[0].hdisplay;
   drm->fb_height   = g_drm_connector->modes[0].vdisplay;

   g_gbm_dev        = gbm_create_device(fd);

   if (!g_gbm_dev)
   {
      RARCH_WARN("[KMS]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);

   /* Setup the flip handler. */
   g_drm_fds.fd                   = fd;
   g_drm_fds.events               = POLLIN;
   g_drm_evctx.version            = DRM_EVENT_CONTEXT_VERSION;
   g_drm_evctx.page_flip_handler  = drm_flip_handler;

   g_drm_fd                       = fd;

   return drm;

error:
   dir_list_free(gpu_descriptors);

   gfx_ctx_drm_destroy_resources(drm);

   if (drm)
      free(drm);

   return NULL;
}
コード例 #18
0
ファイル: input_autodetect.c プロジェクト: Joonie86/RetroArch
static bool input_autoconfigure_joypad_from_conf_dir(
      autoconfig_params_t *params)
{
   size_t i;
   char path[PATH_MAX_LENGTH];
   int ret                    = 0;
   int index                  = -1;
   int current_best           = 0;
   config_file_t *conf        = NULL;
   struct string_list *list   = NULL;
   settings_t *settings       = config_get_ptr();

   if (!settings)
      return false;

   fill_pathname_join(path,
         settings->input.autoconfig_dir,
         settings->input.joypad_driver,
         sizeof(path));
   list = dir_list_new(path, "cfg", false, false);

   if (!list || !list->size)
      list = dir_list_new(settings->input.autoconfig_dir, "cfg", false, false);

   if(!list)
      return false;

   RARCH_LOG("Autodetect: %d profiles found\n", list->size);

   for (i = 0; i < list->size; i++)
   {
      conf = config_file_new(list->elems[i].data);
      ret = input_try_autoconfigure_joypad_from_conf(conf, params);
      if(ret >= current_best)
      {
         index = i;
         current_best = ret;
      }
      config_file_free(conf);
   }

   if(index >= 0 && current_best > 0)
   {
      conf = config_file_new(list->elems[index].data);
      RARCH_LOG("Autodetect: selected configuration: %s\n", conf->path);
      input_autoconfigure_joypad_add(conf, params);
      config_file_free(conf);
      ret = 1;
   }
   else
   {
      char msg[PATH_MAX_LENGTH];

      RARCH_LOG("Autodetect: no profiles found for %s (%d/%d)", params->name, params->vid, params->pid);
      snprintf(msg, sizeof(msg), "%s (%ld/%ld) not configured", params->name, (long)params->vid, (long)params->pid);
      rarch_main_msg_queue_push(msg, 0, 60, false);
      ret = 0;
   }
   string_list_free(list);

   if (ret == 0)
      return false;
   return true;
}
コード例 #19
0
static int zarch_zui_render_lay_root_load(zui_t *zui,
      struct zui_tabbed *tabbed)
{
   char parent_dir[PATH_MAX_LENGTH];
   settings_t           *settings   = config_get_ptr();
   core_info_list_t           *list = NULL;

   parent_dir[0] = '\0';

   if (zarch_zui_tab(zui, tabbed, "Load", 1))
   {
      unsigned cwd_offset;

      if (!zui->load_cwd)
         zui->load_cwd = strdup(settings->directory.menu_content);

      if (!zui->load_dlist)
      {
         core_info_t *core_info = NULL;
         core_info_get_current_core(&core_info);

         zui->load_dlist = dir_list_new(zui->load_cwd,
               core_info->supported_extensions, true, true, false, true);
         dir_list_sort(zui->load_dlist, true);
         zui->load_dlist_first  = 0;
      }

      cwd_offset = MIN(strlen(zui->load_cwd), 60);

      zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15,
            tabbed->tabline_size + 5 + 41,
            &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);

      if (zarch_zui_button(zui, zui->width - 290 - 129,
               tabbed->tabline_size + 5, "Home"))
         zarch_zui_render_lay_root_load_free(zui);

      if (zui->load_dlist)
      {
         fill_pathname_parent_dir(parent_dir,
               zui->load_cwd, sizeof(parent_dir));
         if (!string_is_empty(parent_dir) &&
               zarch_zui_list_item(zui, tabbed, 0,
                  tabbed->tabline_size + 73, " ..", 0, NULL, false /* TODO/FIXME */))
         {
            zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
         }
         else
         {
            static int gamepad_index = 0;
            unsigned size = zui->load_dlist->size;
            unsigned i, j = 1;
            unsigned skip = 0;

            for (i = 0; i < size; ++i)
            {
               const char *basename = 
                  path_basename(zui->load_dlist->elems[i].data);
               if (basename[0] != '.')
                  break;
               skip++;
            }

            if (zarch_zui_gamepad_input(zui, &gamepad_index,
                     &zui->load_dlist_first, skip))
               zui->load_dlist_first = gamepad_index;

            for (i = skip + zui->load_dlist_first; i < size; ++i)
            {
               char label[PATH_MAX_LENGTH];
               const char        *path     = NULL;
               const char        *basename = NULL;

               if (j > 10)
                  break;

               label[0] = '\0';

               path     = zui->load_dlist->elems[i].data;
               basename = path_basename(path);

               *label = 0;
               strncat(label, "  ", sizeof(label)-1);
               strncat(label, basename, sizeof(label)-1);

               if (path_is_directory(path))
                  strncat(label, "/", sizeof(label)-1);

               if (zarch_zui_list_item(zui, tabbed, 0,
                        tabbed->tabline_size + 73 + j * ZUI_ITEM_SIZE_PX,
                        label, i, NULL, gamepad_index == (signed)(i-skip)))
               {
                  if (path_is_directory(path))
                  {
                     zarch_zui_render_lay_root_load_set_new_path(zui, path);
                     break;
                  }

                  zui->pick_cores     = NULL;
                  zui->pick_supported = 0;
                  strlcpy(zui->pick_content,
                        path, sizeof(zui->pick_content));

                  core_info_get_list(&list);

                  core_info_list_get_supported_cores(list, path,
                        &zui->pick_cores, &zui->pick_supported);
                  zarch_layout = LAY_PICK_CORE;
                  break;
               }
               j++;
            }
         }
      }
   }
   else if (zui->load_dlist)
   {
      dir_list_free(zui->load_dlist);
      zui->load_dlist = NULL;
   }

   return 0;
}
コード例 #20
0
ファイル: input_common.c プロジェクト: lifning/RetroArch
void input_config_autoconfigure_joypad(unsigned index, const char *name, const char *driver)
{
   if (!g_settings.input.autodetect_enable)
      return;

   // This will be the case if input driver is reinit. No reason to spam autoconfigure messages
   // every time (fine in log).
   bool block_osd_spam = g_settings.input.autoconfigured[index] && name;

   for (unsigned i = 0; i < RARCH_BIND_LIST_END; i++)
   {
      g_settings.input.autoconf_binds[index][i].joykey = NO_BTN;
      g_settings.input.autoconf_binds[index][i].joyaxis = AXIS_NONE;
   }
   g_settings.input.autoconfigured[index] = false;

   if (!name)
      return;

   if (!*g_settings.input.autoconfig_dir)
      return;

   struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false);
   if (!list)
      return;

   char ident[1024];
   char input_driver[1024];
   for (size_t i = 0; i < list->size; i++)
   {
      *ident = *input_driver = '\0';

      config_file_t *conf = config_file_new(list->elems[i].data);
      if (!conf)
         continue;

      config_get_array(conf, "input_device", ident, sizeof(ident));
      config_get_array(conf, "input_driver", input_driver, sizeof(input_driver));

      if (!strcmp(ident, name) && !strcmp(driver, input_driver))
      {
         g_settings.input.autoconfigured[index] = true;
         input_autoconfigure_joypad_conf(conf, g_settings.input.autoconf_binds[index]);

         char msg[512];
         snprintf(msg, sizeof(msg), "Joypad port #%u (%s) configured.",
               index, name);

         if (!block_osd_spam)
            msg_queue_push(g_extern.msg_queue, msg, 0, 60);
         RARCH_LOG("%s\n", msg);

         config_file_free(conf);
         break;
      }
      else
         config_file_free(conf);
   }

   string_list_free(list);
}
コード例 #21
0
ファイル: core_info.c プロジェクト: budney93/RetroArch
core_info_list_t *core_info_list_new(const char *modules_path)
{
   struct string_list *contents = dir_list_new(modules_path, EXT_EXECUTABLES, false);
   size_t all_ext_len, i;

   core_info_t *core_info = NULL;
   core_info_list_t *core_info_list = NULL;

   if (!contents)
      return NULL;

   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      char info_path_base[PATH_MAX], info_path[PATH_MAX];
      core_info[i].path = strdup(contents->elems[i].data);

      if (!core_info[i].path)
         break;

      fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base));
      path_remove_extension(info_path_base);

#if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE)
      char *substr = strrchr(info_path_base, '_');
      if (substr)
         *substr = '\0';
#endif

      strlcat(info_path_base, ".info", sizeof(info_path_base));

      fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path,
            info_path_base, sizeof(info_path));

      core_info[i].data = config_file_new(info_path);

      if (core_info[i].data)
      {
         config_get_string(core_info[i].data, "display_name", &core_info[i].display_name);
         if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) &&
               core_info[i].supported_extensions)
            core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|");

         if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) &&
               core_info[i].authors)
            core_info[i].authors_list = string_split(core_info[i].authors, "|");
      }

      if (!core_info[i].display_name)
         core_info[i].display_name = strdup(path_basename(core_info[i].path));
   }

   all_ext_len = 0;
   for (i = 0; i < core_info_list->count; i++)
   {
      all_ext_len += core_info_list->list[i].supported_extensions ?
         (strlen(core_info_list->list[i].supported_extensions) + 2) : 0;
   }

   if (all_ext_len)
   {
      all_ext_len += strlen("|zip");
      core_info_list->all_ext = (char*)calloc(1, all_ext_len);
   }

   if (core_info_list->all_ext)
   {
      for (i = 0; i < core_info_list->count; i++)
      {
         if (core_info_list->list[i].supported_extensions)
         {
            strlcat(core_info_list->all_ext, core_info_list->list[i].supported_extensions, all_ext_len);
            strlcat(core_info_list->all_ext, "|", all_ext_len);
         }
      }
      strlcat(core_info_list->all_ext, "|zip", all_ext_len);
   }

   dir_list_free(contents);
   return core_info_list;

error:
   if (contents)
      dir_list_free(contents);
   core_info_list_free(core_info_list);
   return NULL;
}
コード例 #22
0
ファイル: menu_entries.c プロジェクト: Miinky-Games/RetroArch
int menu_entries_parse_list(
      file_list_t *list, file_list_t *menu_list,
      const char *dir, const char *label, unsigned type,
      unsigned default_type_plain, const char *exts,
      rarch_setting_t *setting)
{
   size_t i, list_size;
   bool path_is_compressed, push_dir;
   int                   device = 0;
   struct string_list *str_list = NULL;
   settings_t *settings         = config_get_ptr();
   global_t *global             = global_get_ptr();

   (void)device;

   if (!list || !menu_list)
      return -1;

   menu_list_clear(list);

   if (!*dir)
   {
      menu_entries_parse_drive_list(list);
      menu_driver_populate_entries(dir, label, type);
      return 0;
   }

#if defined(GEKKO) && defined(HW_RVL)
   slock_lock(gx_device_mutex);
   device = gx_get_device_from_path(dir);

   if (device != -1 && !gx_devices[device].mounted &&
         gx_devices[device].interface->isInserted())
      fatMountSimple(gx_devices[device].name, gx_devices[device].interface);

   slock_unlock(gx_device_mutex);
#endif

   path_is_compressed = path_is_compressed_file(dir);
   push_dir           = (setting && setting->browser_selection_type == ST_DIR);

   if (path_is_compressed)
      str_list = compressed_file_list_new(dir,exts);
   else
      str_list = dir_list_new(dir,
            settings->menu.navigation.browser.filter.supported_extensions_enable 
            ? exts : NULL, true);

   if (push_dir)
      menu_list_push(list, "<Use this directory>", "",
            MENU_FILE_USE_DIRECTORY, 0);

   if (!str_list)
      return -1;

   dir_list_sort(str_list, true);


   list_size = str_list->size;
   for (i = 0; i < str_list->size; i++)
   {
      bool is_dir;
      const char *path = NULL;
      menu_file_type_t file_type = MENU_FILE_NONE;

      switch (str_list->elems[i].attr.i)
      {
         case RARCH_DIRECTORY:
            file_type = MENU_FILE_DIRECTORY;
            break;
         case RARCH_COMPRESSED_ARCHIVE:
            file_type = MENU_FILE_CARCHIVE;
            break;
         case RARCH_COMPRESSED_FILE_IN_ARCHIVE:
            file_type = MENU_FILE_IN_CARCHIVE;
            break;
         case RARCH_PLAIN_FILE:
         default:
            if (!strcmp(label, "detect_core_list"))
            {
               if (path_is_compressed_file(str_list->elems[i].data))
               {
                  /* in case of deferred_core_list we have to interpret
                   * every archive as an archive to disallow instant loading
                   */
                  file_type = MENU_FILE_CARCHIVE;
                  break;
               }
            }
            file_type = (menu_file_type_t)default_type_plain;
            break;
      }

      is_dir = (file_type == MENU_FILE_DIRECTORY);

      if (push_dir && !is_dir)
         continue;

      /* Need to preserve slash first time. */
      path = str_list->elems[i].data;

      if (*dir && !path_is_compressed)
         path = path_basename(path);


#ifdef HAVE_LIBRETRO_MANAGEMENT
#ifdef RARCH_CONSOLE
      if (!strcmp(label, "core_list") && (is_dir ||
               strcasecmp(path, SALAMANDER_FILE) == 0))
         continue;
#endif
#endif

      /* Push type further down in the chain.
       * Needed for shader manager currently. */
      if (!strcmp(label, "core_list"))
      {
         /* Compressed cores are unsupported */
         if (file_type == MENU_FILE_CARCHIVE)
            continue;

         menu_list_push(list, path, "",
               is_dir ? MENU_FILE_DIRECTORY : MENU_FILE_CORE, 0);
      }
      else
      menu_list_push(list, path, "",
            file_type, 0);
   }

   string_list_free(str_list);

   if (!strcmp(label, "core_list"))
   {
      driver_t *driver = driver_get_ptr();

      menu_list_get_last_stack(driver->menu->menu_list, &dir, NULL, NULL);
      list_size = file_list_get_size(list);

      for (i = 0; i < list_size; i++)
      {
         char core_path[PATH_MAX_LENGTH], display_name[PATH_MAX_LENGTH];
         const char *path = NULL;

         menu_list_get_at_offset(list, i, &path, NULL, &type);

         if (type != MENU_FILE_CORE)
            continue;

         fill_pathname_join(core_path, dir, path, sizeof(core_path));

         if (global->core_info &&
               core_info_list_get_display_name(global->core_info,
                  core_path, display_name, sizeof(display_name)))
            menu_list_set_alt_at_offset(list, i, display_name);
      }
      menu_list_sort_on_alt(list);
   }

   menu_list_populate_generic(list, dir, label, type);

   return 0;
}
コード例 #23
0
ファイル: lakka.c プロジェクト: Mbcpro/RetroArch
static void lakka_init_items(int i, menu_category_t *category, core_info_t *info, const char* path)
{
   int num_items, j, n, k;
   struct string_list *list = (struct string_list*)dir_list_new(path, info->supported_extensions, true);

   dir_list_sort(list, true);

   num_items = list ? list->size : 0;

   for (j = 0; j < num_items; j++)
   {
      if (list->elems[j].attr.b) // is a directory
         lakka_init_items(i, category, info, list->elems[j].data);
      else
      {
         menu_item_t *item;

         n = category->num_items;

         category->num_items++;
         category->items = (menu_item_t*)realloc(category->items, category->num_items * sizeof(menu_item_t));
         item = (menu_item_t*)&category->items[n];

         strlcpy(item->name, path_basename(list->elems[j].data), sizeof(item->name));
         strlcpy(item->rom, list->elems[j].data, sizeof(item->rom));
         item->alpha          = i != menu_active_category ? 0 : n ? 0.5 : 1;
         item->zoom           = n ? I_PASSIVE_ZOOM : I_ACTIVE_ZOOM;
         item->y              = n ? VSPACING*(3+n) : VSPACING*2.4;
         item->active_subitem = 0;
         item->num_subitems   = 5;
         item->subitems       = (menu_subitem_t*)calloc(item->num_subitems, sizeof(menu_subitem_t));

         for (k = 0; k < item->num_subitems; k++)
         {
            menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[k];

            if (!subitem)
               continue;

            switch (k)
            {
               case 0:
                  strlcpy(subitem->name, "Run", sizeof(subitem->name));
                  break;
               case 1:
                  strlcpy(subitem->name, "Save State", sizeof(subitem->name));
                  break;
               case 2:
                  strlcpy(subitem->name, "Load State", sizeof(subitem->name));
                  break;
               case 3:
                  strlcpy(subitem->name, "Take Screenshot", sizeof(subitem->name));
                  break;
               case 4:
                  strlcpy(subitem->name, "Reset", sizeof(subitem->name));
                  break;
            }
            subitem->alpha = 0;
            subitem->zoom = k ? I_PASSIVE_ZOOM : I_ACTIVE_ZOOM;
            subitem->y = k ? VSPACING * (3+k) : VSPACING * 2.4;

            if (font_driver)
               font_driver->render_msg(font, subitem->name, &subitem->out);
         }
      }
   }
}
コード例 #24
0
ファイル: core_info.c プロジェクト: DSkywalk/RetroArch
void core_info_get_name(const char *path, char *s, size_t len,
      const char *path_info, const char *dir_cores,
      const char *exts, bool dir_show_hidden_files,
      bool get_display_name)
{
   size_t i;
   const char       *path_basedir   = !string_is_empty(path_info) ?
      path_info : dir_cores;
   struct string_list *contents     = dir_list_new(
         dir_cores, exts, false, dir_show_hidden_files, false, false);
   const char *core_path_basename   = path_basename(path);

   if (!contents)
      return;

   for (i = 0; i < contents->size; i++)
   {
      size_t path_size                = PATH_MAX_LENGTH * sizeof(char);
      char *info_path                 = NULL;
      config_file_t *conf             = NULL;
      char *new_core_name             = NULL;
      const char *current_path        = contents->elems[i].data;

      if (!string_is_equal(path_basename(current_path), core_path_basename))
         continue;

      info_path                       = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
      info_path[0]                    = '\0';

      if (!core_info_list_iterate(info_path,
               path_size, path_basedir, contents, i)
            && path_is_valid(info_path))
      {
         free(info_path);
         continue;
      }

      conf                            = config_file_new(info_path);

      if (!conf)
      {
         free(info_path);
         continue;
      }

      if (config_get_string(conf, get_display_name ? "display_name" : "corename",
            &new_core_name))
      {
         strlcpy(s, new_core_name, len);
         free(new_core_name);
      }

      config_file_free(conf);
      free(info_path);
      break;
   }

   if (contents)
      dir_list_free(contents);
   contents = NULL;
}
コード例 #25
0
void input_config_autoconfigure_joypad(unsigned idx,
      const char *name, int32_t vid, int32_t pid,
      const char *drv)
{
   size_t i;
   bool internal_only, block_osd_spam;
   struct string_list *list = NULL;

   if (!g_settings.input.autodetect_enable)
      return;

   /* This will be the case if input driver is reinit.
    * No reason to spam autoconfigure messages
    * every time (fine in log). */
   block_osd_spam = g_settings.input.autoconfigured[idx] && name;

   for (i = 0; i < RARCH_BIND_LIST_END; i++)
   {
      g_settings.input.autoconf_binds[idx][i].joykey = NO_BTN;
      g_settings.input.autoconf_binds[idx][i].joyaxis = AXIS_NONE;
      g_settings.input.autoconf_binds[idx][i].joykey_label[0] = '\0';
      g_settings.input.autoconf_binds[idx][i].joyaxis_label[0] = '\0';
   }
   g_settings.input.autoconfigured[idx] = false;

   if (!name)
      return;

   /* if false, load from both cfg files and internal */
   internal_only = !*g_settings.input.autoconfig_dir;

#if defined(HAVE_BUILTIN_AUTOCONFIG)
   /* First internal */
   for (i = 0; input_builtin_autoconfs[i]; i++)
   {
      config_file_t *conf = (config_file_t*)
         config_file_new_from_string(input_builtin_autoconfs[i]);
      bool success = input_try_autoconfigure_joypad_from_conf(conf,
            idx, name, drv, vid, pid, block_osd_spam);

      config_file_free(conf);
      if (success)
         break;
   }
#endif

   if (internal_only)
      return;

   /* Now try files */
   list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false);

   if (!list)
      return;

   for (i = 0; i < list->size; i++)
   {
      bool success;
      config_file_t *conf = config_file_new(list->elems[i].data);
      if (!conf)
         continue;

      success = input_try_autoconfigure_joypad_from_conf(conf,
            idx, name, drv, vid, pid, block_osd_spam);
      config_file_free(conf);
      if (success)
         break;
   }

   string_list_free(list);
}
コード例 #26
0
ファイル: core_info.c プロジェクト: FriskyBandit/RetroArch
core_info_list_t *core_info_list_new(const char *modules_path)
{
   size_t i;
   core_info_t *core_info = NULL;
   core_info_list_t *core_info_list = NULL;
   struct string_list *contents = (struct string_list*)dir_list_new(modules_path, EXT_EXECUTABLES, false);
   if (!contents)
      return NULL;

   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      char info_path_base[PATH_MAX], info_path[PATH_MAX];
      core_info[i].path = strdup(contents->elems[i].data);

      if (!core_info[i].path)
         break;

      fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base));
      path_remove_extension(info_path_base);

#if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE)
      char *substr = strrchr(info_path_base, '_');
      if (substr)
         *substr = '\0';
#endif

      strlcat(info_path_base, ".info", sizeof(info_path_base));

      fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path,
            info_path_base, sizeof(info_path));

      core_info[i].data = config_file_new(info_path);

      if (core_info[i].data)
      {
         unsigned count = 0;
         config_get_string(core_info[i].data, "display_name", &core_info[i].display_name);
         config_get_string(core_info[i].data, "systemname", &core_info[i].systemname);
         config_get_uint(core_info[i].data, "firmware_count", &count);
         core_info[i].firmware_count = count;
         if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) &&
               core_info[i].supported_extensions)
            core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|");

         if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) &&
               core_info[i].authors)
            core_info[i].authors_list = string_split(core_info[i].authors, "|");

         if (config_get_string(core_info[i].data, "permissions", &core_info[i].permissions) &&
               core_info[i].permissions)
            core_info[i].permissions_list = string_split(core_info[i].permissions, "|");
         if (config_get_string(core_info[i].data, "notes", &core_info[i].notes) &&
               core_info[i].notes)
            core_info[i].note_list = string_split(core_info[i].notes, "|");
      }

      if (!core_info[i].display_name)
         core_info[i].display_name = strdup(path_basename(core_info[i].path));
   }

   core_info_list_resolve_all_extensions(core_info_list);
   core_info_list_resolve_all_firmware(core_info_list);

   dir_list_free(contents);
   return core_info_list;

error:
   if (contents)
      dir_list_free(contents);
   core_info_list_free(core_info_list);
   return NULL;
}
コード例 #27
0
struct string_list *dir_list_new_special(const char *input_dir,
      enum dir_list_type type, const char *filter)
{
   char ext_shaders[PATH_MAX_LENGTH];
   char ext_name[PATH_MAX_LENGTH];
   const char *dir   = NULL;
   const char *exts  = NULL;
   bool include_dirs = false;

   settings_t *settings = config_get_ptr();

   (void)input_dir;
   (void)settings;
   ext_shaders[0] = '\0';

   switch (type)
   {
      case DIR_LIST_AUTOCONFIG:
         dir  = input_dir;
         exts = filter;
         break;
      case DIR_LIST_CORES:
         dir  = settings->directory.libretro;

         if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name)))
            return NULL;

         exts = ext_name;
         break;
      case DIR_LIST_CORE_INFO:
         {
            core_info_list_t *list = NULL;
            core_info_get_list(&list);

            dir  = input_dir;
            exts = list->all_ext;
         }
         break;
      case DIR_LIST_SHADERS:
         dir  = settings->directory.video_shader;
#ifdef HAVE_CG
         strlcat(ext_shaders, "cg|cgp", sizeof(ext_shaders));
#endif
#ifdef HAVE_GLSL
         strlcat(ext_shaders, "glsl|glslp", sizeof(ext_shaders));
#endif
#ifdef HAVE_VULKAN
         strlcat(ext_shaders, "slang|slangp", sizeof(ext_shaders));
#endif
         exts = ext_shaders;
         break;
      case DIR_LIST_COLLECTIONS:
         dir  = settings->directory.playlist;
         exts = "lpl";
         break;
      case DIR_LIST_DATABASES:
         dir  = settings->path.content_database;
         exts = "rdb";
         break;
      case DIR_LIST_PLAIN:
         dir  = input_dir;
         exts = filter;
         break;
      case DIR_LIST_NONE:
      default:
         return NULL;
   }

   return dir_list_new(dir, exts, include_dirs, type == DIR_LIST_CORE_INFO);
}
コード例 #28
0
ファイル: zarch.c プロジェクト: bronnel/RetroArch
static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
{
   char parent_dir[PATH_MAX_LENGTH];
   settings_t *settings = config_get_ptr();
   global_t     *global = global_get_ptr();

   if (zarch_zui_tab(zui, tabbed, "Load", 1))
   {
      unsigned cwd_offset;

      if (!zui->load_cwd)
         zui->load_cwd = strdup(settings->menu_content_directory);

      if (!zui->load_dlist)
      {
         zui->load_dlist = dir_list_new(zui->load_cwd, global->core_info.current->supported_extensions, true, true);
         dir_list_sort(zui->load_dlist, true);
         zui->load_dlist_first  = 0;
      }

      cwd_offset = min(strlen(zui->load_cwd), 60);

      zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15, tabbed->tabline_size + 5 + 41, &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);

      if (zarch_zui_button(zui, zui->width - 290 - 129, tabbed->tabline_size + 5, "Home"))
         zarch_zui_render_lay_root_load_free(zui);

      if (zui->load_dlist)
      {
         fill_pathname_parent_dir(parent_dir, zui->load_cwd, sizeof(parent_dir));
         if (parent_dir[0] != '\0' &&
               zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73, " ..", 0, NULL /* TODO/FIXME */))
         {
            zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
         }
         else
         {
            unsigned size = zui->load_dlist->size;
            unsigned i, j = 1;
            unsigned skip = 0;

            for (i = 0; i < size; ++i)
            {
               const char *basename = path_basename(zui->load_dlist->elems[i].data);
               if (basename[0] != '.')
                  break;
               skip++;
            }

            zui->load_dlist_first += zui->mouse.wheel;

            if (zui->load_dlist_first < 0)
               zui->load_dlist_first = 0;
            else if (zui->load_dlist_first > size - 5)
               zui->load_dlist_first = size - 5;

            zui->load_dlist_first = min(max(zui->load_dlist_first, 0), size - 5 - skip);

            for (i = skip + zui->load_dlist_first; i < size; ++i)
            {
               char label[PATH_MAX_LENGTH];
               const char *path     = NULL;
               const char *basename = NULL;

               if (j > 10)
                  break;

               path = zui->load_dlist->elems[i].data;
               basename = path_basename(path);

               *label = 0;
               strncat(label, "  ", sizeof(label)-1);
               strncat(label, basename, sizeof(label)-1);

               if (path_is_directory(path))
                  strncat(label, "/", sizeof(label)-1);

               if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73 + j * 54,
                        label, i, NULL))
               {
                  if (path_is_directory(path))
                  {
                     zarch_zui_render_lay_root_load_set_new_path(zui, path);
                     break;
                  }

                  zui->pick_cores     = NULL;
                  zui->pick_supported = 0;
                  strncpy(zui->pick_content, path, sizeof(zui->pick_content)-1);
                  core_info_list_get_supported_cores(global->core_info.list, path,
                        &zui->pick_cores, &zui->pick_supported);
                  layout = LAY_PICK_CORE;
                  break;
               }
               j++;
            }
         }
      }
   }
   else if (zui->load_dlist)
   {
      dir_list_free(zui->load_dlist);
      zui->load_dlist = NULL;
   }

   return 0;
}
コード例 #29
0
ファイル: nk_wnd_file_picker.c プロジェクト: Alcaro/RetroArch
bool nk_wnd_file_picker(nk_menu_handle_t *nk, char* title, char* in, char* out, char* filter)
{
   struct nk_panel layout;
   struct nk_context                 *ctx = &nk->ctx;
   const int id                      = NK_WND_FILE_PICKER;
   int i                             = 0;
   static file_list_t *drives        = NULL;
   static struct string_list *files  = NULL;
   settings_t *settings              = config_get_ptr();
   bool ret                          = false;

   if (!drives)
   {
      drives = (file_list_t*)calloc(1, sizeof(file_list_t));
      frontend_driver_parse_drive_list(drives, false);
   }

   if (!string_is_empty(in) && string_is_empty(path))
   {
      strlcpy(path, in, sizeof(path));
      files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false);
   }

   if (!assets_loaded)
      load_icons(nk);

   if (nk_begin(ctx, title, nk_rect(10, 10, 500, 400),
         NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_MOVABLE|
         NK_WINDOW_BORDER))
   {
      nk_layout_row_dynamic(ctx, 30, 4);

      if (drives->size == 0)
      {
         if(nk_button_image_label(ctx, icons.disk, "/", 
            NK_TEXT_CENTERED))
         {
            fill_pathname_join(path, "/",
                  "", sizeof(path));
            files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false);
         }
      }
      else
      {
         for (i = 0; i < drives->size; i++)
         {
            if(nk_button_image_label(ctx, icons.disk, drives->list[i].path, 
               NK_TEXT_CENTERED))
            {
               fill_pathname_join(path, drives->list[i].path,
                     "", sizeof(path));
               files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false);
            }
         }
      }

      nk_layout_row_dynamic(ctx, 30, 1);
      if (files)
      {
         for (i = 0; i < files->size; i++)
         {
            if (nk_button_image_label(ctx, path_is_directory(files->elems[i].data) ? 
               icons.folder : icons.file, path_basename(files->elems[i].data), 
               NK_TEXT_RIGHT))
            {
               strlcpy (path, files->elems[i].data, sizeof(path));
               if (path_is_directory (path))
                  files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false);
            }
         }
      }
      nk_layout_row_dynamic(ctx, 30, 1);
      {
         if (nk_button_text(ctx, "OK", 2))
         {
            ret = true;
            strlcpy(out, path, sizeof(path));
            nk->window[NK_WND_FILE_PICKER].open = false;
            path[0] = '\0';
         }
      }
   }

   /* sort the dir list with directories first */
   dir_list_sort(files, true);

   /* copy the path variable to out*/

   /* save position and size to restore after context reset */
   nk_wnd_set_state(nk, id, nk_window_get_position(ctx), nk_window_get_size(ctx));
   nk_end(ctx);

   return ret;
}
コード例 #30
0
ファイル: drm_egl_ctx.c プロジェクト: maddox/RetroArch
static bool gfx_ctx_drm_egl_init(void *data)
{
   const char *gpu;
   int i;
   unsigned monitor_index;
   unsigned gpu_index = 0;
   unsigned monitor = max(g_settings.video.monitor_index, 1);
   struct string_list *gpu_descriptors  = NULL;

   gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*)calloc(1, sizeof(gfx_ctx_drm_egl_data_t));

   if (!drm)
      return NULL;

   drm->g_drm_fd = -1;
   gpu_descriptors = (struct string_list*)dir_list_new("/dev/dri", NULL, false);

nextgpu:
   free_drm_resources(drm);

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   drm->g_drm_fd = open(gpu, O_RDWR);
   if (drm->g_drm_fd < 0)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   drm->g_resources = drmModeGetResources(drm->g_drm_fd);
   if (!drm->g_resources)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device resources.\n");
      goto nextgpu;
   }

   /* Enumerate all connectors. */
   monitor_index = 0;
   RARCH_LOG("[KMS/EGL]: Found %d connectors.\n",
         drm->g_resources->count_connectors);

   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drmModeConnectorPtr conn = drmModeGetConnector(
            drm->g_drm_fd, drm->g_resources->connectors[i]);

      if (conn)
      {
         bool connected = conn->connection == DRM_MODE_CONNECTED;
         RARCH_LOG("[KMS/EGL]: Connector %d connected: %s\n", i, connected ? "yes" : "no");
         RARCH_LOG("[KMS/EGL]: Connector %d has %d modes.\n", i, conn->count_modes);
         if (connected && conn->count_modes > 0)
         {
            monitor_index++;
            RARCH_LOG("[KMS/EGL]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index);
         }
         drmModeFreeConnector(conn);
      }
   }

   monitor_index = 0;
   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drm->g_connector = drmModeGetConnector(drm->g_drm_fd,
            drm->g_resources->connectors[i]);

      if (!drm->g_connector)
         continue;
      if (drm->g_connector->connection == DRM_MODE_CONNECTED
            && drm->g_connector->count_modes > 0)
      {
         monitor_index++;
         if (monitor_index == monitor)
            break;
      }

      drmModeFreeConnector(drm->g_connector);
      drm->g_connector = NULL;
   }

   if (!drm->g_connector)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device connector.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_resources->count_encoders; i++)
   {
      drm->g_encoder = drmModeGetEncoder(drm->g_drm_fd,
            drm->g_resources->encoders[i]);

      if (!drm->g_encoder)
         continue;
      if (drm->g_encoder->encoder_id == drm->g_connector->encoder_id)
         break;

      drmModeFreeEncoder(drm->g_encoder);
      drm->g_encoder = NULL;
   }

   if (!drm->g_encoder)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_connector->count_modes; i++)
   {
      RARCH_LOG("[KMS/EGL]: Mode %d: (%s) %d x %d, %u Hz\n",
            i,
            drm->g_connector->modes[i].name,
            drm->g_connector->modes[i].hdisplay,
            drm->g_connector->modes[i].vdisplay,
            drm->g_connector->modes[i].vrefresh);
   }

   drm->g_crtc_id   = drm->g_encoder->crtc_id;
   drm->g_orig_crtc = drmModeGetCrtc(drm->g_drm_fd, drm->g_crtc_id);
   if (!drm->g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   drm->g_connector_id = drm->g_connector->connector_id;

   /* First mode is assumed to be the "optimal" 
    * one for get_video_size() purposes. */
   drm->g_fb_width  = drm->g_connector->modes[0].hdisplay;
   drm->g_fb_height = drm->g_connector->modes[0].vdisplay;

   drm->g_gbm_dev = gbm_create_device(drm->g_drm_fd);

   if (!drm->g_gbm_dev)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);

   driver.video_context_data = drm;

   return true;

error:
   dir_list_free(gpu_descriptors);

   gfx_ctx_drm_egl_destroy_resources(drm);

   if (drm)
      free(drm);

   return false;
}