mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp.git
synced 2025-12-25 01:12:49 +00:00
Add special config option id to control texture pack state for code mods
This commit is contained in:
parent
8382fa3d65
commit
7407bebf6e
7 changed files with 162 additions and 21 deletions
|
|
@ -14,6 +14,8 @@ namespace RT64 {
|
|||
|
||||
namespace zelda64 {
|
||||
namespace renderer {
|
||||
inline const std::string special_option_texture_pack_enabled = "_recomp_texture_pack_enabled";
|
||||
|
||||
class RT64Context final : public ultramodern::renderer::RendererContext {
|
||||
public:
|
||||
~RT64Context() override;
|
||||
|
|
@ -33,6 +35,7 @@ namespace zelda64 {
|
|||
private:
|
||||
std::unique_ptr<RT64::Application> app;
|
||||
std::unordered_set<std::string> enabled_texture_packs;
|
||||
std::unordered_set<std::string> secondary_disabled_texture_packs;
|
||||
|
||||
void check_texture_pack_actions();
|
||||
};
|
||||
|
|
@ -44,8 +47,14 @@ namespace zelda64 {
|
|||
bool RT64HighPrecisionFBEnabled();
|
||||
|
||||
void trigger_texture_pack_update();
|
||||
void enable_texture_pack(const recomp::mods::ModHandle& mod);
|
||||
void enable_texture_pack(const recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod);
|
||||
void disable_texture_pack(const recomp::mods::ModHandle& mod);
|
||||
void secondary_enable_texture_pack(const std::string& mod_id);
|
||||
void secondary_disable_texture_pack(const std::string& mod_id);
|
||||
|
||||
// Texture pack enable option. Must be an enum with two options.
|
||||
// The first option is treated as disabled and the second option is treated as enabled.
|
||||
bool is_texture_pack_enable_config_option(const recomp::mods::ConfigOption& option, bool show_errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit bb6b3b1645a582b8d9305f221375da9d3563ee60
|
||||
Subproject commit 234ed4a95e6578c42434bc45d5232466a9b74de7
|
||||
|
|
@ -544,8 +544,8 @@ void release_preload(PreloadContext& context) {
|
|||
|
||||
#endif
|
||||
|
||||
void enable_texture_pack(recomp::mods::ModContext&, const recomp::mods::ModHandle& mod) {
|
||||
zelda64::renderer::enable_texture_pack(mod);
|
||||
void enable_texture_pack(recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) {
|
||||
zelda64::renderer::enable_texture_pack(context, mod);
|
||||
}
|
||||
|
||||
void disable_texture_pack(recomp::mods::ModContext&, const recomp::mods::ModHandle& mod) {
|
||||
|
|
|
|||
|
|
@ -30,10 +30,18 @@ struct TexturePackDisableAction {
|
|||
std::string mod_id;
|
||||
};
|
||||
|
||||
struct TexturePackSecondaryEnableAction {
|
||||
std::string mod_id;
|
||||
};
|
||||
|
||||
struct TexturePackSecondaryDisableAction {
|
||||
std::string mod_id;
|
||||
};
|
||||
|
||||
struct TexturePackUpdateAction {
|
||||
};
|
||||
|
||||
using TexturePackAction = std::variant<TexturePackEnableAction, TexturePackDisableAction, TexturePackUpdateAction>;
|
||||
using TexturePackAction = std::variant<TexturePackEnableAction, TexturePackDisableAction, TexturePackSecondaryEnableAction, TexturePackSecondaryDisableAction, TexturePackUpdateAction>;
|
||||
|
||||
static moodycamel::ConcurrentQueue<TexturePackAction> texture_pack_action_queue;
|
||||
|
||||
|
|
@ -403,6 +411,14 @@ void zelda64::renderer::RT64Context::check_texture_pack_actions() {
|
|||
enabled_texture_packs.insert(to_enable.mod_id);
|
||||
packs_changed = true;
|
||||
},
|
||||
[&](TexturePackSecondaryDisableAction &to_override_disable) {
|
||||
secondary_disabled_texture_packs.insert(to_override_disable.mod_id);
|
||||
packs_changed = true;
|
||||
},
|
||||
[&](TexturePackSecondaryEnableAction &to_override_enable) {
|
||||
secondary_disabled_texture_packs.erase(to_override_enable.mod_id);
|
||||
packs_changed = true;
|
||||
},
|
||||
[&](TexturePackUpdateAction &) {
|
||||
packs_changed = true;
|
||||
}
|
||||
|
|
@ -411,23 +427,29 @@ void zelda64::renderer::RT64Context::check_texture_pack_actions() {
|
|||
|
||||
// If any packs were disabled, unload all packs and load all the active ones.
|
||||
if (packs_changed) {
|
||||
if (!enabled_texture_packs.empty()) {
|
||||
// Sort the enabled texture packs in reverse order so that earlier ones override later ones.
|
||||
std::vector<std::string> sorted_texture_packs{};
|
||||
sorted_texture_packs.assign(enabled_texture_packs.begin(), enabled_texture_packs.end());
|
||||
std::sort(sorted_texture_packs.begin(), sorted_texture_packs.end(),
|
||||
[](const std::string& lhs, const std::string& rhs) {
|
||||
return recomp::mods::get_mod_order_index(lhs) > recomp::mods::get_mod_order_index(rhs);
|
||||
}
|
||||
);
|
||||
|
||||
// Build the path list from the sorted mod list.
|
||||
std::vector<RT64::ReplacementDirectory> replacement_directories;
|
||||
replacement_directories.reserve(enabled_texture_packs.size());
|
||||
for (const std::string &mod_id : sorted_texture_packs) {
|
||||
replacement_directories.emplace_back(RT64::ReplacementDirectory(recomp::mods::get_mod_filename(mod_id)));
|
||||
// Sort the enabled texture packs in reverse order so that earlier ones override later ones.
|
||||
std::vector<std::string> sorted_texture_packs{};
|
||||
sorted_texture_packs.reserve(enabled_texture_packs.size());
|
||||
for (const std::string& mod : enabled_texture_packs) {
|
||||
if (!secondary_disabled_texture_packs.contains(mod)) {
|
||||
sorted_texture_packs.emplace_back(mod);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(sorted_texture_packs.begin(), sorted_texture_packs.end(),
|
||||
[](const std::string& lhs, const std::string& rhs) {
|
||||
return recomp::mods::get_mod_order_index(lhs) > recomp::mods::get_mod_order_index(rhs);
|
||||
}
|
||||
);
|
||||
|
||||
// Build the path list from the sorted mod list.
|
||||
std::vector<RT64::ReplacementDirectory> replacement_directories;
|
||||
replacement_directories.reserve(enabled_texture_packs.size());
|
||||
for (const std::string &mod_id : sorted_texture_packs) {
|
||||
replacement_directories.emplace_back(RT64::ReplacementDirectory(recomp::mods::get_mod_filename(mod_id)));
|
||||
}
|
||||
|
||||
if (!replacement_directories.empty()) {
|
||||
app->textureCache->loadReplacementDirectories(replacement_directories);
|
||||
}
|
||||
else {
|
||||
|
|
@ -456,10 +478,68 @@ void zelda64::renderer::trigger_texture_pack_update() {
|
|||
texture_pack_action_queue.enqueue(TexturePackUpdateAction{});
|
||||
}
|
||||
|
||||
void zelda64::renderer::enable_texture_pack(const recomp::mods::ModHandle& mod) {
|
||||
void zelda64::renderer::enable_texture_pack(const recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) {
|
||||
texture_pack_action_queue.enqueue(TexturePackEnableAction{mod.manifest.mod_id});
|
||||
|
||||
// Check for the texture pack enabled config option.
|
||||
const recomp::mods::ConfigSchema& config_schema = context.get_mod_config_schema(mod.manifest.mod_id);
|
||||
auto find_it = config_schema.options_by_id.find(zelda64::renderer::special_option_texture_pack_enabled);
|
||||
if (find_it != config_schema.options_by_id.end()) {
|
||||
const recomp::mods::ConfigOption& config_option = config_schema.options[find_it->second];
|
||||
|
||||
if (is_texture_pack_enable_config_option(config_option, false)) {
|
||||
recomp::mods::ConfigValueVariant value_variant = context.get_mod_config_value(mod.manifest.mod_id, config_option.id);
|
||||
uint32_t value;
|
||||
if (uint32_t* value_ptr = std::get_if<uint32_t>(&value_variant)) {
|
||||
value = *value_ptr;
|
||||
}
|
||||
else {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
zelda64::renderer::secondary_enable_texture_pack(mod.manifest.mod_id);
|
||||
}
|
||||
else {
|
||||
zelda64::renderer::secondary_disable_texture_pack(mod.manifest.mod_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void zelda64::renderer::disable_texture_pack(const recomp::mods::ModHandle& mod) {
|
||||
texture_pack_action_queue.enqueue(TexturePackDisableAction{mod.manifest.mod_id});
|
||||
}
|
||||
|
||||
void zelda64::renderer::secondary_enable_texture_pack(const std::string& mod_id) {
|
||||
texture_pack_action_queue.enqueue(TexturePackSecondaryEnableAction{mod_id});
|
||||
}
|
||||
|
||||
void zelda64::renderer::secondary_disable_texture_pack(const std::string& mod_id) {
|
||||
texture_pack_action_queue.enqueue(TexturePackSecondaryDisableAction{mod_id});
|
||||
}
|
||||
|
||||
|
||||
// HD texture enable option. Must be an enum with two options.
|
||||
// The first option is treated as disabled and the second option is treated as enabled.
|
||||
bool zelda64::renderer::is_texture_pack_enable_config_option(const recomp::mods::ConfigOption& option, bool show_errors) {
|
||||
if (option.id == zelda64::renderer::special_option_texture_pack_enabled) {
|
||||
if (option.type != recomp::mods::ConfigOptionType::Enum) {
|
||||
if (show_errors) {
|
||||
recompui::message_box(("Mod has the special config option id for enabling an HD texture pack (\"" + zelda64::renderer::special_option_texture_pack_enabled + "\"), but the config option is not an enum.").c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
|
||||
if (option_enum.options.size() != 2) {
|
||||
if (show_errors) {
|
||||
recompui::message_box(("Mod has the special config option id for enabling an HD texture pack (\"" + zelda64::renderer::special_option_texture_pack_enabled + "\"), but the config option doesn't have exactly 2 values.").c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ui_mod_menu.h"
|
||||
#include "recomp_ui.h"
|
||||
#include "zelda_support.h"
|
||||
#include "zelda_render.h"
|
||||
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
|
|
@ -384,6 +385,22 @@ ContextId get_config_sub_menu_context_id() {
|
|||
return sub_menu_context;
|
||||
}
|
||||
|
||||
bool ModMenu::handle_special_config_options(const recomp::mods::ConfigOption& option, const recomp::mods::ConfigValueVariant& config_value) {
|
||||
if (zelda64::renderer::is_texture_pack_enable_config_option(option, true)) {
|
||||
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
|
||||
|
||||
config_sub_menu->add_radio_option(option.id, option.name, option.description, std::get<uint32_t>(config_value), option_enum.options,
|
||||
[this](const std::string &id, uint32_t value) {
|
||||
mod_enum_option_changed(id, value);
|
||||
mod_hd_textures_enabled_changed(value);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ModMenu::mod_configure_requested() {
|
||||
if (active_mod_index >= 0) {
|
||||
// Record the context that was open when this function was called and close it.
|
||||
|
|
@ -401,6 +418,10 @@ void ModMenu::mod_configure_requested() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (handle_special_config_options(option, config_value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (option.type) {
|
||||
case recomp::mods::ConfigOptionType::Enum: {
|
||||
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
|
||||
|
|
@ -455,6 +476,17 @@ void ModMenu::mod_number_option_changed(const std::string &id, double value) {
|
|||
}
|
||||
}
|
||||
|
||||
void ModMenu::mod_hd_textures_enabled_changed(uint32_t value) {
|
||||
if (active_mod_index >= 0) {
|
||||
if (value) {
|
||||
zelda64::renderer::secondary_enable_texture_pack(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
else {
|
||||
zelda64::renderer::secondary_disable_texture_pack(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::create_mod_list() {
|
||||
ContextId context = get_current_context();
|
||||
|
||||
|
|
|
|||
|
|
@ -74,9 +74,11 @@ private:
|
|||
void mod_selected(uint32_t mod_index);
|
||||
void mod_dragged(uint32_t mod_index, EventDrag drag);
|
||||
void mod_configure_requested();
|
||||
bool handle_special_config_options(const recomp::mods::ConfigOption& option, const recomp::mods::ConfigValueVariant& config_value);
|
||||
void mod_enum_option_changed(const std::string &id, uint32_t value);
|
||||
void mod_string_option_changed(const std::string &id, const std::string &value);
|
||||
void mod_number_option_changed(const std::string &id, double value);
|
||||
void mod_hd_textures_enabled_changed(uint32_t value);
|
||||
void create_mod_list();
|
||||
void process_event(const Event &e) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ void recompui::open_choice_prompt(
|
|||
|
||||
std::function<void()> prev_cancel_action = std::move(prompt_state.cancel_action);
|
||||
|
||||
ContextId prev_context = try_close_current_context();
|
||||
|
||||
prompt_state.ui_context.open();
|
||||
|
||||
prompt_state.prompt_header->set_text(header_text);
|
||||
|
|
@ -252,6 +254,10 @@ void recompui::open_choice_prompt(
|
|||
|
||||
prompt_state.ui_context.close();
|
||||
|
||||
if (prev_context != ContextId::null()) {
|
||||
prev_context.open();
|
||||
}
|
||||
|
||||
show_prompt(prev_cancel_action, focus_on_cancel);
|
||||
}
|
||||
|
||||
|
|
@ -267,6 +273,8 @@ void recompui::open_info_prompt(
|
|||
|
||||
std::function<void()> prev_cancel_action = std::move(prompt_state.cancel_action);
|
||||
|
||||
ContextId prev_context = try_close_current_context();
|
||||
|
||||
prompt_state.ui_context.open();
|
||||
|
||||
prompt_state.prompt_header->set_text(header_text);
|
||||
|
|
@ -283,6 +291,10 @@ void recompui::open_info_prompt(
|
|||
|
||||
prompt_state.ui_context.close();
|
||||
|
||||
if (prev_context != ContextId::null()) {
|
||||
prev_context.open();
|
||||
}
|
||||
|
||||
show_prompt(prev_cancel_action, true);
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +307,8 @@ void recompui::open_notification(
|
|||
|
||||
std::function<void()> prev_cancel_action = std::move(prompt_state.cancel_action);
|
||||
|
||||
ContextId prev_context = try_close_current_context();
|
||||
|
||||
prompt_state.ui_context.open();
|
||||
|
||||
prompt_state.prompt_header->set_text(header_text);
|
||||
|
|
@ -308,6 +322,10 @@ void recompui::open_notification(
|
|||
|
||||
prompt_state.ui_context.close();
|
||||
|
||||
if (prev_context != ContextId::null()) {
|
||||
prev_context.open();
|
||||
}
|
||||
|
||||
show_prompt(prev_cancel_action, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue