diff --git a/include/d/d_file_sel_info.h b/include/d/d_file_sel_info.h index 973349c469..37dadbeb1b 100644 --- a/include/d/d_file_sel_info.h +++ b/include/d/d_file_sel_info.h @@ -37,7 +37,7 @@ public: CPaneMgrAlpha* getNoDatBase() { return mNoDatBase; } void draw() { _draw(); } -private: +// private: /* 0x04 */ JKRArchive* mArchive; /* 0x08 */ dDlst_FileInfo_c mFileInfo; /* 0x1C */ u8 field_0x1c[4]; diff --git a/include/d/d_menu_collect.h b/include/d/d_menu_collect.h index b7d5ec2976..c2d28a5ee1 100644 --- a/include/d/d_menu_collect.h +++ b/include/d/d_menu_collect.h @@ -17,14 +17,9 @@ class dMenu_Insect_c; class dSelect_cursor_c; #if TARGET_PC -struct PaneCache { - u64 tag; - f32 origTransX; - f32 origTransY; - bool cached; -}; +#include "dusk/utilities.hpp" -static PaneCache mpScreenPanes[] = { +static dusk::utils::PaneCache mpScreenPanes[] = { {MULTI_CHAR('sa_tex_n'), 0.0f, 0.0f, false}, {MULTI_CHAR('op_tex_n'), 0.0f, 0.0f, false}, {MULTI_CHAR('heart_n'), 0.0f, 0.0f, false}, @@ -172,7 +167,7 @@ public: J2DPicture* getBlackTex() { return mpBlackTex; } u8 getSubWindowOpenCheck() { return mSubWindowOpenCheck; } -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ JKRExpHeap* mpSubHeap; /* 0x00C */ void* field_0xc; diff --git a/include/d/d_menu_fishing.h b/include/d/d_menu_fishing.h index 972aa8f7c4..f2e9419ce3 100644 --- a/include/d/d_menu_fishing.h +++ b/include/d/d_menu_fishing.h @@ -43,7 +43,7 @@ public: u8 getStatus() { return mStatus; } -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ JKRArchive* mpArchive; /* 0x00C */ STControl* mpStick; diff --git a/include/d/d_menu_fmap.h b/include/d/d_menu_fmap.h index 110298798a..2e5ee95772 100644 --- a/include/d/d_menu_fmap.h +++ b/include/d/d_menu_fmap.h @@ -270,7 +270,7 @@ public: static DUSK_GAME_DATA dMenu_Fmap_c* MyClass; -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ JKRExpHeap* mpTalkHeap; /* 0x00C */ STControl* mpStick; diff --git a/include/d/d_menu_insect.h b/include/d/d_menu_insect.h index 90cfca7d5a..5e0b453949 100644 --- a/include/d/d_menu_insect.h +++ b/include/d/d_menu_insect.h @@ -60,7 +60,7 @@ public: u8 getStatus() { return mStatus; } -private: +// private: /* 0x04 */ JKRExpHeap* mpHeap; /* 0x08 */ JKRArchive* mpArchive; /* 0x0C */ STControl* mpStick; diff --git a/include/d/d_menu_letter.h b/include/d/d_menu_letter.h index 208f8b65a9..21747c7e78 100644 --- a/include/d/d_menu_letter.h +++ b/include/d/d_menu_letter.h @@ -64,7 +64,7 @@ public: u8 getStatus() { return mStatus; } -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ JKRArchive* mpArchive; /* 0x00C */ STControl* mpStick; diff --git a/include/d/d_menu_option.h b/include/d/d_menu_option.h index 49e81f98ae..f158498dd7 100644 --- a/include/d/d_menu_option.h +++ b/include/d/d_menu_option.h @@ -117,7 +117,7 @@ public: return ((u8)mUseFlag & (u8)i_flag) != 0 ? true : false; } -private: +// private: /* 0x004 */ J2DScreen* mpBackScreen; /* 0x008 */ J2DScreen* mpScreen; /* 0x00C */ J2DScreen* mpClipScreen; diff --git a/include/d/d_menu_ring.h b/include/d/d_menu_ring.h index c7467d2a4b..d0f021339e 100644 --- a/include/d/d_menu_ring.h +++ b/include/d/d_menu_ring.h @@ -84,7 +84,7 @@ public: void drawFlag0() { mDrawFlag = 0; } void setStatus(u8 i_status) { mStatus = i_status; } -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ STControl* mpStick; /* 0x00C */ CSTControl* mpCStick; diff --git a/include/d/d_menu_save.h b/include/d/d_menu_save.h index d9d052aa33..7e94d1d1c9 100644 --- a/include/d/d_menu_save.h +++ b/include/d/d_menu_save.h @@ -278,7 +278,7 @@ public: u8 getEndStatus() { return mEndStatus; } void setUseType(u8 type) { mUseType = type; } -private: +// private: /* 0x0004 */ JKRArchive* mpArchive; /* 0x0008 */ mDoDvdThd_mountArchive_c* mpMount; /* 0x000C */ STControl* stick; diff --git a/include/d/d_menu_skill.h b/include/d/d_menu_skill.h index 2f9097b165..d21332c341 100644 --- a/include/d/d_menu_skill.h +++ b/include/d/d_menu_skill.h @@ -58,7 +58,7 @@ public: u8 getStatus() { return mStatus; } -private: +// private: /* 0x004 */ JKRExpHeap* mpHeap; /* 0x008 */ JKRArchive* mpArchive; /* 0x00C */ STControl* mpStick; diff --git a/include/d/d_msg_out_font.h b/include/d/d_msg_out_font.h index 2b2d0fa33d..c6715757eb 100644 --- a/include/d/d_msg_out_font.h +++ b/include/d/d_msg_out_font.h @@ -25,7 +25,7 @@ public: void setTextBoxPtr(J2DTextBox* p_textBox) { mpTextBoxPtr = p_textBox; } void resetType() { mType = 0x47; } -private: +// private: /* 0x04 */ J2DTextBox* mpTextBoxPtr; /* 0x08 */ f32 mPosX; /* 0x0C */ f32 mPosY; @@ -53,7 +53,7 @@ public: void setRupeeColor(u8 color) { mRupeeColor = color; } -private: +// private: /* 0x004 */ COutFontSet_c* mpOfs[35]; /* 0x090 */ J2DPicture* mpPane[70]; /* 0x1A8 */ f32 mAlphaRatio; diff --git a/mods/basic_cosmetics_mod/src/hooks.cpp b/mods/basic_cosmetics_mod/src/hooks.cpp index 75f1cc93a5..95f26a5b71 100644 --- a/mods/basic_cosmetics_mod/src/hooks.cpp +++ b/mods/basic_cosmetics_mod/src/hooks.cpp @@ -11,16 +11,33 @@ #include "d/actor/d_a_alink.h" #include "d/actor/d_a_midna.h" +#include "d/d_bright_check.h" +#include "d/d_file_sel_info.h" +#include "d/d_file_select.h" #include "d/d_kankyo.h" #include "d/d_kantera_icon_meter.h" +#include "d/d_menu_collect.h" +#include "d/d_menu_fishing.h" +#include "d/d_menu_insect.h" +#include "d/d_menu_letter.h" +#include "d/d_menu_option.h" +#include "d/d_menu_ring.h" +#include "d/d_menu_save.h" +#include "d/d_menu_skill.h" +#include "d/d_meter_button.h" #include "d/d_meter2.h" #include "d/d_meter2_draw.h" #include "d/d_meter2_info.h" +#include "d/d_msg_out_font.h" #include "d/d_pane_class.h" #include "m_Do/m_Do_dvd_thread.h" +#include "SSystem/SComponent/c_phase.h" #include +#include "d/d_menu_fmap2D.h" + +// Main hook for recoloring textures on load DEFINE_HOOK_SYMBOL( "mDoDvdThd_mountArchive_c::execute", s32(mDoDvdThd_mountArchive_c*), MountArchiveExecute); void mount_archive_execute_post(ModContext*, void* args, void* retval, void* userdata) { @@ -28,29 +45,31 @@ void mount_archive_execute_post(ModContext*, void* args, void* retval, void* use handle_texture_overrides_on_load(archive); } -// Helper for getting lantern color -std::optional get_lantern_color() { - auto lanternColorStr = get_str_option(get_cvars().lanternGlowColor, ""); - if (is_valid_hex_color_str(lanternColorStr) || lanternColorStr == "rainbow") { - if (is_valid_hex_color_str(lanternColorStr)) { - return hex_color_str_to_gx_color(lanternColorStr); +// Helper for getting configVar color +static std::optional get_config_var_color(ConfigVarHandle handle, bool allowRainbow = false) { + auto colorStr = get_str_option(handle, ""); + if (is_valid_hex_color_str(colorStr) || (colorStr == "rainbow" && allowRainbow)) { + if (is_valid_hex_color_str(colorStr)) { + return hex_color_str_to_gx_color(colorStr); + } + + if (allowRainbow) { + // Assume rainbow if not a valid hex str + auto color = get_rainbow_rgb(127.5f); + color.r /= 2; + color.g /= 2; + color.b /= 2; + return color; } - - // Assume rainbow if not a valid hex str - auto lanternColor = get_rainbow_rgb(127.5f); - lanternColor.r /= 2; - lanternColor.g /= 2; - lanternColor.b /= 2; - return lanternColor; } return std::nullopt; } -// Override Lantern ambience color +// Lantern ambience color DEFINE_HOOK(&dKy_WolfEyeLight_set, WolfEyeLightSet); void wolf_eye_light_set_post(ModContext*, void* args, void* retval, void* userdata) { - auto maybeLanternColor = get_lantern_color(); + auto maybeLanternColor = get_config_var_color(get_cvars().lanternGlowColor, true); if (maybeLanternColor.has_value()) { auto lanternColor = maybeLanternColor.value(); @@ -61,10 +80,10 @@ void wolf_eye_light_set_post(ModContext*, void* args, void* retval, void* userda } } -// Override Lantern Sphere color +// Lantern Sphere color DEFINE_HOOK(&daAlink_c::preKandelaarDraw, PreKandelaarDraw); void pre_kandelaar_draw_post(ModContext*, void* args, void* retval, void* userdata) { - auto maybeLanternColor = get_lantern_color(); + auto maybeLanternColor = get_config_var_color(get_cvars().lanternGlowColor, true); if (maybeLanternColor.has_value()) { auto lanternColor = maybeLanternColor.value(); @@ -84,7 +103,7 @@ void pre_kandelaar_draw_post(ModContext*, void* args, void* retval, void* userda } } -// Override Main Lantern Meter Color +// Main Lantern Meter Color DEFINE_HOOK(&CPaneMgr::setBlackWhite, CPaneMgrSetBlackWhite); HookAction cpane_mgr_set_black_white_pre(ModContext*, void* args, void* retval, void* userdata) { // Check for magic meter @@ -101,7 +120,7 @@ HookAction cpane_mgr_set_black_white_pre(ModContext*, void* args, void* retval, return HOOK_CONTINUE; } - auto maybeLanternColor = get_lantern_color(); + auto maybeLanternColor = get_config_var_color(get_cvars().lanternGlowColor, true); if (maybeLanternColor.has_value()) { auto lanternColor = maybeLanternColor.value(); black = JUtility::TColor(lanternColor.r, lanternColor.g, lanternColor.b, 255); @@ -111,10 +130,10 @@ HookAction cpane_mgr_set_black_white_pre(ModContext*, void* args, void* retval, return HOOK_CONTINUE; } -// Override Lantern Icon Meter Color +// Lantern Icon Meter Color DEFINE_HOOK(&dKantera_icon_c::setNowGauge, KanteraIconSetNowGauge); void kantera_icon_set_now_gauge_post(ModContext*, void* args, void* retval, void* userdata) { - auto maybeLanternColor = get_lantern_color(); + auto maybeLanternColor = get_config_var_color(get_cvars().lanternGlowColor, true); if (maybeLanternColor.has_value()) { auto lanternColor = maybeLanternColor.value(); @@ -125,19 +144,15 @@ void kantera_icon_set_now_gauge_post(ModContext*, void* args, void* retval, void } } -// Override Light Sword Effect Color +// Light Sword Effect Color DEFINE_HOOK(&daAlink_c::setLightningSwordEffect, SetLightningSwordEffect); void set_lightning_sword_effect_post(ModContext*, void* args, void* retval, void* userdata) { - auto glowColorStr = get_str_option(get_cvars().lightSwordGlowColor, ""); - if (is_valid_hex_color_str(glowColorStr) || glowColorStr == "rainbow") { - GXColor glowColor{}; - if (glowColorStr == "rainbow") { - glowColor = get_rainbow_rgb(127.5f); - } else { - glowColor = hex_color_str_to_gx_color(glowColorStr); - } + auto maybeGlowColor = get_config_var_color(get_cvars().lightSwordGlowColor, true); + if (maybeGlowColor.has_value()) { + auto glowColor = maybeGlowColor.value(); auto link = mods::arg(args, 0); + // Check copied from inside the hooked function if (link->mEquipItem == 0x103 && link->checkNoResetFlg3(daPy_py_c::FLG3_UNK_100000)) { for (size_t i = 0; i < 3; i++) { auto emitter = dComIfGp_particle_getEmitter(link->field_0x327c[i]); @@ -150,36 +165,266 @@ void set_lightning_sword_effect_post(ModContext*, void* args, void* retval, void } } -// Heart Icon tags -static constexpr std::array heart_tags = { - MULTI_CHAR('hear_00'), MULTI_CHAR('hear_01'), MULTI_CHAR('hear_02'), MULTI_CHAR('hear_03'), MULTI_CHAR('hear_04'), MULTI_CHAR('hear_05'), MULTI_CHAR('hear_06'), - MULTI_CHAR('hear_07'), MULTI_CHAR('hear_08'), MULTI_CHAR('hear_09'), MULTI_CHAR('hear_10'), MULTI_CHAR('hear_11'), MULTI_CHAR('hear_12'), MULTI_CHAR('hear_13'), - MULTI_CHAR('hear_14'), MULTI_CHAR('hear_15'), MULTI_CHAR('hear_16'), MULTI_CHAR('hear_17'), MULTI_CHAR('hear_18'), MULTI_CHAR('hear_19'), MULTI_CHAR('bigh_00'), - MULTI_CHAR('bigh_01'), MULTI_CHAR('bigh_02'), MULTI_CHAR('bigh_03'), /*MULTI_CHAR('bigh_n')*/ -}; +void recolor_ui_button(ConfigVarHandle option, u64 tag, J2DScreen* screen) { + auto buttonColorStr = get_str_option(option, ""); + if (is_valid_hex_color_str(buttonColorStr)) { + auto color = hex_color_str_to_gx_color(buttonColorStr); + auto element = static_cast(screen->search(tag)); + if (element != nullptr) { + element->setBlackWhite(JUtility::TColor(0, 0, 0, 0), + JUtility::TColor(color.r, color.g, color.b, 0xFF)); + } + } +} +// Main gameplay UI. Top left hearts and top right buttons DEFINE_HOOK(&dMeter2Draw_c::init, dMeter2Init); -void d_meter_2_init_post(ModContext*, void* args, void* retval, void* userdata) { +void d_meter_2_init_post(ModContext*, void* args, void*, void*) { auto dMeter2Draw = mods::arg(args, 0); + auto screen = dMeter2Draw->getMainScreenPtr(); + + // Heart tags on main UI + static constexpr std::array kHeartTags = { + MULTI_CHAR('hear_00'), MULTI_CHAR('hear_01'), MULTI_CHAR('hear_02'), MULTI_CHAR('hear_03'), MULTI_CHAR('hear_04'), MULTI_CHAR('hear_05'), MULTI_CHAR('hear_06'), + MULTI_CHAR('hear_07'), MULTI_CHAR('hear_08'), MULTI_CHAR('hear_09'), MULTI_CHAR('hear_10'), MULTI_CHAR('hear_11'), MULTI_CHAR('hear_12'), MULTI_CHAR('hear_13'), + MULTI_CHAR('hear_14'), MULTI_CHAR('hear_15'), MULTI_CHAR('hear_16'), MULTI_CHAR('hear_17'), MULTI_CHAR('hear_18'), MULTI_CHAR('hear_19'), MULTI_CHAR('bigh_00'), + MULTI_CHAR('bigh_01'), MULTI_CHAR('bigh_02'), MULTI_CHAR('bigh_03') + }; + auto heartColorStr = get_str_option(get_cvars().heartColor, ""); if (is_valid_hex_color_str(heartColorStr)) { auto heartColor = hex_color_str_to_gx_color(heartColorStr); - auto screen = dMeter2Draw->getMainScreenPtr(); - for (auto tag : heart_tags) { + for (auto tag : kHeartTags) { auto element = static_cast(screen->search(tag)); if (element != nullptr) { element->setBlackWhite(heartColor, JUtility::TColor(200, 200, 200, 255)); } } } + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); + recolor_ui_button(get_cvars().xButtonColor, MULTI_CHAR('x_btn'), screen); + recolor_ui_button(get_cvars().yButtonColor, MULTI_CHAR('y_btn'), screen); + recolor_ui_button(get_cvars().zButtonColor, MULTI_CHAR('zbtn'), screen); +} + +// Hearts on the file select screen +DEFINE_HOOK(&dFile_info_c::setHeartCnt, FileInfoSetHeartCount); +void file_info_set_heart_count_post(ModContext*, void* args, void*, void*) { + auto fileInfo = mods::arg(args, 0); + + // Heart tags on file select + static constexpr std::array kFileSelectHeartTags { + MULTI_CHAR('hear_20'), MULTI_CHAR('hear_21'), MULTI_CHAR('hear_22'), MULTI_CHAR('hear_23'), MULTI_CHAR('hear_24'), MULTI_CHAR('hear_25'), MULTI_CHAR('hear_26'), + MULTI_CHAR('hear_27'), MULTI_CHAR('hear_28'), MULTI_CHAR('hear_29'), MULTI_CHAR('hear_30'), MULTI_CHAR('hear_31'), MULTI_CHAR('hear_32'), MULTI_CHAR('hear_33'), + MULTI_CHAR('hear_34'), MULTI_CHAR('hear_35'), MULTI_CHAR('hear_36'), MULTI_CHAR('hear_37'), MULTI_CHAR('hear_38'), MULTI_CHAR('hear_39'), + }; + + auto heartColorStr = get_str_option(get_cvars().heartColor, ""); + if (is_valid_hex_color_str(heartColorStr)) { + auto heartColor = hex_color_str_to_gx_color(heartColorStr); + for (auto tag : kFileSelectHeartTags) { + auto element = static_cast(fileInfo->mFileInfo.Scr->search(tag)); + if (element != nullptr) { + element->setBlackWhite(heartColor, JUtility::TColor(200, 200, 200, 255)); + } + } + } } -// Override Midna Hair Color +// Buttons that appear contextually at the bottom of the screen during gameplay +// (Are X, Y ever used there?) +DEFINE_HOOK(&dMeterButton_c::screenInitButton, ScreenInitButton); +void screen_init_button_post(ModContext*, void* args, void*, void*) { + auto meterButton = mods::arg(args, 0); + auto screen = meterButton->mpButtonScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn1'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); + recolor_ui_button(get_cvars().xButtonColor, MULTI_CHAR('x_btn'), screen); + recolor_ui_button(get_cvars().yButtonColor, MULTI_CHAR('y_btn'), screen); + recolor_ui_button(get_cvars().zButtonColor, MULTI_CHAR('zbtn'), screen); +} + +// A and B buttons when saving a file +DEFINE_HOOK(&dMenu_save_c::screenSet, MenuSaveScreenSet); +void menu_save_screen_set_post(ModContext*, void* args, void*, void*) { + auto menuSave = mods::arg(args, 0); + auto screen = menuSave->mSaveSel.Scr; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('wabtn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('wbbtn'), screen); +} + +// A and B buttons when selecting a file +DEFINE_HOOK(&dFile_select_c::screenSet, FileSelectScreenSet); +void file_select_screen_set_post(ModContext*, void* args, void*, void*) { + auto fileSelect = mods::arg(args, 0); + auto screen = fileSelect->fileSel.Scr; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('wabtn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('wbbtn'), screen); +} + +// A button on brightness check screen +DEFINE_HOOK(&dBrightCheck_c::screenSet, BrightCheckScreenSet); +void bright_check_screen_set_post(ModContext*, void* args, void*, void*) { + auto brightCheck = mods::arg(args, 0); + auto screen = brightCheck->mBrightCheck.Scr; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn1'), screen); +} + +// X and Y buttons on the item wheel screen +DEFINE_HOOK(&dMenu_Ring_c::_create, MenuRingCreate); +void menu_ring_create_post(ModContext*, void* args, void*, void*) { + auto menuRing = mods::arg(args, 0); + auto screen = menuRing->mpScreen; + + recolor_ui_button(get_cvars().xButtonColor, MULTI_CHAR('xbtn'), screen); + recolor_ui_button(get_cvars().yButtonColor, MULTI_CHAR('ybtn'), screen); +} + +// A and B buttons on the main pause screen +DEFINE_HOOK(&dMenu_Collect2D_c::_create, MenuCollect2DCreate); +void menu_collect_2D_create_post(ModContext*, void* args, void*, void*) { + auto menuCollect2D = mods::arg(args, 0); + auto screen = menuCollect2D->mpScreenIcon; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); +} + +// A and B buttons on the fishing journal screen +DEFINE_HOOK(&dMenu_Fishing_c::screenSetDoIcon, MenuFishingScreenSetDoIcon); +void menu_fishing_screen_set_do_icon_post(ModContext*, void* args, void*, void*) { + auto menuFishing = mods::arg(args, 0); + auto screen = menuFishing->mpIconScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); +} + +// A and B buttons on the insect collection screen +DEFINE_HOOK(&dMenu_Insect_c::screenSetDoIcon, MenuInsectScreenSetDoIcon); +void menu_insect_screen_set_do_icon_post(ModContext*, void* args, void*, void*) { + auto menuInsect = mods::arg(args, 0); + auto screen = menuInsect->mpIconScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); +} + +// A and B buttons on the letters screen +DEFINE_HOOK(&dMenu_Letter_c::screenSetDoIcon, MenuLetterScreenSetDoIcon); +void menu_letter_screen_set_do_icon_post(ModContext*, void* args, void*, void*) { + auto menuLetter = mods::arg(args, 0); + auto screen = menuLetter->mpIconScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); +} + +// A, B, and Z buttons on option screen +DEFINE_HOOK(&dMenu_Option_c::_create, MenuOptionCreate); +void menu_option_create_post(ModContext*, void* args, void*, void*) { + auto menuOption = mods::arg(args, 0); + auto screen = menuOption->mpScreenIcon; + auto backScreen = menuOption->mpBackScreen; + auto tvScreen = menuOption->mpTVScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); + recolor_ui_button(get_cvars().zButtonColor, MULTI_CHAR('g_zbtn'), backScreen); + + // A Button on option's brightness check screen + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn1'), tvScreen); +} + +// A and B buttons on the hidden skills screen +DEFINE_HOOK(&dMenu_Skill_c::screenSetDoIcon, MenuSkillScreenSetDoIcon); +void menu_skill_screen_set_do_icon_post(ModContext*, void* args, void*, void*) { + auto menuSkill = mods::arg(args, 0); + auto screen = menuSkill->mpIconScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn'), screen); +} + +// A, B, and Z buttons on the map screen +DEFINE_HOOK(&dMenu_Fmap_c::_create, MenuFMapCreate); +void menu_fmap_create_post(ModContext*, void* args, void*, void*) { + auto menuFMap = mods::arg(args, 0); + auto screen = menuFMap->mpDraw2DTop->mpTitleScreen; + + recolor_ui_button(get_cvars().aButtonColor, MULTI_CHAR('a_btn'), screen); + recolor_ui_button(get_cvars().bButtonColor, MULTI_CHAR('b_btn1'), screen); + recolor_ui_button(get_cvars().zButtonColor, MULTI_CHAR('zbtn'), screen); +} + +// A, B, X, and Y button icons in text +DEFINE_HOOK(&COutFont_c::createPane, OutFontCreatePane); +void out_font_create_pane_post(ModContext*, void* args, void*, void*) { + auto outFont = mods::arg(args, 0); + auto paneArr = outFont->mpPane; + + auto maybeAButtonColor = get_config_var_color(get_cvars().aButtonColor); + if (maybeAButtonColor.has_value()) { + auto aButtonColor = maybeAButtonColor.value(); + paneArr[0]->setBlackWhite( + JUtility::TColor(255, 255, 255, 0), + JUtility::TColor(aButtonColor.r,aButtonColor.g,aButtonColor.b, 255)); + } + + auto maybeBButtonColor = get_config_var_color(get_cvars().bButtonColor); + if (maybeBButtonColor.has_value()) { + auto bButtonColor = maybeBButtonColor.value(); + paneArr[1]->setBlackWhite( + JUtility::TColor(255, 255, 255, 0), + JUtility::TColor(bButtonColor.r,bButtonColor.g,bButtonColor.b, 255)); + } + + // Condition copied from hooked function + auto xyBlack = JUtility::TColor(255, 255, 255, 0); + if (outFont->field_0x242 == 1) { + xyBlack = JUtility::TColor(0, 0, 0, 0); + } + + auto maybeXButtonColor = get_config_var_color(get_cvars().xButtonColor); + if (maybeXButtonColor.has_value()) { + auto xButtonColor = maybeXButtonColor.value(); + paneArr[5]->setBlackWhite(xyBlack, JUtility::TColor(xButtonColor.r,xButtonColor.g,xButtonColor.b, 255)); + } + + auto maybeYButtonColor = get_config_var_color(get_cvars().yButtonColor); + if (maybeYButtonColor.has_value()) { + auto yButtonColor = maybeYButtonColor.value(); + paneArr[6]->setBlackWhite(xyBlack, JUtility::TColor(yButtonColor.r,yButtonColor.g,yButtonColor.b, 255)); + } +} + +// Heart icon in text +DEFINE_HOOK(&COutFontSet_c::drawFont, OutFontSetDrawFont); +void out_font_set_draw_font_post(ModContext*, void* args, void*, void*) { + auto outFontSet = mods::arg(args, 0); + + auto maybeHeartColor = get_config_var_color(get_cvars().heartColor); + if (maybeHeartColor.has_value()) { + auto heartColor = maybeHeartColor.value(); + u32 heartColor_u32 = heartColor.r << 24 | heartColor.g << 16 | heartColor.b << 8 | 0xFF; + if (outFontSet->getType() == 0x1B) { // Heart icon type + outFontSet->mColor = heartColor_u32; + } + } +} + +// Midna Hair Color DEFINE_HOOK(&daMidna_c::create, MidnaCreate); -void midna_create_post(ModContext*, void* args, void* retval, void* userdata) { +void midna_create_post(ModContext*, void* args, void* retval, void*) { auto step = reinterpret_cast(retval); - // check for cPhs_Compleate - if (*step != 4) { + // Don't set colors if midna isn't done loading + if (*step != cPhs_COMPLEATE_e) { return; } @@ -268,7 +513,7 @@ void midna_set_body_part_matrix_post(ModContext*, void* args, void* retval, void } } -// Override Midna Charge Ring Color +// Midna Charge Ring Color DEFINE_HOOK(&daAlink_c::setWolfLockDomeModel, SetWolfLockDomeModel); void wolf_lock_dome_model_post(ModContext*, void* args, void* retval, void* userdata) { auto domeRingColorStr = get_str_option(get_cvars().midnaChargeRingColor, ""); @@ -295,72 +540,62 @@ void wolf_lock_dome_model_post(ModContext*, void* args, void* retval, void* user } } +#define ADD_POST_HOOK(defined_hook, function, original) \ + result = mods::hook::add_post(function); \ + if (result != MOD_OK) { \ + mods::log::debug("failed to add post hook to" #original ", Result {}", static_cast(result)); \ + return result; \ + } + +#define ADD_PRE_HOOK(defined_hook, function, original) \ + result = mods::hook::add_pre(function); \ + if (result != MOD_OK) { \ + mods::log::debug("failed to add pre hook to" #original ", Result {}", static_cast(result)); \ + return result; \ + } + ModResult add_all_hooks() { - auto result = mods::hook::add_post(mount_archive_execute_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to mountArchive_execute, Result {}", static_cast(result)); - return result; - } + ModResult result{}; - result = mods::hook::add_post(wolf_eye_light_set_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to dKy_WolfEyeLight_set, Result {}", static_cast(result)); - return result; - } + // Main hook for texture recoloring + ADD_POST_HOOK(MountArchiveExecute, mount_archive_execute_post, mountArchive_execute) - result = mods::hook::add_post(pre_kandelaar_draw_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to daAlink_c::preKandelaarDraw, Result {}", static_cast(result)); - return result; - } + // Hooks for lantern glow + ADD_POST_HOOK(WolfEyeLightSet, wolf_eye_light_set_post, dKy_WolfEyeLight_set) + ADD_POST_HOOK(PreKandelaarDraw, pre_kandelaar_draw_post, daAlink_c::preKandelaarDraw) - result = mods::hook::add_post(wolf_lock_dome_model_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to daAlink_c::setWolfLockDomeModel, Result {}", static_cast(result)); - return result; - } + // Hooks for lantern meter color + ADD_PRE_HOOK(CPaneMgrSetBlackWhite, cpane_mgr_set_black_white_pre, CPaneMgr::setBlackWhite) + ADD_POST_HOOK(KanteraIconSetNowGauge, kantera_icon_set_now_gauge_post, dKantera_icon_c::setNowGauge) - result = mods::hook::add_pre(cpane_mgr_set_black_white_pre); - if (result != MOD_OK) { - mods::log::debug("failed to add pre hook to CPaneMgr::setBlackWhite, Result {}", static_cast(result)); - return result; - } + // Hook for midna charge ring + ADD_POST_HOOK(SetWolfLockDomeModel, wolf_lock_dome_model_post, daAlink_c::setWolfLockDomeModel) - result = mods::hook::add_post(kantera_icon_set_now_gauge_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to dKantera_icon_c::setNowGauge, Result {}", static_cast(result)); - return result; - } + // Hook for light sword glow + ADD_POST_HOOK(SetLightningSwordEffect, set_lightning_sword_effect_post, daAlink_c::setLightningSwordEffect) - result = mods::hook::add_post(set_lightning_sword_effect_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to daAlink_c::setLightningSwordEffect, Result {}", static_cast(result)); - return result; - } + // Hooks for Midna Hair Color + ADD_POST_HOOK(MidnaCreate, midna_create_post, daMidna_c::create) + ADD_PRE_HOOK(MidnaSetBodyPartMatrix, midna_set_body_part_matrix_pre, daMidna_c::setBodyPartMatrix) + ADD_POST_HOOK(MidnaSetBodyPartMatrix, midna_set_body_part_matrix_post, daMidna_c::setBodyPartMatrix) - result = mods::hook::add_post(midna_create_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to daMidna_c::create, Result {}", static_cast(result)); - return result; - } - - result = mods::hook::add_pre(midna_set_body_part_matrix_pre); - if (result != MOD_OK) { - mods::log::debug("failed to add pre hook to daMidna_c::setBodyPartMatrix, Result {}", static_cast(result)); - return result; - } - - result = mods::hook::add_post(midna_set_body_part_matrix_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to daMidna_c::setBodyPartMatrix, Result {}", static_cast(result)); - return result; - } - - result = mods::hook::add_post(d_meter_2_init_post); - if (result != MOD_OK) { - mods::log::debug("failed to add post hook to dMeter2Draw_c::init, Result {}", static_cast(result)); - return result; - } + // Hooks for UI colors + ADD_POST_HOOK(dMeter2Init, d_meter_2_init_post, dMeter2Draw_c::init) + ADD_POST_HOOK(FileInfoSetHeartCount, file_info_set_heart_count_post, dFile_info_c::setHeartCnt) + ADD_POST_HOOK(ScreenInitButton, screen_init_button_post, dMeterButton_c::screenInitButton) + ADD_POST_HOOK(MenuSaveScreenSet, menu_save_screen_set_post, dMenu_save_c::screenSet) + ADD_POST_HOOK(FileSelectScreenSet, file_select_screen_set_post, dFile_select_c::screenSet) + ADD_POST_HOOK(BrightCheckScreenSet, bright_check_screen_set_post, dBrightCheck_c::screenSet) + ADD_POST_HOOK(MenuRingCreate, menu_ring_create_post, dMenu_Ring_c::_create) + ADD_POST_HOOK(MenuCollect2DCreate, menu_collect_2D_create_post, dMenu_Collect2D_c::_create) + ADD_POST_HOOK(MenuFishingScreenSetDoIcon, menu_fishing_screen_set_do_icon_post, dMenu_Fishing_c::screenSetDoIcon) + ADD_POST_HOOK(MenuInsectScreenSetDoIcon, menu_insect_screen_set_do_icon_post, dMenu_Insect_c::screenSetDoIcon) + ADD_POST_HOOK(MenuLetterScreenSetDoIcon, menu_letter_screen_set_do_icon_post, dMenu_Letter_c::screenSetDoIcon) + ADD_POST_HOOK(MenuOptionCreate, menu_option_create_post, dMenu_Option_c::_create) + ADD_POST_HOOK(MenuSkillScreenSetDoIcon, menu_skill_screen_set_do_icon_post, dMenu_Skill_c::screenSetDoIcon) + ADD_POST_HOOK(OutFontCreatePane, out_font_create_pane_post, COutFont_c::createPane) + ADD_POST_HOOK(OutFontSetDrawFont, out_font_set_draw_font_post, COutFontSet_c::drawFont) + ADD_POST_HOOK(MenuFMapCreate, menu_fmap_create_post, dMenu_Fmap_c::_create) return MOD_OK; } \ No newline at end of file diff --git a/mods/basic_cosmetics_mod/src/mod.cpp b/mods/basic_cosmetics_mod/src/mod.cpp index 9cf961279c..27d573e419 100644 --- a/mods/basic_cosmetics_mod/src/mod.cpp +++ b/mods/basic_cosmetics_mod/src/mod.cpp @@ -70,13 +70,6 @@ ModResult register_int_option( return MOD_OK; } -void add_control(UiElementHandle pane, const UiControlDesc& desc) { - auto result = svc_ui->pane_add_control(mod_ctx, pane, &desc, nullptr); - if (result != MOD_OK) { - mods::log::debug("pane_add_control failed {}", static_cast(result)); - } -} - const char* kDefaultHexColorsExplanation = "Set the color with any 6 digit hex code. A reload will be required to see changes.
" "Common colors:
" @@ -91,7 +84,7 @@ const char* kDefaultHexColorsExplanation = "- Brown: 91723e
"; const char* kGlowColorsExplanation = - "Set the color with any 6 digit hex code, or with \"rainbow\" for a rainbow effect.
" + "Set the color of the lantern light with any 6 digit hex code, or with \"rainbow\" for a rainbow effect.
" "Common colors:
" "- Red: ff0000
" "- Orange: f68821
" @@ -113,8 +106,82 @@ const char* kMasterSwordColorsExplanation = "- White: a0a0a0
" "- Cyan: 30d0d0
"; +const char* kAButtonColorsExplanation = + "Set the color of the A button with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Red: ff0000
" + "- Orange: ff5000
" + "- Yellow: ffaf00
" + "- Dark Green: 0080ff
" + "- Blue: 0000ff
" + "- Purple: 8000ff
" + "- Grey: 5555ff
" + "- Pink: ff20ff
"; + +const char* kBButtonColorsExplanation = + "Set the color of the B button with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Orange: ffff40
" + "- Pink: ffa0ff
" + "- Green: 00e87b
" + "- Blue: 00aaff
" + "- Purple: 6078ff
" + "- Black: 000000
" + "- Teal: 00f3ff
"; + +const char* kXButtonColorsExplanation = + "Set the color of the X button with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Red: ff0000
" + "- Orange: ff8200
" + "- Yellow: f7df00
" + "- Lime Green: 70ff00
" + "- Dark Green: 00bd11
" + "- Blue: 0000ff
" + "- Purple: 800088
" + "- Black: 000000
" + "- Pink: ff00aa
" + "- Cyan: 00ffff
"; + +const char* kYButtonColorsExplanation = + "Set the color of the Y button with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Red: ff0000
" + "- Orange: ff8200
" + "- Yellow: f7df00
" + "- Lime Green: 70ff00
" + "- Dark Green: 00bd11
" + "- Blue: 0000ff
" + "- Purple: 800088
" + "- Black: 000000
" + "- Pink: ff00aa
" + "- Cyan: 00ffff
"; + +const char* kZButtonColorsExplanation = + "Set the Z button color with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Red: ff0000
" + "- Orange: ff8200
" + "- Yellow: f7df00
" + "- Lime Green: 70ff00
" + "- Dark Green: 00bd11
" + "- Purple: 800088
" + "- Black: 000000
" + "- Light Blue: 00ffff
"; + +const char* kHeartColorsExplanation = + "Set the heart color with any 6 digit hex code. A reload may be necessary to see changes.
" + "Common colors:
" + "- Orange: ffff40
" + "- Pink: ffa0ff
" + "- Green: 00e87b
" + "- Blue: 00aaff
" + "- Purple: 6078ff
" + "- Black: 000000
" + "- Teal: 00f3ff
"; + const char* kChargeRingColorsExplanation = - "Set the color with any 6 digit hex code.
" + "Set the color of Midna's charge ring with any 6 digit hex code.
" "Common colors:
" "- Pink: ff9f9f
" "- Red: ff0000
" @@ -126,6 +193,13 @@ const char* kChargeRingColorsExplanation = "- White: feffff
" "- Black: 000000
"; +void add_control(UiElementHandle pane, const UiControlDesc& desc) { + auto result = svc_ui->pane_add_control(mod_ctx, pane, &desc, nullptr); + if (result != MOD_OK) { + mods::log::debug("pane_add_control failed {}", static_cast(result)); + } +} + void add_cosmetic_option(UiElementHandle left, ConfigVarHandle cvar, const char* name, const char* helpRml) { UiControlDesc control = UI_CONTROL_DESC_INIT; control.kind = UI_CONTROL_STRING; @@ -191,7 +265,12 @@ ModResult build_ui_colors_tab( ModContext*, UiWindowHandle, UiElementHandle left, UiElementHandle right, void*, ModError*) { (void)right; - add_cosmetic_option(left, g_cvars.heartColor, "Heart Color", kDefaultHexColorsExplanation); + add_cosmetic_option(left, g_cvars.aButtonColor, "A Button Color", kAButtonColorsExplanation); + add_cosmetic_option(left, g_cvars.bButtonColor, "B Button Color", kBButtonColorsExplanation); + add_cosmetic_option(left, g_cvars.xButtonColor, "X Button Color", kXButtonColorsExplanation); + add_cosmetic_option(left, g_cvars.yButtonColor, "Y Button Color", kYButtonColorsExplanation); + add_cosmetic_option(left, g_cvars.zButtonColor, "Z Button Color", kZButtonColorsExplanation); + add_cosmetic_option(left, g_cvars.heartColor, "Heart Color", kHeartColorsExplanation); return MOD_OK; } @@ -272,6 +351,11 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) { REGISTER_COSMETIC_OPTION(boomerangColor) REGISTER_COSMETIC_OPTION(ironBootsColor) REGISTER_COSMETIC_OPTION(spinnerColor) + REGISTER_COSMETIC_OPTION(aButtonColor) + REGISTER_COSMETIC_OPTION(bButtonColor) + REGISTER_COSMETIC_OPTION(xButtonColor) + REGISTER_COSMETIC_OPTION(yButtonColor) + REGISTER_COSMETIC_OPTION(zButtonColor) REGISTER_COSMETIC_OPTION(heartColor) result = register_int_option("midnaHairBaseColor", 0, g_cvars.midnaHairBaseColor, error); diff --git a/mods/basic_cosmetics_mod/src/mod.hpp b/mods/basic_cosmetics_mod/src/mod.hpp index aa184d7a1f..113364e4d2 100644 --- a/mods/basic_cosmetics_mod/src/mod.hpp +++ b/mods/basic_cosmetics_mod/src/mod.hpp @@ -22,6 +22,11 @@ struct cvars { ConfigVarHandle ironBootsColor = 0; ConfigVarHandle spinnerColor = 0; ConfigVarHandle heartColor = 0; + ConfigVarHandle aButtonColor = 0; + ConfigVarHandle bButtonColor = 0; + ConfigVarHandle xButtonColor = 0; + ConfigVarHandle yButtonColor = 0; + ConfigVarHandle zButtonColor = 0; ConfigVarHandle midnaHairBaseColor = 0; ConfigVarHandle midnaHairTipsColor = 0; ConfigVarHandle midnaChargeRingColor = 0;