Parse thumbnail when opening mods.

This commit is contained in:
Dario 2025-01-28 22:33:00 -03:00 committed by Mr-Wiseguy
parent e436b41bb5
commit 3ac97d9269
4 changed files with 37 additions and 7 deletions

View file

@ -332,6 +332,7 @@ namespace recomp {
std::vector<ModDetails> get_mod_details(const std::string& mod_game_id);
void set_mod_index(const std::string &mod_game_id, const std::string &mod_id, size_t index);
const ConfigSchema &get_mod_config_schema(const std::string &mod_id) const;
const std::vector<char> &get_mod_thumbnail(const std::string &mod_id) const;
void set_mod_config_value(const std::string &mod_id, const std::string &option_id, const ConfigValueVariant &value);
ConfigValueVariant get_mod_config_value(const std::string &mod_id, const std::string &option_id);
void set_mods_config_path(const std::filesystem::path &path);
@ -347,7 +348,7 @@ namespace recomp {
CodeModLoadError init_mod_code(uint8_t* rdram, const std::unordered_map<uint32_t, uint16_t>& section_vrom_map, ModHandle& mod, int32_t load_address, bool hooks_available, uint32_t& ram_used, std::string& error_param);
CodeModLoadError load_mod_code(uint8_t* rdram, ModHandle& mod, uint32_t base_event_index, std::string& error_param);
CodeModLoadError resolve_code_dependencies(ModHandle& mod, const std::unordered_map<recomp_func_t*, recomp::overlays::BasePatchedFunction>& base_patched_funcs, std::string& error_param);
void add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types);
void add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types, std::vector<char>&& thumbnail);
void close_mods();
std::vector<ModLoadErrorDetails> regenerate_with_hooks(
const std::vector<std::pair<HookDefinition, size_t>>& sorted_unprocessed_hooks,
@ -386,6 +387,7 @@ namespace recomp {
// to add hooks to any functions that weren't already replaced by a mod.
std::vector<bool> processed_hook_slots;
ConfigSchema empty_schema;
std::vector<char> empty_bytes;
size_t num_events = 0;
ModContentTypeId code_content_type_id;
size_t active_game = (size_t)-1;
@ -414,8 +416,9 @@ namespace recomp {
std::vector<uint32_t> section_load_addresses;
// Content types present in this mod.
std::vector<ModContentTypeId> content_types;
std::vector<char> thumbnail;
ModHandle(const ModContext& context, ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& content_types);
ModHandle(const ModContext& context, ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& content_types, std::vector<char>&& thumbnail);
ModHandle(const ModHandle& rhs) = delete;
ModHandle& operator=(const ModHandle& rhs) = delete;
ModHandle(ModHandle&& rhs);
@ -552,6 +555,7 @@ namespace recomp {
bool is_mod_enabled(const std::string& mod_id);
bool is_mod_auto_enabled(const std::string& mod_id);
const ConfigSchema &get_mod_config_schema(const std::string &mod_id);
const std::vector<char> &get_mod_thumbnail(const std::string &mod_id);
void set_mod_config_value(const std::string &mod_id, const std::string &option_id, const ConfigValueVariant &value);
ConfigValueVariant get_mod_config_value(const std::string &mod_id, const std::string &option_id);
ModContentTypeId register_mod_content_type(const ModContentType& type);

View file

@ -842,9 +842,18 @@ recomp::mods::ModOpenError recomp::mods::ModContext::open_mod(const std::filesys
std::filesystem::path config_path = mod_config_directory / (manifest.mod_id + ".json");
parse_mod_config_storage(config_path, manifest.mod_id, config_storage, manifest.config_schema);
// Read the mod thumbnail if it exists.
static const std::string thumbnail_dds_name = "thumb.dds";
static const std::string thumbnail_png_name = "thumb.png";
bool exists = false;
std::vector<char> thumbnail_data = manifest.file_handle->read_file(thumbnail_dds_name, exists);
if (!exists) {
thumbnail_data = manifest.file_handle->read_file(thumbnail_png_name, exists);
}
// Store the loaded mod manifest in a new mod handle.
manifest.mod_root_path = mod_path;
add_opened_mod(std::move(manifest), std::move(config_storage), std::move(game_indices), std::move(detected_content_types));
add_opened_mod(std::move(manifest), std::move(config_storage), std::move(game_indices), std::move(detected_content_types), std::move(thumbnail_data));
return ModOpenError::Good;
}

View file

@ -266,13 +266,14 @@ recomp::mods::CodeModLoadError recomp::mods::validate_api_version(uint32_t api_v
}
}
recomp::mods::ModHandle::ModHandle(const ModContext& context, ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& content_types) :
recomp::mods::ModHandle::ModHandle(const ModContext& context, ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& content_types, std::vector<char>&& thumbnail) :
manifest(std::move(manifest)),
config_storage(std::move(config_storage)),
code_handle(),
recompiler_context{std::make_unique<N64Recomp::Context>()},
content_types{std::move(content_types)},
game_indices{std::move(game_indices)}
game_indices{std::move(game_indices)},
thumbnail{std::move(thumbnail)}
{
runtime_toggleable = true;
for (ModContentTypeId type : this->content_types) {
@ -593,11 +594,11 @@ void unpatch_func(void* target_func, const recomp::mods::PatchData& data) {
protect(target_func, old_flags);
}
void recomp::mods::ModContext::add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types) {
void recomp::mods::ModContext::add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types, std::vector<char>&& thumbnail) {
std::unique_lock lock(opened_mods_mutex);
size_t mod_index = opened_mods.size();
opened_mods_by_id.emplace(manifest.mod_id, mod_index);
opened_mods.emplace_back(*this, std::move(manifest), std::move(config_storage), std::move(game_indices), std::move(detected_content_types));
opened_mods.emplace_back(*this, std::move(manifest), std::move(config_storage), std::move(game_indices), std::move(detected_content_types), std::move(thumbnail));
opened_mods_order.emplace_back(mod_index);
}
@ -1195,6 +1196,17 @@ const recomp::mods::ConfigSchema &recomp::mods::ModContext::get_mod_config_schem
return mod.manifest.config_schema;
}
const std::vector<char> &recomp::mods::ModContext::get_mod_thumbnail(const std::string &mod_id) const {
// Check that the mod exists.
auto find_it = opened_mods_by_id.find(mod_id);
if (find_it == opened_mods_by_id.end()) {
return empty_bytes;
}
const ModHandle &mod = opened_mods[find_it->second];
return mod.thumbnail;
}
void recomp::mods::ModContext::set_mod_config_value(const std::string &mod_id, const std::string &option_id, const ConfigValueVariant &value) {
// Check that the mod exists.
auto find_it = opened_mods_by_id.find(mod_id);

View file

@ -525,6 +525,11 @@ const recomp::mods::ConfigSchema &recomp::mods::get_mod_config_schema(const std:
return mod_context->get_mod_config_schema(mod_id);
}
const std::vector<char> &recomp::mods::get_mod_thumbnail(const std::string &mod_id) {
std::lock_guard lock{ mod_context_mutex };
return mod_context->get_mod_thumbnail(mod_id);
}
void recomp::mods::set_mod_config_value(const std::string &mod_id, const std::string &option_id, const ConfigValueVariant &value) {
std::lock_guard lock{ mod_context_mutex };
return mod_context->set_mod_config_value(mod_id, option_id, value);