File vita3k-issue664.patch of Package vita3k
diff --git a/vita3k/config/src/config.cpp b/vita3k/config/src/config.cpp
index b4a7f3e1..ca78053e 100644
--- a/vita3k/config/src/config.cpp
+++ b/vita3k/config/src/config.cpp
@@ -30,6 +30,11 @@
#include <exception>
#include <iostream>
+fs::path user_home = getenv("HOME");
+fs::path local_path = user_home / "/.local/share/Vita3K/";
+fs::path config_path = user_home / "/.config/Vita3k/";
+fs::path output_path = local_path;
+
namespace config {
static std::set<std::string> get_file_set(const fs::path &loc, bool dirs_only = true) {
@@ -54,14 +59,14 @@ static std::set<std::string> get_file_set(const fs::path &loc, bool dirs_only =
return cur_set;
}
-static fs::path check_path(const fs::path &output_path) {
- if (output_path.filename() != "config.yml") {
- if (!output_path.has_extension()) // assume it is a folder
- return output_path / "config.yml";
- if (output_path.extension() != ".yml")
+static fs::path check_path(const fs::path &config_path) {
+ if (config_path.filename() != "config.yml") {
+ if (!config_path.has_extension()) // assume it is a folder
+ return config_path / "config.yml";
+ if (config_path.extension() != ".yml")
return "";
}
- return output_path;
+ return config_path;
}
static ExitCode parse(Config &cfg, const fs::path &load_path, const fs::path &root_pref_path) {
@@ -118,12 +123,12 @@ ExitCode serialize_config(Config &cfg, const fs::path &output_path) {
ExitCode init_config(Config &cfg, int argc, char **argv, const Root &root_paths) {
// Always generate the default configuration file
Config command_line{};
- serialize_config(command_line, root_paths.get_base_path() / "data/config/default.yml");
+ serialize_config(command_line, output_path / "data/config/default.yml");
// Load base path configuration by default; otherwise, move the default to the base path
- if (fs::exists(check_path(root_paths.get_base_path())))
- parse(cfg, root_paths.get_base_path(), root_paths.get_base_path());
+ if (fs::exists(check_path(config_path)))
+ parse(cfg, config_path, root_paths.get_pref_path_string());
else
- fs::copy(root_paths.get_base_path() / "data/config/default.yml", root_paths.get_base_path() / "config.yml");
+ fs::copy(output_path / "data/config/default.yml", config_path / "config.yml");
// Declare all options
CLI::App app{ "Vita3K Command Line Interface" }; // "--help,-h" is automatically generated
@@ -222,9 +227,9 @@ ExitCode init_config(Config &cfg, int argc, char **argv, const Root &root_paths)
cfg.pkg_zrif = std::move(command_line.pkg_zrif);
return QuitRequested;
}
- if (command_line.load_config || command_line.config_path != root_paths.get_base_path()) {
+ if (command_line.load_config || command_line.config_path != config_path) {
if (command_line.config_path.empty()) {
- command_line.config_path = root_paths.get_base_path();
+ command_line.config_path = config_path;
} else {
if (parse(command_line, command_line.config_path, root_paths.get_base_path()) != Success)
return InitConfigFailed;
diff --git a/vita3k/io/src/io.cpp b/vita3k/io/src/io.cpp
index 8ca6fa06..d075560e 100644
--- a/vita3k/io/src/io.cpp
+++ b/vita3k/io/src/io.cpp
@@ -96,7 +96,7 @@ SpaceInfo get_space_info(const VitaIoDevice device, const std::string &vfs_path,
// * End utility functions *
// ****************************
-bool init(IOState &io, const fs::path &base_path, const fs::path &pref_path, bool redirect_stdio) {
+bool init(IOState &io, const fs::path &output_path, const fs::path &pref_path, bool redirect_stdio) {
// Iterate through the entire list of devices and create the subdirectories if they do not exist
for (auto i : VitaIoDevice::_names()) {
if (!device::is_valid_output_path(i))
@@ -128,9 +128,9 @@ bool init(IOState &io, const fs::path &base_path, const fs::path &pref_path, boo
if (!fs::exists(uma0_data))
fs::create_directory(uma0_data);
- fs::create_directories(base_path / "cache/shaders");
- fs::create_directory(base_path / "shaderlog");
- fs::create_directory(base_path / "texturelog");
+ fs::create_directories(output_path / "cache/shaders");
+ fs::create_directory(output_path / "shaderlog");
+ fs::create_directory(output_path / "texturelog");
io.redirect_stdio = redirect_stdio;
diff --git a/vita3k/main.cpp b/vita3k/main.cpp
index 27440b90..0f6f2424 100644
--- a/vita3k/main.cpp
+++ b/vita3k/main.cpp
@@ -84,8 +84,16 @@ static void run_execv(char *argv[], EmuEnvState &emuenv) {
int main(int argc, char *argv[]) {
ZoneScoped; // Tracy - Track main function scope
Root root_paths;
+#ifdef WIN32
root_paths.set_base_path(string_utils::utf_to_wide(SDL_GetBasePath()));
root_paths.set_pref_path(string_utils::utf_to_wide(SDL_GetPrefPath(org_name, app_name)));
+#elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__)
+ fs::path user_home = getenv("HOME");
+ fs::path local_path = user_home / "/.local/share/Vita3K/";
+ fs::path config_path = user_home / "/.config/Vita3k/";
+ root_paths.set_base_path(local_path);
+ root_paths.set_pref_path(config_path);
+#endif
// Create default preference path for safety
if (!fs::exists(root_paths.get_pref_path()))
diff --git a/vita3k/renderer/src/gl/screen_render.cpp b/vita3k/renderer/src/gl/screen_render.cpp
index 47c78ff3..d18a062d 100644
--- a/vita3k/renderer/src/gl/screen_render.cpp
+++ b/vita3k/renderer/src/gl/screen_render.cpp
@@ -23,10 +23,10 @@
namespace renderer::gl {
-bool ScreenRenderer::init(const std::string &base_path) {
+bool ScreenRenderer::init(const std::string &output_path) {
glGenTextures(1, &m_screen_texture);
- const auto builtin_shaders_path = base_path + "shaders-builtin/opengl/";
+ const auto builtin_shaders_path = output_path + "shaders-builtin/opengl/";
m_render_shader_nofilter = ::gl::load_shaders(builtin_shaders_path + "render_main.vert", builtin_shaders_path + "render_main.frag");
m_render_shader_fxaa = ::gl::load_shaders(builtin_shaders_path + "render_main.vert", builtin_shaders_path + "render_main_fxaa.frag");
diff --git a/vita3k/renderer/src/shaders.cpp b/vita3k/renderer/src/shaders.cpp
index 18098cc7..05ffe35d 100644
--- a/vita3k/renderer/src/shaders.cpp
+++ b/vita3k/renderer/src/shaders.cpp
@@ -33,7 +33,7 @@
namespace renderer {
bool get_shaders_cache_hashs(State &renderer) {
- const auto shaders_path{ fs::path(renderer.base_path) / "cache/shaders" / renderer.title_id / renderer.self_name };
+ const auto shaders_path{ fs::path(output_path) / "cache/shaders" / renderer.title_id / renderer.self_name };
const std::string hash_file_name = fmt::format("hashs-{}.dat", (renderer.current_backend == Backend::OpenGL) ? "gl" : "vk");
if (renderer.current_backend == Backend::Vulkan) {
@@ -54,7 +54,7 @@ bool get_shaders_cache_hashs(State &renderer) {
if (versionInFile != shader::CURRENT_VERSION) {
shaders_hashs.close();
fs::remove_all(shaders_path);
- fs::remove_all(fs::path(renderer.base_path) / "shaderlog" / renderer.title_id / renderer.self_name);
+ fs::remove_all(fs::path(output_path) / "shaderlog" / renderer.title_id / renderer.self_name);
LOG_WARN("Current version of cache: {}, is outdated, recreate it.", versionInFile);
return false;
}
@@ -83,7 +83,7 @@ bool get_shaders_cache_hashs(State &renderer) {
}
void save_shaders_cache_hashs(State &renderer, std::vector<ShadersHash> &shaders_cache_hashs) {
- const auto shaders_path{ fs::path(renderer.base_path) / "cache/shaders" / renderer.title_id / renderer.self_name };
+ const auto shaders_path{ fs::path(output_path) / "cache/shaders" / renderer.title_id / renderer.self_name };
if (!fs::exists(shaders_path))
fs::create_directory(shaders_path);
std::string hash_file_name = fmt::format("hashs-{}.dat", (renderer.current_backend == Backend::OpenGL) ? "gl" : "vk");
@@ -111,8 +111,8 @@ void save_shaders_cache_hashs(State &renderer, std::vector<ShadersHash> &shaders
}
}
-static bool load_shader(const char *hash, const char *extension, const char *base_path, const char *title_id, const char *self_name, char **destination, std::size_t &size_read) {
- const auto shader_path = fs_utils::construct_file_name(base_path, (fs::path("cache/shaders") / title_id / self_name).string().c_str(), hash, extension);
+static bool load_shader(const char *hash, const char *extension, const char *output_path, const char *title_id, const char *self_name, char **destination, std::size_t &size_read) {
+ const auto shader_path = fs_utils::construct_file_name(output_path, (fs::path("cache/shaders") / title_id / self_name).string().c_str(), hash, extension);
fs::ifstream is(shader_path, fs::ifstream::binary);
if (!is) {
return false;
@@ -140,21 +140,21 @@ static const Sha256Hash get_shader_hash(const SceGxmProgram &program) {
}
template <typename R>
-R load_shader_generic(const char *hash_text, const char *base_path, const char *title_id, const char *self_name, const char *shader_type_str) {
+R load_shader_generic(const char *hash_text, const char *output_path, const char *title_id, const char *self_name, const char *shader_type_str) {
std::size_t read_size = 0;
R source;
- if (load_shader(hash_text, shader_type_str, base_path, title_id, self_name, nullptr, read_size)) {
+ if (load_shader(hash_text, shader_type_str, output_path, title_id, self_name, nullptr, read_size)) {
source.resize((read_size + sizeof(typename R::value_type) - 1) / sizeof(typename R::value_type));
char *dest_pointer = reinterpret_cast<char *>(source.data());
- load_shader(hash_text, shader_type_str, base_path, title_id, self_name, &dest_pointer, read_size);
+ load_shader(hash_text, shader_type_str, output_path, title_id, self_name, &dest_pointer, read_size);
}
return source;
}
-shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmProgram &program, const FeatureState &features, const shader::Hints &hints, bool maskupdate, const char *base_path, const char *title_id, const char *self_name, const char *shader_type_str, const std::string &shader_version, bool shader_cache) {
+shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmProgram &program, const FeatureState &features, const shader::Hints &hints, bool maskupdate, const char *output_path, const char *title_id, const char *self_name, const char *shader_type_str, const std::string &shader_version, bool shader_cache) {
// TODO: no need to recompute the hash here
const std::string hash_text = hex_string(get_shader_hash(program));
// Set Shader Hash with Version
@@ -162,12 +162,12 @@ shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmP
if (shader_cache) {
if (target == shader::Target::GLSLOpenGL) {
- std::string source = load_shader_generic<std::string>(hash_hex_ver.c_str(), base_path, title_id, self_name, shader_type_str);
+ std::string source = load_shader_generic<std::string>(hash_hex_ver.c_str(), output_path, title_id, self_name, shader_type_str);
if (!source.empty()) {
return { source, std::vector<uint32_t>() };
}
} else {
- std::vector<uint32_t> source = load_shader_generic<std::vector<uint32_t>>(hash_hex_ver.c_str(), base_path, title_id, self_name, shader_type_str);
+ std::vector<uint32_t> source = load_shader_generic<std::vector<uint32_t>>(hash_hex_ver.c_str(), output_path, title_id, self_name, shader_type_str);
if (!source.empty())
return { "", source };
}
@@ -179,10 +179,10 @@ shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmP
std::string disasm_dump;
const fs::path shader_base_dir{ fs::path("shaderlog") / title_id / self_name };
- if (!fs::exists(base_path / shader_base_dir))
- fs::create_directories(base_path / shader_base_dir);
+ if (!fs::exists(output_path / shader_base_dir))
+ fs::create_directories(output_path / shader_base_dir);
- auto shader_base_path = fs_utils::construct_file_name(base_path, shader_base_dir, hash_hex_ver.c_str(), ".gxp");
+ auto shader_base_path = fs_utils::construct_file_name(output_path, shader_base_dir, hash_hex_ver.c_str(), ".gxp");
// Dump gxp binary
fs::ofstream of{ shader_base_path, fs::ofstream::binary };
@@ -206,14 +206,14 @@ shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmP
// Copy shader generate to shaders cache
const auto shaders_cache_path = fs::path("cache/shaders") / title_id / self_name;
- if (!fs::exists(base_path / shaders_cache_path))
- fs::create_directories(base_path / shaders_cache_path);
+ if (!fs::exists(output_path / shaders_cache_path))
+ fs::create_directories(output_path / shaders_cache_path);
if (target == shader::Target::GLSLOpenGL) {
shader_base_path.replace_extension(shader_type_str);
if (fs::exists(shader_base_path)) {
try {
- const auto shader_dst_path = fs_utils::construct_file_name(base_path, shaders_cache_path, hash_hex_ver.c_str(), shader_type_str);
+ const auto shader_dst_path = fs_utils::construct_file_name(output_path, shaders_cache_path, hash_hex_ver.c_str(), shader_type_str);
fs::copy_file(shader_base_path, shader_dst_path, fs::copy_option::overwrite_if_exists);
fs::remove(shader_base_path);
} catch (std::exception &e) {
@@ -221,7 +221,7 @@ shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmP
}
}
} else {
- const auto shader_dst_path = fs_utils::construct_file_name(base_path, shaders_cache_path, hash_hex_ver.c_str(), "spv");
+ const auto shader_dst_path = fs_utils::construct_file_name(output_path, shaders_cache_path, hash_hex_ver.c_str(), "spv");
fs::ofstream of{ shader_dst_path, fs::ofstream::binary };
if (!of.fail()) {
of.write(reinterpret_cast<const char *>(source.spirv.data()), sizeof(uint32_t) * source.spirv.size());
@@ -232,7 +232,7 @@ shader::GeneratedShader load_shader_generic(shader::Target target, const SceGxmP
return source;
}
-std::string load_glsl_shader(const SceGxmProgram &program, const FeatureState &features, const shader::Hints &hints, bool maskupdate, const char *base_path, const char *title_id, const char *self_name, const std::string &shader_version, bool shader_cache) {
+std::string load_glsl_shader(const SceGxmProgram &program, const FeatureState &features, const shader::Hints &hints, bool maskupdate, const char *output_path, const char *title_id, const char *self_name, const std::string &shader_version, bool shader_cache) {
SceGxmProgramType program_type = program.get_type();
auto shader_type_to_str = [](SceGxmProgramType type) {
@@ -240,25 +240,25 @@ std::string load_glsl_shader(const SceGxmProgram &program, const FeatureState &f
};
const char *shader_type_str = shader_type_to_str(program_type);
- return load_shader_generic(shader::Target::GLSLOpenGL, program, features, hints, maskupdate, base_path, title_id, self_name, shader_type_str, shader_version, shader_cache).glsl;
+ return load_shader_generic(shader::Target::GLSLOpenGL, program, features, hints, maskupdate, output_path, title_id, self_name, shader_type_str, shader_version, shader_cache).glsl;
}
-std::vector<uint32_t> load_spirv_shader(const SceGxmProgram &program, const FeatureState &features, bool is_vulkan, const shader::Hints &hints, bool maskupdate, const char *base_path, const char *title_id, const char *self_name, const std::string &shader_version, bool shader_cache) {
+std::vector<uint32_t> load_spirv_shader(const SceGxmProgram &program, const FeatureState &features, bool is_vulkan, const shader::Hints &hints, bool maskupdate, const char *output_path, const char *title_id, const char *self_name, const std::string &shader_version, bool shader_cache) {
const shader::Target target = is_vulkan ? shader::Target::SpirVVulkan : shader::Target::SpirVOpenGL;
auto shader_type_to_str = [](SceGxmProgramType type) {
return (type == SceGxmProgramType::Vertex) ? "vert.spv.txt" : ((type == SceGxmProgramType::Fragment) ? "frag.spv.txt" : "unknown.spv.txt");
};
const char *shader_type_str = shader_type_to_str(program.get_type());
- return load_shader_generic(target, program, features, hints, maskupdate, base_path, title_id, self_name, shader_type_str, shader_version, shader_cache).spirv;
+ return load_shader_generic(target, program, features, hints, maskupdate, output_path, title_id, self_name, shader_type_str, shader_version, shader_cache).spirv;
}
-std::string pre_load_shader_glsl(const char *hash_text, const char *shader_type_str, const char *base_path, const char *title_id, const char *self_name) {
- return load_shader_generic<std::string>(hash_text, base_path, title_id, self_name, shader_type_str);
+std::string pre_load_shader_glsl(const char *hash_text, const char *shader_type_str, const char *output_path, const char *title_id, const char *self_name) {
+ return load_shader_generic<std::string>(hash_text, output_path, title_id, self_name, shader_type_str);
}
-std::vector<uint32_t> pre_load_shader_spirv(const char *hash_text, const char *shader_type_str, const char *base_path, const char *title_id, const char *self_name) {
- return load_shader_generic<std::vector<uint32_t>>(hash_text, base_path, title_id, self_name, shader_type_str);
+std::vector<uint32_t> pre_load_shader_spirv(const char *hash_text, const char *shader_type_str, const char *output_path, const char *title_id, const char *self_name) {
+ return load_shader_generic<std::vector<uint32_t>>(hash_text, output_path, title_id, self_name, shader_type_str);
}
} // namespace renderer
diff --git a/vita3k/renderer/src/vulkan/screen_renderer.cpp b/vita3k/renderer/src/vulkan/screen_renderer.cpp
index 0359abaf..dbb3b07b 100644
--- a/vita3k/renderer/src/vulkan/screen_renderer.cpp
+++ b/vita3k/renderer/src/vulkan/screen_renderer.cpp
@@ -53,7 +53,7 @@ bool ScreenRenderer::create(SDL_Window *window) {
return true;
}
-bool ScreenRenderer::setup(const char *base_path) {
+bool ScreenRenderer::setup(const char *output_path) {
vk::SemaphoreCreateInfo semaphore_info{};
image_acquired_semaphore = state.device.createSemaphore(semaphore_info);
image_ready_semaphore = state.device.createSemaphore(semaphore_info);
@@ -97,7 +97,7 @@ bool ScreenRenderer::setup(const char *base_path) {
LOG_INFO("Present mode: {}", vk::to_string(present_mode));
// part of the swapchain that does not need to be rebuilt every time
- const auto builtin_shaders_path = std::string(base_path) + "shaders-builtin/vulkan/";
+ const auto builtin_shaders_path = std::string(output_path) + "shaders-builtin/vulkan/";
shader_vertex = vkutil::load_shader(state.device, builtin_shaders_path + "render_main.vert.spv");
shader_fragment = vkutil::load_shader(state.device, builtin_shaders_path + "render_main.frag.spv");
shader_fragment_fxaa = vkutil::load_shader(state.device, builtin_shaders_path + "render_main_fxaa.frag.spv");
@@ -665,4 +665,4 @@ void ScreenRenderer::create_surface_image() {
std::tie(vita_surface_staging, vita_surface_staging_alloc) = state.allocator.createBuffer(buffer_info, vkutil::vma_mapped_alloc, vita_surface_staging_info);
}
-} // namespace renderer::vulkan
\ No newline at end of file
+} // namespace renderer::vulkan
diff --git a/vita3k/util/include/util/fs.h b/vita3k/util/include/util/fs.h
index 8076d61a..48c8325a 100644
--- a/vita3k/util/include/util/fs.h
+++ b/vita3k/util/include/util/fs.h
@@ -52,6 +52,11 @@ public:
}
}; // class root
+extern fs::path user_home;
+extern fs::path config_path;
+extern fs::path local_path;
+extern fs::path output_path;
+
namespace fs_utils {
/**
diff --git a/vita3k/util/src/util.cpp b/vita3k/util/src/util.cpp
index 2867b80d..de91f894 100644
--- a/vita3k/util/src/util.cpp
+++ b/vita3k/util/src/util.cpp
@@ -66,12 +66,28 @@ void flush() {
spdlog::details::registry::instance().flush_all();
}
+static fs::path check_path(const fs::path &output_path) {
+ if (output_path.filename() != LOG_FILE_NAME) {
+ if (!output_path.has_extension()) // assume it is a folder
+ return output_path / LOG_FILE_NAME;
+ if (output_path.extension() != ".log")
+ return "";
+ }
+ return output_path;
+}
+
ExitCode init(const Root &root_paths, bool use_stdout) {
+ const auto output = check_path(output_path);
+ if (output.empty())
+ return InvalidApplicationPath;
+ if (!fs::exists(output.parent_path()))
+ fs::create_directories(output.parent_path());
+
sinks.clear();
if (use_stdout)
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
- if (add_sink(root_paths.get_base_path() / LOG_FILE_NAME) != Success)
+ if (add_sink(output_path.string() / LOG_FILE_NAME) != Success)
return InitConfigFailed;
spdlog::set_error_handler([](const std::string &msg) {
@@ -106,12 +122,12 @@ void set_level(spdlog::level::level_enum log_level) {
spdlog::set_level(log_level);
}
-ExitCode add_sink(const fs::path &log_path) {
+ExitCode add_sink(const fs::path &output_path) {
try {
#ifdef WIN32
- sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.generic_path().wstring(), true));
+ sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(output_path.generic_path().wstring(), true));
#else
- sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.generic_path().string(), true));
+ sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(output_path.generic_path().string(), true));
#endif
} catch (const spdlog::spdlog_ex &ex) {
std::cerr << "File log initialization failed: " << ex.what() << std::endl;