mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 21:32:45 +00:00
Merge pull request #320 from libretro/createconfig
Create default config
This commit is contained in:
commit
1d60ea18c2
@ -16,8 +16,21 @@ retroarch-joyconfig \- Tool to configure joypad bindings for \fBretroarch\fR.
|
||||
It reads in necessary joypad bindings for a certain player and joypad.
|
||||
|
||||
.SH "EXAMPLE COMMANDLINES"
|
||||
|
||||
.TP
|
||||
\fBConfigure joypad for player 1, using first joypad. Configuration is dumped to a file.\fR
|
||||
retroarch-joyconfig -p 1 -j 0 -o inputconfig.cfg
|
||||
|
||||
.TP
|
||||
\fBConfigure joypad for player 1, using first joypad. Update retroarch.cfg directly.\fR
|
||||
retroarch-joyconfig -p 1 -j 0 -i retroarch.cfg -o retroarch.cfg
|
||||
|
||||
.TP
|
||||
\fBConfigure joypad for player 1, using first joypad. Configuration is dumped to stdout.\fR
|
||||
retroarch-joyconfig -p 1 -j 0
|
||||
|
||||
.TP
|
||||
\fBCreate an autoconfig file using first joypad.\fR
|
||||
retroarch-joyconfig -j 0 -a ~/.config/retroarch/autoconfig/pad.cfg
|
||||
|
||||
.SH "GENERAL OPTIONS"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
.SH NAME
|
||||
|
||||
retroarch \- A simple frontend for the libretro API.
|
||||
retroarch \- The reference frontend for the libretro API.
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
@ -12,13 +12,32 @@ retroarch \- A simple frontend for the libretro API.
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
|
||||
\fBretroarch\fR is an emulator frontend for the libretro API.
|
||||
libretro provides emulation of a game system, and can be implemented by any frontend.
|
||||
\fBretroarch\fR is the reference frontend for the libretro API.
|
||||
libretro is an abstraction of a game system, and can be implemented by any frontend.
|
||||
The libretro API is designed for games and emulators.
|
||||
\fBretroarch\fR focuses on exposing needed functionality for the game system through the use of command line and configuration files.
|
||||
It also features a simple built-in UI called RGUI.
|
||||
|
||||
.SH "EXAMPLE COMMANDLINE"
|
||||
|
||||
.TP
|
||||
\fBLoad a ROM, using a specific libretro core and config file.\fR
|
||||
retroarch --config ~/.config/retroarch/retroarch.cfg --libretro /path/to/libretro/core.so /path/to/rom.rom --verbose
|
||||
|
||||
.TP
|
||||
\fBNo command line options will start RetroArch in RGUI mode.\fR
|
||||
retroarch
|
||||
|
||||
.TP
|
||||
\fBStart RetroArch in RGUI, with verbose logging.\fR
|
||||
retroarch --menu --verbose
|
||||
|
||||
.SH "RGUI"
|
||||
RGUI is the built-in GUI system for RetroArch. It is aimed at being controlled with a gamepad only.
|
||||
|
||||
.SH "DEFAULT CONTROLS"
|
||||
By default, only keyboard input is accepted.
|
||||
|
||||
.SH "GENERAL OPTIONS"
|
||||
|
||||
.TP
|
||||
@ -74,14 +93,20 @@ Always starts RetroArch in fullscreen. Disregards settings in configuration file
|
||||
Sets the configuration file path. \fBretroarch\fR will use this path to load the configuration file.
|
||||
Should this not be defined, \fBretroarch\fR will look in platform specific paths to attempt finding the config file.
|
||||
/etc/retroarch.cfg (when installed), or retroarch.cfg in the source tarball serves as a skeleton configuration file.
|
||||
If PATH is a directory, RetroArch will treat this as the config file directory, where the state file name will be inferred from the rom name (*.cfg).
|
||||
If a config cannot be found when using directory path, the default config path will be used instead.
|
||||
/etc/retroarch.cfg should serve as a skeleton config only, and not used as a config file.
|
||||
|
||||
.IP
|
||||
Unix-like systems will look in $XDG_CONFIG_HOME/retroarch/retroarch.cfg first. If $XDG_CONFIG_HOME is not defined, it is assumed to be $HOME/.config as per specification. Then it will try $HOME/.retroarch.cfg. Last, it will try /etc/retroarch.cfg. If no configuration is found, default settings will be assumed. A configuration file does not need to define every possible option, only those that should be overridden.
|
||||
Unix-like systems will look in $XDG_CONFIG_HOME/retroarch/retroarch.cfg first. If $XDG_CONFIG_HOME is not defined, it is assumed to be $HOME/.config as per specification. Then it will try $HOME/.retroarch.cfg. If both paths fail, RetroArch will try to create a new, default config file in $XDG_CONFIG_HOME/retroarch/retroarch.cfg (or the $HOME/.config default for $XDG_CONFIG_HOME). If no configuration is found at all, default settings will be assumed.
|
||||
RetroArch will not attempt to load the skeleton config /etc/retroarch.cfg.
|
||||
A configuration file does not need to define every possible option, only those which should be overridden.
|
||||
|
||||
If config_save_on_exit = true is set in the config file, RetroArch will overwrite the config file on exit. Settings can be changed from within RGUI.
|
||||
If RetroArch overwrites a config file, formatting, comments, etc will be lost.
|
||||
If RetroArch creates a default config file, it will have config_save_on_exit set automatically.
|
||||
|
||||
.IP
|
||||
Windows will look in retroarch.cfg in same folder where retroarch.exe resides.
|
||||
A default config file will also be created in the same manner as Unix.
|
||||
|
||||
.TP
|
||||
\fB--appendconfig PATH\fR
|
||||
|
2
file.h
2
file.h
@ -74,6 +74,8 @@ bool path_is_directory(const char *path);
|
||||
bool path_file_exists(const char *path);
|
||||
const char *path_get_extension(const char *path);
|
||||
|
||||
bool path_mkdir(const char *dir);
|
||||
|
||||
// Removes all text after and including the last '.'
|
||||
char *path_remove_extension(char *path);
|
||||
|
||||
|
60
file_path.c
60
file_path.c
@ -19,6 +19,7 @@
|
||||
#include "boolean.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "compat/strl.h"
|
||||
#include "compat/posix_string.h"
|
||||
|
||||
@ -44,6 +45,7 @@
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#else
|
||||
@ -564,6 +566,64 @@ void path_resolve_realpath(char *buf, size_t size)
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool path_mkdir_norecurse(const char *dir)
|
||||
{
|
||||
#if (defined(_WIN32) && !defined(_XBOX)) || !defined(RARCH_CONSOLE)
|
||||
#ifdef _WIN32
|
||||
int ret = _mkdir(dir);
|
||||
#else
|
||||
int ret = mkdir(dir, 0750);
|
||||
#endif
|
||||
if (ret < 0 && errno == EEXIST && path_is_directory(dir)) // Don't treat this as an error.
|
||||
ret = 0;
|
||||
if (ret < 0)
|
||||
RARCH_ERR("mkdir(%s) error: %s.\n", dir, strerror(errno));
|
||||
return ret == 0;
|
||||
#else
|
||||
(void)dir;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool path_mkdir(const char *dir)
|
||||
{
|
||||
const char *target = NULL;
|
||||
char *basedir = strdup(dir); // Use heap. Real chance of stack overflow if we recurse too hard.
|
||||
bool ret = true;
|
||||
|
||||
if (!basedir)
|
||||
return false;
|
||||
|
||||
path_parent_dir(basedir);
|
||||
if (!*basedir || !strcmp(basedir, dir))
|
||||
{
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (path_is_directory(basedir))
|
||||
{
|
||||
target = dir;
|
||||
ret = path_mkdir_norecurse(dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
target = basedir;
|
||||
ret = path_mkdir(basedir);
|
||||
if (ret)
|
||||
{
|
||||
target = dir;
|
||||
ret = path_mkdir_norecurse(dir);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (target && !ret)
|
||||
RARCH_ERR("Failed to create directory: \"%s\".\n", target);
|
||||
free(basedir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size)
|
||||
{
|
||||
if (path_is_absolute(in_path))
|
||||
|
@ -67,6 +67,7 @@ static bool libretro_install_core(const char *path_prefix,
|
||||
|
||||
void rarch_make_dir(const char *x, const char *name)
|
||||
{
|
||||
// FIXME: This should use path_mkdir() in file_path.c.
|
||||
RARCH_LOG("Checking directory name %s [%s]\n", name, x);
|
||||
if (strlen(x) > 0)
|
||||
{
|
||||
|
15
retroarch.c
15
retroarch.c
@ -600,9 +600,9 @@ static int16_t input_state(unsigned port, unsigned device, unsigned index, unsig
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define RARCH_DEFAULT_CONF_PATH_STR "\n\t\tDefaults to retroarch.cfg in same directory as retroarch.exe."
|
||||
#define RARCH_DEFAULT_CONF_PATH_STR "\n\t\tDefaults to retroarch.cfg in same directory as retroarch.exe.\n\t\tIf a default config is not found, RetroArch will attempt to create one."
|
||||
#else
|
||||
#define RARCH_DEFAULT_CONF_PATH_STR "\n\t\tBy default looks for config in $XDG_CONFIG_HOME/retroarch/retroarch.cfg,\n\t\t$HOME/.config/retroarch/retroarch.cfg,\n\t\tand $HOME/.retroarch.cfg."
|
||||
#define RARCH_DEFAULT_CONF_PATH_STR "\n\t\tBy default looks for config in $XDG_CONFIG_HOME/retroarch/retroarch.cfg,\n\t\t$HOME/.config/retroarch/retroarch.cfg,\n\t\tand $HOME/.retroarch.cfg.\n\t\tIf a default config is not found, RetroArch will attempt to create one."
|
||||
#endif
|
||||
|
||||
#include "config.features.h"
|
||||
@ -772,17 +772,6 @@ static void set_paths(const char *path)
|
||||
// do not overwrite it as this was initialized before in a menu or otherwise.
|
||||
if (!*g_settings.system_directory)
|
||||
fill_pathname_basedir(g_settings.system_directory, path, sizeof(g_settings.system_directory));
|
||||
|
||||
if (*g_extern.config_path && path_is_directory(g_extern.config_path))
|
||||
{
|
||||
fill_pathname_dir(g_extern.config_path, g_extern.basename, ".cfg", sizeof(g_extern.config_path));
|
||||
RARCH_LOG("Redirecting config file to \"%s\".\n", g_extern.config_path);
|
||||
if (!path_file_exists(g_extern.config_path))
|
||||
{
|
||||
*g_extern.config_path = '\0';
|
||||
RARCH_LOG("Did not find config file. Using system default.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_input(int argc, char *argv[])
|
||||
|
66
settings.c
66
settings.c
@ -392,6 +392,28 @@ static config_file_t *open_default_config_file(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Try to create a new config file.
|
||||
if (!conf)
|
||||
{
|
||||
conf = config_file_new(NULL);
|
||||
bool saved = false;
|
||||
if (conf) // Since this is a clean config file, we can safely use config_save_on_exit.
|
||||
{
|
||||
fill_pathname_resolve_relative(conf_path, app_path, "retroarch.cfg", sizeof(conf_path));
|
||||
config_set_bool(conf, "config_save_on_exit", true);
|
||||
saved = config_file_write(conf, conf_path);
|
||||
}
|
||||
|
||||
if (saved)
|
||||
RARCH_WARN("Created new config file in: \"%s\".\n", conf_path); // WARN here to make sure user has a good chance of seeing it.
|
||||
else
|
||||
{
|
||||
RARCH_ERR("Failed to create new config file in: \"%s\".\n", conf_path);
|
||||
config_file_free(conf);
|
||||
conf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf)
|
||||
strlcpy(g_extern.config_path, conf_path, sizeof(g_extern.config_path));
|
||||
#elif !defined(__CELLOS_LV2__) && !defined(_XBOX)
|
||||
@ -401,9 +423,9 @@ static config_file_t *open_default_config_file(void)
|
||||
|
||||
// XDG_CONFIG_HOME falls back to $HOME/.config.
|
||||
if (xdg)
|
||||
snprintf(conf_path, sizeof(conf_path), "%s/retroarch/retroarch.cfg", xdg);
|
||||
fill_pathname_join(conf_path, xdg, "retroarch/retroarch.cfg", sizeof(conf_path));
|
||||
else if (home)
|
||||
snprintf(conf_path, sizeof(conf_path), "%s/.config/retroarch/retroarch.cfg", home);
|
||||
fill_pathname_join(conf_path, home, ".config/retroarch/retroarch.cfg", sizeof(conf_path));
|
||||
|
||||
if (xdg || home)
|
||||
{
|
||||
@ -414,20 +436,42 @@ static config_file_t *open_default_config_file(void)
|
||||
// Fallback to $HOME/.retroarch.cfg.
|
||||
if (!conf && home)
|
||||
{
|
||||
snprintf(conf_path, sizeof(conf_path), "%s/.retroarch.cfg", home);
|
||||
fill_pathname_join(conf_path, home, ".retroarch.cfg", sizeof(conf_path));
|
||||
RARCH_LOG("Looking for config in: \"%s\".\n", conf_path);
|
||||
conf = config_file_new(conf_path);
|
||||
}
|
||||
|
||||
// Try this as a last chance ...
|
||||
if (!conf)
|
||||
// Try to create a new config file.
|
||||
if (!conf && (home || xdg))
|
||||
{
|
||||
#ifndef GLOBAL_CONFIG_DIR
|
||||
#define GLOBAL_CONFIG_DIR "/etc"
|
||||
#endif
|
||||
fill_pathname_join(conf_path, GLOBAL_CONFIG_DIR, "retroarch.cfg", sizeof(conf_path));
|
||||
RARCH_LOG("Looking for config in: \"%s\".\n", conf_path);
|
||||
conf = config_file_new(conf_path);
|
||||
// XDG_CONFIG_HOME falls back to $HOME/.config.
|
||||
if (xdg)
|
||||
fill_pathname_join(conf_path, xdg, "retroarch/retroarch.cfg", sizeof(conf_path));
|
||||
else if (home)
|
||||
fill_pathname_join(conf_path, home, ".config/retroarch/retroarch.cfg", sizeof(conf_path));
|
||||
|
||||
char basedir[PATH_MAX];
|
||||
fill_pathname_basedir(basedir, conf_path, sizeof(basedir));
|
||||
|
||||
if (path_mkdir(basedir))
|
||||
{
|
||||
conf = config_file_new(NULL);
|
||||
bool saved = false;
|
||||
if (conf)
|
||||
{
|
||||
config_set_bool(conf, "config_save_on_exit", true); // Since this is a clean config file, we can safely use config_save_on_exit.
|
||||
saved = config_file_write(conf, conf_path);
|
||||
}
|
||||
|
||||
if (saved)
|
||||
RARCH_WARN("Created new config file in: \"%s\".\n", conf_path); // WARN here to make sure user has a good chance of seeing it.
|
||||
else
|
||||
{
|
||||
RARCH_ERR("Failed to create new config file in: \"%s\".\n", conf_path);
|
||||
config_file_free(conf);
|
||||
conf = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conf)
|
||||
|
Loading…
x
Reference in New Issue
Block a user