mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
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:
+24
-11
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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>)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user