mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-07-25 08:04:01 +02:00
302 lines
6.9 KiB
C++
302 lines
6.9 KiB
C++
/*
|
|
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
|
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "Directories.hpp"
|
|
#include "Error.hpp"
|
|
#include "Core.hpp"
|
|
#include "Config.hpp"
|
|
#include "m64p/Api.hpp"
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <filesystem>
|
|
|
|
//
|
|
// Local Variables
|
|
//
|
|
|
|
static std::filesystem::path l_CorePathOverride;
|
|
static std::filesystem::path l_PluginPathOverride;
|
|
static std::filesystem::path l_SharedDataPathOverride;
|
|
|
|
//
|
|
// Local Functions
|
|
//
|
|
|
|
static std::filesystem::path get_var_directory(std::string var, std::string append, std::string fallbackVar, std::string fallbackAppend)
|
|
{
|
|
std::filesystem::path directory;
|
|
|
|
const char* env = std::getenv(var.c_str());
|
|
if (env == nullptr)
|
|
{
|
|
env = std::getenv(fallbackVar.c_str());
|
|
if (env == nullptr)
|
|
{
|
|
std::cerr << "get_var_directory: fallbackVar: $" << fallbackVar << " cannot be nullptr!" << std::endl;
|
|
std::terminate();
|
|
}
|
|
directory = env;
|
|
directory += fallbackAppend;
|
|
}
|
|
else
|
|
{
|
|
directory = env;
|
|
directory += append;
|
|
}
|
|
|
|
return directory;
|
|
}
|
|
|
|
static std::filesystem::path get_command_output(std::string command)
|
|
{
|
|
std::string output;
|
|
char buf[2048];
|
|
FILE* pipe = nullptr;
|
|
|
|
pipe = popen(command.c_str(), "r");
|
|
if (pipe == nullptr)
|
|
{
|
|
return std::string();
|
|
}
|
|
|
|
while (fgets(buf, sizeof(buf), pipe) != nullptr)
|
|
{
|
|
output += buf;
|
|
}
|
|
|
|
pclose(pipe);
|
|
|
|
// strip newline
|
|
if (output.back() == '\n')
|
|
{
|
|
output.pop_back();
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
//
|
|
// Exported Functions
|
|
//
|
|
|
|
bool CoreCreateDirectories(void)
|
|
{
|
|
std::string error;
|
|
|
|
std::filesystem::path directories[] =
|
|
{
|
|
#ifdef PORTABLE_INSTALL
|
|
CoreGetCoreDirectory(),
|
|
CoreGetPluginDirectory(),
|
|
CoreGetSharedDataDirectory(),
|
|
#endif // PORTABLE_INSTALL
|
|
CoreGetUserConfigDirectory(),
|
|
CoreGetUserDataDirectory(),
|
|
CoreGetUserCacheDirectory(),
|
|
CoreGetSaveDirectory(),
|
|
CoreGetSaveStateDirectory(),
|
|
CoreGetScreenshotDirectory()
|
|
};
|
|
|
|
for (const auto& dir : directories)
|
|
{
|
|
try
|
|
{
|
|
std::filesystem::create_directories(dir);
|
|
}
|
|
catch (...)
|
|
{
|
|
error = "CoreCreateDirectories Failed: cannot create the '";
|
|
error += dir.string();
|
|
error += "' directory!";
|
|
CoreSetError(error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::filesystem::path CoreGetCoreDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Core";
|
|
#else // Not Portable
|
|
if (!l_CorePathOverride.empty())
|
|
{
|
|
directory = l_CorePathOverride;
|
|
}
|
|
else
|
|
{
|
|
directory = CORE_INSTALL_PREFIX;
|
|
directory += "/lib/RMG/Core";
|
|
}
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetPluginDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Plugin";
|
|
#else // Not Portable
|
|
if (!l_PluginPathOverride.empty())
|
|
{
|
|
directory = l_PluginPathOverride;
|
|
}
|
|
else
|
|
{
|
|
directory = CORE_INSTALL_PREFIX;
|
|
directory += "/lib/RMG/Plugin";
|
|
}
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetUserConfigDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Config";
|
|
#else // Not Portable
|
|
directory = get_var_directory("XDG_CONFIG_HOME", "/RMG", "HOME", "/.config/RMG");
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetDefaultUserDataDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Data";
|
|
#else // Not Portable
|
|
directory = get_var_directory("XDG_DATA_HOME", "/RMG", "HOME", "/.local/share/RMG");
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetDefaultUserCacheDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Cache";
|
|
#else // Not Portable
|
|
directory = get_var_directory("XDG_CACHE_HOME", "/RMG", "HOME", "/.cache/RMG");
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetDefaultSaveDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Save/Game";
|
|
#else // Not Portable
|
|
directory = CoreGetDefaultUserDataDirectory();
|
|
directory += "/Save/Game";
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetDefaultSaveStateDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Save/State";
|
|
#else // Not Portable
|
|
directory = CoreGetDefaultUserDataDirectory();
|
|
directory += "/Save/State";
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetDefaultScreenshotDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Screenshots";
|
|
#else // Not Portable
|
|
directory = get_command_output("xdg-user-dir PICTURES");
|
|
if (!directory.empty())
|
|
{
|
|
directory += "/RMG";
|
|
}
|
|
else
|
|
{
|
|
directory = get_var_directory("XDG_PICTURES_DIR", "/RMG", "HOME", "/Pictures/RMG");
|
|
}
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetUserDataDirectory(void)
|
|
{
|
|
return std::filesystem::path(m64p::Config.GetUserDataPath());
|
|
}
|
|
|
|
std::filesystem::path CoreGetUserCacheDirectory(void)
|
|
{
|
|
return std::filesystem::path(m64p::Config.GetUserCachePath());
|
|
}
|
|
|
|
std::filesystem::path CoreGetSharedDataDirectory(void)
|
|
{
|
|
std::filesystem::path directory;
|
|
#ifdef PORTABLE_INSTALL
|
|
directory = "Data";
|
|
#else // Not Portable
|
|
if (!l_SharedDataPathOverride.empty())
|
|
{
|
|
directory = l_SharedDataPathOverride;
|
|
}
|
|
else
|
|
{
|
|
directory = CORE_INSTALL_PREFIX;
|
|
directory += "/share/RMG";
|
|
}
|
|
#endif // PORTABLE_INSTALL
|
|
return directory;
|
|
}
|
|
|
|
std::filesystem::path CoreGetSaveDirectory(void)
|
|
{
|
|
return CoreSettingsGetStringValue(SettingsID::Core_SaveSRAMPath);
|
|
}
|
|
|
|
std::filesystem::path CoreGetSaveStateDirectory(void)
|
|
{
|
|
return CoreSettingsGetStringValue(SettingsID::Core_SaveStatePath);
|
|
}
|
|
|
|
std::filesystem::path CoreGetScreenshotDirectory(void)
|
|
{
|
|
return CoreSettingsGetStringValue(SettingsID::Core_ScreenshotPath);
|
|
}
|
|
|
|
#ifndef PORTABLE_INSTALL
|
|
void CoreSetCorePathOverride(std::filesystem::path path)
|
|
{
|
|
l_CorePathOverride = path;
|
|
}
|
|
|
|
void CoreSetPluginPathOverride(std::filesystem::path path)
|
|
{
|
|
l_PluginPathOverride = path;
|
|
}
|
|
|
|
void CoreSetSharedDataPathOverride(std::filesystem::path path)
|
|
{
|
|
l_SharedDataPathOverride = path;
|
|
}
|
|
#endif // PORTABLE_INSTALL
|