From fa660ebd0f119d6f1bcc7137e64ff4b39b678562 Mon Sep 17 00:00:00 2001 From: TakaRikka Date: Wed, 20 May 2026 03:19:25 -0700 Subject: [PATCH] fmap poe counter --- include/d/d_menu_fmap2D.h | 7 +++ include/d/d_menu_map_common.h | 5 ++ include/dusk/settings.h | 1 + src/d/d_menu_fmap.cpp | 10 ++++ src/d/d_menu_fmap2D.cpp | 49 ++++++++++++++++ src/d/d_menu_map_common.cpp | 106 ++++++++++++++++++++++++++++++++++ src/dusk/settings.cpp | 2 + src/dusk/ui/preset.cpp | 1 + src/dusk/ui/settings.cpp | 2 + 9 files changed, 183 insertions(+) diff --git a/include/d/d_menu_fmap2D.h b/include/d/d_menu_fmap2D.h index 7df78bb6d0..aa64129ccf 100644 --- a/include/d/d_menu_fmap2D.h +++ b/include/d/d_menu_fmap2D.h @@ -421,6 +421,13 @@ public: /* 0xC2 */ u8 mAlphaButtonZ; /* 0xC3 */ u8 mAlphaAnalogStick; /* 0xC4 */ u8 mAlphaDpad; + +#if TARGET_PC + J2DTextBox* mpPoeCountPane; + ResTIMG* mpPoeCountIconTex; + J2DPicture* mpPoeCountIcon; + u8 mSelectRegionNo; +#endif }; #endif /* D_MENU_D_MENU_FMAP2D_H */ diff --git a/include/d/d_menu_map_common.h b/include/d/d_menu_map_common.h index de50d775ca..55de3d0f6c 100644 --- a/include/d/d_menu_map_common.h +++ b/include/d/d_menu_map_common.h @@ -76,6 +76,11 @@ public: } #endif +#if TARGET_PC + static void getDmapPoeCount(const std::string& stageName, int& nowCount, int& totalCount); + static void getFmapPoeCount(const int regionNo, int& nowCount, int& totalCount); +#endif + struct Stage_c { // Incomplete class diff --git a/include/dusk/settings.h b/include/dusk/settings.h index 0d85b714a5..1c77ae992b 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -133,6 +133,7 @@ struct UserSettings { ConfigVar instantText; ConfigVar sunsSong; ConfigVar autoSave; + ConfigVar showMapPoeCounter; // Preferences ConfigVar enableMirrorMode; diff --git a/src/d/d_menu_fmap.cpp b/src/d/d_menu_fmap.cpp index 72b97ddbc2..eef18ba91c 100644 --- a/src/d/d_menu_fmap.cpp +++ b/src/d/d_menu_fmap.cpp @@ -525,6 +525,16 @@ void dMenu_Fmap_c::_move() { } mpDraw2DBack->setSpotTextureFadeAlpha(mSpotTextureFadeAlpha); } + +#if TARGET_PC + u8 region = mpDraw2DBack->getSelectRegion(); + if (region != 0xFF && mpDraw2DBack->isShowRegion(region)) { + mpDraw2DTop->mSelectRegionNo = region; + } else { + mpDraw2DTop->mSelectRegionNo = 0xFF; + } + +#endif } void dMenu_Fmap_c::_draw() { diff --git a/src/d/d_menu_fmap2D.cpp b/src/d/d_menu_fmap2D.cpp index a63f6ec282..39ec07e5d7 100644 --- a/src/d/d_menu_fmap2D.cpp +++ b/src/d/d_menu_fmap2D.cpp @@ -2482,6 +2482,18 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { set3DStickString(0x524); #endif +#if TARGET_PC + mpPoeCountIcon = JKR_NEW J2DPicture((ResTIMG*)JKRGetNameResource("ni_item_icon_pou.bti", dComIfGp_getItemIconArchive())); + + mpPoeCountPane = JKR_NEW J2DTextBox(); + if (mpPoeCountPane != nullptr) { + mpPoeCountPane->setFontSize(15.0f, 15.0f); + mpPoeCountPane->setFont(mDoExt_getMesgFont()); + } + + mSelectRegionNo = 0xFF; +#endif + setHIO(true); } @@ -2540,6 +2552,14 @@ dMenu_Fmap2DTop_c::~dMenu_Fmap2DTop_c() { } JKR_DELETE(mpAnm); mpAnm = NULL; + +#if TARGET_PC + JKR_DELETE(mpPoeCountIcon); + mpPoeCountIcon = NULL; + + JKR_DELETE(mpPoeCountPane); + mpPoeCountPane = NULL; +#endif } void dMenu_Fmap2DTop_c::_execute() { @@ -2636,6 +2656,35 @@ void dMenu_Fmap2DTop_c::draw() { ctx->scissor(mTransX, 0.0f, FB_WIDTH, FB_HEIGHT); ctx->setScissor(); mpTitleScreen->draw(mTransX, mTransY, ctx); + +#if TARGET_PC + if (dusk::getSettings().game.showMapPoeCounter) { + int nowPoeCount = 0; + int totalPoeCount = 0; + dMenuMapCommon_c::getFmapPoeCount(mSelectRegionNo, nowPoeCount, totalPoeCount); + if (dComIfGs_isEventBit(dSv_event_flag_c::F_0456) && totalPoeCount > 0) { + const f32 x = mTransX + mDoGph_gInf_c::ScaleHUDXRight(485.0f); + const f32 y = 380.0f; + constexpr f32 iconsize = 48.0f * 0.8f; + + if (mpPoeCountIcon != nullptr) + mpPoeCountIcon->draw(x - 35.0f, y - 25.0f, iconsize, iconsize, false, false, false); + + char counter_text[6]; + snprintf(counter_text, sizeof(counter_text), "%d/%d", nowPoeCount, totalPoeCount); + mpPoeCountPane->setString(counter_text); + + mpPoeCountPane->setCharColor(0x000000FF); + mpPoeCountPane->setGradColor(0x000000FF); + mpPoeCountPane->draw(x + 1, y + 1, FB_WIDTH, HBIND_LEFT); + + mpPoeCountPane->setCharColor(0xC8C8C8FF); + mpPoeCountPane->setGradColor(0xC8C8C8FF); + mpPoeCountPane->draw(x, y, FB_WIDTH, HBIND_LEFT); + } + } +#endif + ctx->scissor(scissor_left, scissor_top, scissor_width, scissor_height); ctx->setScissor(); if (mpScrnExplain) { diff --git a/src/d/d_menu_map_common.cpp b/src/d/d_menu_map_common.cpp index 0017975c4e..feed9310ef 100644 --- a/src/d/d_menu_map_common.cpp +++ b/src/d/d_menu_map_common.cpp @@ -747,3 +747,109 @@ void dMenuMapCommon_c::debugIcon() { setIconInfo(ICON_LV8_WARP_e, pos_x, pos_y, 0.0f, scale, 1.0f, 1); } } + +#if TARGET_PC +static constexpr struct { + std::string stagename; + u8 switch_no; + s8 region_id; + u8 save_id; +} l_poeInfo[] = { + // Dungeons + {"D_MN06", 0x19, -1, 0x15}, + {"D_MN06", 0x18, -1, 0x15}, + {"D_MN07", 0x54, -1, 0x16}, + {"D_MN07", 0x55, -1, 0x16}, + {"D_MN10", 0x1E, -1, 0x13}, + {"D_MN10", 0x1F, -1, 0x13}, + {"D_MN10", 0x20, -1, 0x13}, + {"D_MN10", 0x21, -1, 0x13}, + {"D_MN11", 0x72, -1, 0x14}, + {"D_MN11", 0x15, -1, 0x14}, + {"D_MN11", 0x7F, -1, 0x14}, + + // Sub-Dungeons + {"D_SB01", 0x45, 4, 0x19}, + {"D_SB01", 0x46, 4, 0x19}, + {"D_SB01", 0x47, 4, 0x19}, + {"D_SB02", 0x60, 2, 0x19}, + {"D_SB03", 0x5E, 3, 0x1A}, + {"D_SB03", 0x5F, 3, 0x1A}, + {"D_SB03", 0x5D, 3, 0x1A}, + {"D_SB05", 0xA, 3, 0x1B}, + {"D_SB05", 0xB, 3, 0x1B}, + {"D_SB07", 0xF, 4, 0x1B}, + {"D_SB07", 0x10, 4, 0x1B}, + + // Field Spots + {"F_SP108", 0x5D, 1, 0x2}, + {"F_SP109", 0x5E, 2, 0x3}, + {"F_SP109", 0x5F, 2, 0x3}, + {"F_SP110", 0x59, 2, 0x3}, + {"F_SP111", 0x57, 2, 0x3}, + {"F_SP111", 0x58, 2, 0x3}, + {"F_SP113", 0x49, 3, 0x4}, + {"F_SP113", 0x4A, 3, 0x4}, + {"F_SP114", 0x7C, 5, 0x8}, + {"F_SP114", 0x7D, 5, 0x8}, + {"F_SP114", 0x7B, 5, 0x8}, + {"F_SP114", 0x7E, 5, 0x8}, + {"F_SP114", 0x7F, 5, 0x8}, + {"F_SP115", 0x46, 3, 0x4}, + {"F_SP115", 0x47, 3, 0x4}, + {"F_SP115", 0x4B, 3, 0x4}, + {"F_SP115", 0x4C, 3, 0x4}, + {"F_SP115", 0x4D, 3, 0x4}, + {"F_SP117", 0xF, 1, 0x7}, + {"F_SP117", 0x1E, 1, 0x7}, + {"F_SP117", 0x10, 1, 0x7}, + {"F_SP117", 0x11, 1, 0x7}, + {"F_SP118", 0x78, 4, 0xA}, + {"F_SP118", 0x5A, 4, 0xA}, + {"F_SP121", 0x3A, 2, 0x6}, + {"F_SP121", 0x39, 1, 0x6}, + {"F_SP121", 0x33, 3, 0x6}, + {"F_SP121", 0x3B, 3, 0x6}, + {"F_SP122", 0x49, 3, 0x6}, + {"F_SP122", 0x30, 3, 0x6}, + {"F_SP122", 0x47, 3, 0x6}, + {"F_SP124", 0x5B, 4, 0xA}, + {"F_SP124", 0x5C, 4, 0xA}, + {"F_SP124", 0x5D, 4, 0xA}, + {"F_SP124", 0x33, 4, 0xA}, + {"F_SP126", 0x48, 3, 0x4}, + {"F_SP128", 0x40, 2, 0x3}, + {"R_SP160", 0x1F, 3, 0x9}, +}; + +void dMenuMapCommon_c::getDmapPoeCount(const std::string& stageName, int& nowCount, int& totalCount) { + nowCount = 0; + totalCount = 0; + + for (const auto& i : l_poeInfo) { + if (stageName == i.stagename) { + nowCount += dComIfGs_isSaveSwitch(i.save_id, i.switch_no); + totalCount++; + } + } +} + +void dMenuMapCommon_c::getFmapPoeCount(const int regionNo, int& nowCount, int& totalCount) { + nowCount = 0; + totalCount = 0; + + if (regionNo < 0) + return; + + for (const auto& i : l_poeInfo) { + if (regionNo == i.region_id) { + if (dStage_stagInfo_GetSaveTbl(dComIfGp_getStageStagInfo()) == i.save_id) { + nowCount += dComIfGs_isSwitch(i.switch_no, -1); + } else { + nowCount += dComIfGs_isSaveSwitch(i.save_id, i.switch_no); + } + totalCount++; + } + } +} +#endif \ No newline at end of file diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index e9768e9250..05e1217322 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -45,6 +45,7 @@ UserSettings g_userSettings = { .instantText {"game.instantText", false}, .sunsSong {"game.sunsSong", false}, .autoSave {"game.autoSave", false}, + .showMapPoeCounter {"game.showMapPoeCounter", false}, // Preferences .enableMirrorMode {"game.enableMirrorMode", false}, @@ -211,6 +212,7 @@ void registerSettings() { Register(g_userSettings.game.instantText); Register(g_userSettings.game.sunsSong); Register(g_userSettings.game.autoSave); + Register(g_userSettings.game.showMapPoeCounter); Register(g_userSettings.game.enableMirrorMode); Register(g_userSettings.game.invertCameraXAxis); Register(g_userSettings.game.invertCameraYAxis); diff --git a/src/dusk/ui/preset.cpp b/src/dusk/ui/preset.cpp index e5af8f2d50..ef11d9b857 100644 --- a/src/dusk/ui/preset.cpp +++ b/src/dusk/ui/preset.cpp @@ -47,6 +47,7 @@ void applyPresetDusk() { s.game.shadowResolutionMultiplier.setValue(4); s.game.enableGyroAim.setValue(true); s.game.autoSave.setValue(true); + s.game.showMapPoeCounter.setValue(true); } } // namespace diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index 6187f97d4b..a38003e129 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -1161,6 +1161,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { "Link will not recoil when his sword hits walls."); addOption("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat, "Skip needing to catch a second fish for Sera's cat."); + addOption("Show Poe Count on Map", getSettings().game.showMapPoeCounter, + "Displays collected/total number of Poe Souls for a region on the map."); addSpeedrunDisabledOption("Sun's Song (R+X)", getSettings().game.sunsSong, "Allows Wolf Link to howl and change the time of day."); addOption("Quick Transform (R+Y)", getSettings().game.enableQuickTransform,