util/fs_utils: unify read_data using SDL_IOFromFile.

- Switch all assets (avatars, lang) to use read_data
  for universal multi-OS handling.
- Fix default icon path check to properly handle assets on all platforms.

Co-authored-by: Zangetsu38 <dante38@free.fr>
This commit is contained in:
Macdu
2022-09-07 00:14:01 +02:00
committed by bookmist
parent 090d3557c0
commit ee8b6f11ac
5 changed files with 54 additions and 39 deletions
+24 -11
View File
@@ -272,21 +272,36 @@ static void init_font(GuiState &gui, EmuEnvState &emuenv) {
fs::path default_font_path = emuenv.static_assets_path / "data/fonts";
// Check existence of default font file
if (fs::exists(default_font_path)) {
gui.vita_font[i] = io.Fonts->AddFontFromFileTTF(fs_utils::path_to_utf8(default_font_path / "mplus-1mn-bold.ttf").c_str(), font_config.SizePixels, &font_config, latin_range);
std::vector<uint8_t> font_mplus{};
if (fs_utils::read_data(default_font_path / "mplus-1mn-bold.ttf", font_mplus)) {
// when calling AddFontFromMemoryTTF, we tranfer ownership to imgui and it is up to it to free the data
void *font_data = IM_ALLOC(font_mplus.size());
memcpy(font_data, font_mplus.data(), font_mplus.size());
gui.vita_font[i] = io.Fonts->AddFontFromMemoryTTF(font_data, font_mplus.size(), font_config.SizePixels, &font_config, latin_range);
font_config.MergeMode = true;
io.Fonts->AddFontFromFileTTF(fs_utils::path_to_utf8(default_font_path / "mplus-1mn-bold.ttf").c_str(), font_config.SizePixels, &font_config, japanese_and_extra_ranges.Data);
font_data = IM_ALLOC(font_mplus.size());
memcpy(font_data, font_mplus.data(), font_mplus.size());
io.Fonts->AddFontFromMemoryTTF(font_data, font_mplus.size(), font_config.SizePixels, &font_config, japanese_and_extra_ranges.Data);
const auto sys_lang = static_cast<SceSystemParamLang>(emuenv.cfg.sys_lang);
if (!emuenv.cfg.initial_setup || (sys_lang == SCE_SYSTEM_PARAM_LANG_CHINESE_S) || (sys_lang == SCE_SYSTEM_PARAM_LANG_CHINESE_T))
io.Fonts->AddFontFromFileTTF(fs_utils::path_to_utf8(default_font_path / "SourceHanSansSC-Bold-Min.ttf").c_str(), font_config.SizePixels, &font_config, japanese_and_extra_ranges.Data);
if (!emuenv.cfg.initial_setup || (sys_lang == SCE_SYSTEM_PARAM_LANG_CHINESE_S) || (sys_lang == SCE_SYSTEM_PARAM_LANG_CHINESE_T)) {
std::vector<uint8_t> font_source{};
if (fs_utils::read_data(default_font_path / "SourceHanSansSC-Bold-Min.ttf", font_source)) {
font_data = IM_ALLOC(font_source.size());
memcpy(font_data, font_source.data(), font_source.size());
io.Fonts->AddFontFromMemoryTTF(font_data, font_source.size(), font_config.SizePixels, &font_config, japanese_and_extra_ranges.Data);
}
}
font_config.MergeMode = false;
large_font_config.SizePixels = 134.f;
large_font_config.OversampleH = 2;
large_font_config.OversampleV = 2;
large_font_config.RasterizerDensity = scale;
gui.large_font[i] = io.Fonts->AddFontFromFileTTF(fs_utils::path_to_utf8(default_font_path / "mplus-1mn-bold.ttf").c_str(), large_font_config.SizePixels, &large_font_config, large_font_chars);
font_data = IM_ALLOC(font_mplus.size());
memcpy(font_data, font_mplus.data(), font_mplus.size());
gui.large_font[i] = io.Fonts->AddFontFromMemoryTTF(font_data, font_mplus.size(), large_font_config.SizePixels, &large_font_config, large_font_chars);
LOG_INFO("Using default Vita3K font.");
} else
@@ -312,12 +327,10 @@ vfs::FileBuffer init_default_icon(GuiState &gui, EmuEnvState &emuenv) {
const auto default_fw_icon{ emuenv.pref_path / "vs0/data/internal/livearea/default/sce_sys/icon0.png" };
fs::path default_icon = emuenv.static_assets_path / "data/image/icon.png";
const fs::path default_icon{ emuenv.static_assets_path / "data/image/icon.png" };
if (fs::exists(default_fw_icon) || fs::exists(default_icon)) {
fs::path icon_path = fs::exists(default_fw_icon) ? default_fw_icon : default_icon;
fs_utils::read_data(icon_path, buffer);
}
const fs::path icon_path = fs::exists(default_fw_icon) ? default_fw_icon : default_icon;
fs_utils::read_data(icon_path, buffer);
return buffer;
}
+3 -5
View File
@@ -57,7 +57,8 @@ static std::map<std::string, std::map<AvatarSize, AvatarInfo>> users_avatar_info
static bool init_avatar(GuiState &gui, EmuEnvState &emuenv, const std::string &user_id, const std::string &avatar_path) {
const auto avatar_path_path = avatar_path == "default" ? emuenv.static_assets_path / "data/image/icon.png" : fs_utils::utf8_to_path(avatar_path);
if (!fs::exists(avatar_path_path)) {
std::vector<uint8_t> avatar_data{};
if (!fs_utils::read_data(avatar_path_path, avatar_data)) {
LOG_WARN("Avatar image doesn't exist: {}.", avatar_path_path);
return false;
}
@@ -65,9 +66,7 @@ static bool init_avatar(GuiState &gui, EmuEnvState &emuenv, const std::string &u
int32_t width = 0;
int32_t height = 0;
FILE *f = FOPEN(avatar_path_path.c_str(), "rb");
stbi_uc *data = stbi_load_from_file(f, &width, &height, nullptr, STBI_rgb_alpha);
stbi_uc *data = stbi_load_from_memory(avatar_data.data(), avatar_data.size(), &width, &height, nullptr, STBI_rgb_alpha);
if (!data) {
LOG_ERROR("Invalid or corrupted image: {}.", avatar_path_path);
@@ -76,7 +75,6 @@ static bool init_avatar(GuiState &gui, EmuEnvState &emuenv, const std::string &u
gui.users_avatar[user_id] = ImGui_Texture(gui.imgui_state.get(), data, width, height);
stbi_image_free(data);
fclose(f);
// Calculate avatar size and position based of aspect ratio
// Resize for all size of avatar
+14 -16
View File
@@ -90,8 +90,9 @@ void init_lang(LangState &lang, EmuEnvState &emuenv) {
// Load lang xml
pugi::xml_document lang_xml;
const auto lang_xml_path{ (emuenv.cfg.user_lang.empty() ? system_lang_path / lang.user_lang[GUI] : (is_user_lang_static ? user_lang_static_path : user_lang_shared_path) / emuenv.cfg.user_lang).replace_extension("xml") };
if (fs::exists(lang_xml_path)) {
auto load_xml_res = lang_xml.load_file(lang_xml_path.c_str());
std::vector<uint8_t> lang_content{};
if (fs_utils::read_data(lang_xml_path, lang_content)) {
const auto load_xml_res = lang_xml.load_buffer(lang_content.data(), lang_content.size(), pugi::encoding_utf8);
if (load_xml_res) {
// Lang
const auto lang_child = lang_xml.child("lang");
@@ -418,22 +419,19 @@ void init_lang(LangState &lang, EmuEnvState &emuenv) {
set_lang_string(lang.welcome, lang_child.child("welcome"));
}
} else {
LOG_ERROR("Error open lang file xml: {}", lang_xml_path);
LOG_ERROR("Error parsing lang file xml: {}", lang_xml_path);
LOG_DEBUG("error: {} position: {}", load_xml_res.description(), load_xml_res.offset);
constexpr ptrdiff_t context_window = 20;
fs::ifstream file(lang_xml_path, std::ios::binary);
if (file.is_open()) {
const ptrdiff_t error_in_context = load_xml_res.offset < context_window ? load_xml_res.offset : context_window;
file.seekg(load_xml_res.offset - error_in_context, std::ios::beg);
if (!file.eof()) {
std::string error_context;
error_context.resize(context_window * 2);
file.read(error_context.data(), context_window * 2);
if (file.gcount() < context_window * 2)
error_context.resize(file.gcount());
LOG_DEBUG("Error preview: {}|{}", error_context.substr(0, error_in_context), error_context.substr(error_in_context));
}
file.close();
ptrdiff_t offset = static_cast<ptrdiff_t>(load_xml_res.offset);
if (offset >= 0 && offset < static_cast<ptrdiff_t>(lang_content.size())) {
ptrdiff_t start = std::max<ptrdiff_t>(0, offset - context_window);
ptrdiff_t end = std::min<ptrdiff_t>(lang_content.size(), offset + context_window);
ptrdiff_t error_in_context = offset - start;
std::string error_context(reinterpret_cast<const char *>(lang_content.data() + start), end - start);
LOG_DEBUG("Error preview: {}|{}", error_context.substr(0, error_in_context), error_context.substr(error_in_context));
}
}
} else
+1 -1
View File
@@ -17,5 +17,5 @@ add_library(
target_include_directories(util PUBLIC include)
target_link_libraries(util PUBLIC ${Boost_LIBRARIES} fmt spdlog http mem)
target_link_libraries(util PRIVATE libcurl crypto)
target_link_libraries(util PRIVATE libcurl crypto SDL3::SDL3)
target_compile_definitions(util PRIVATE $<$<CONFIG:Debug,RelWithDebInfo>:TRACY_ENABLE>)
+12 -6
View File
@@ -18,6 +18,8 @@
#include <util/fs.h>
#include <util/string_utils.h>
#include <SDL3/SDL_iostream.h>
namespace fs_utils {
fs::path construct_file_name(const fs::path &base_path, const fs::path &folder_path, const fs::path &file_name, const fs::path &extension) {
@@ -58,25 +60,29 @@ void dump_data(const fs::path &path, const void *data, const std::streamsize siz
template <typename T>
static bool read_data(const fs::path &path, std::vector<T> &data) {
data.clear();
fs::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
SDL_IOStream *file = SDL_IOFromFile(fs_utils::path_to_utf8(path).c_str(), "rb");
if (!file) {
return false;
}
// Get the size of the file
std::streamsize size = file.tellg();
const Sint64 size = SDL_GetIOSize(file);
if (size <= 0) {
SDL_CloseIO(file);
return false;
}
// Resize the vector to fit the file content
data.resize(size);
// Go back to the beginning of the file and read the content
file.seekg(0, std::ios::beg);
if (!file.read(reinterpret_cast<char *>(data.data()), size)) {
// Read the content of the file
if (SDL_ReadIO(file, data.data(), size) != size) {
SDL_CloseIO(file);
data.clear();
return false;
}
SDL_CloseIO(file);
return true;
}