diff --git a/soh/soh/Enhancements/cosmetics/FileSelectMoreInfo.cpp b/soh/soh/Enhancements/cosmetics/FileSelectMoreInfo.cpp new file mode 100644 index 000000000..b54b7b146 --- /dev/null +++ b/soh/soh/Enhancements/cosmetics/FileSelectMoreInfo.cpp @@ -0,0 +1,809 @@ +#include "z64.h" +#include "textures/icon_item_static/icon_item_static.h" +#include "textures/icon_item_24_static/icon_item_24_static.h" +#include "textures/icon_item_dungeon_static/icon_item_dungeon_static.h" +#include "textures/parameter_static/parameter_static.h" +#include "textures/nes_font_static/nes_font_static.h" +#include "soh_assets.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/SaveManager.h" +#include "soh/frame_interpolation.h" +#include "ship/utils/color.h" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "src/overlays/gamestates/ovl_file_choose/file_choose.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "assets/textures/title_static/title_static.h" + +/* + * TODO: + * Ocarina Buttons + * Swim + * Keys + * Boss Keys + * Boss Souls + */ + +#define Save_GetSaveMetaInfo(fileIndex) (&SaveManager::Instance->fileMetaInfo[fileIndex]) + +typedef struct IconPosition { + s16 left; + s16 top; +} IconPosition; + +typedef struct IconSize { + s16 width; + s16 height; +} IconSize; + +typedef struct ItemData { + Sprite sprite; + Color_RGBA8 color; + u8 item; + IconPosition pos; + IconSize size; +} ItemData; + +#define CREATE_SPRITE_24(iconTex, spriteId) \ + { iconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, spriteId }, { \ + 0xFF, 0xFF, 0xFF, 0xFF \ + } +#define CREATE_SPRITE_32(iconTex, spriteId) \ + { iconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, spriteId }, { \ + 0xFF, 0xFF, 0xFF, 0xFF \ + } +#define CREATE_SPRITE_SONG(colorR, colorG, colorB) \ + { dgSongNoteTex, 16, 24, G_IM_FMT_IA, G_IM_SIZ_8b, 100 }, { \ + colorR, colorG, colorB, 0xFF \ + } +#define CREATE_SPRITE_RUPEE(colorR, colorG, colorB) \ + { dgRupeeCounterIconTex, 16, 16, G_IM_FMT_IA, G_IM_SIZ_8b, 102 }, { \ + colorR, colorG, colorB, 0xFF \ + } +#define CREATE_SPRITE_SKULL \ + { dgDungeonMapSkullTex, 16, 16, G_IM_FMT_RGBA, G_IM_SIZ_16b, 104 }, { \ + 0xFF, 0xFF, 0xFF, 0xFF \ + } +#define CREATE_SPRITE_COUNTER_DIGIT(i) \ + { dgAmmoDigit##i##Tex, 8, 8, G_IM_FMT_IA, G_IM_SIZ_8b, 105 + i } +#define CREATE_SPRITE_OCARINA_BUTTON(iconTex, spriteId) \ + { iconTex, 16, 16, G_IM_FMT_I, G_IM_SIZ_4b, spriteId }, { \ + 0xFF, 0xFF, 0xFF, 0xFF \ + } + +#define ICON_SIZE 12 +#define COUNTER_SIZE 16 +#define SONG_WIDTH 8 +#define SONG_HEIGHT 12 + +#define LEFT_OFFSET (int)0x37 +#define TOP_OFFSET (int)0x5C + +#define COUNTER_DIGITS_LEFT_OFFSET COUNTER_SIZE / 2 - 3 +#define COUNTER_DIGITS_TOP_OFFSET COUNTER_SIZE - 3 + +#define SIZE_NORMAL \ + { ICON_SIZE, ICON_SIZE } +#define SIZE_COUNTER \ + { COUNTER_SIZE, COUNTER_SIZE } +#define SIZE_SONG \ + { SONG_WIDTH, SONG_HEIGHT } + +// the format exclusion is because clang-format thinks that the * signs are pointers +// clang-format off +#define INVENTORY_ICON_POS(x, y) \ + { 0x4E + ICON_SIZE * x, 0x00 + ICON_SIZE * y } +#define EQUIPMENT_ICON_POS(x, y) \ + { 0x7E + ICON_SIZE * x, 0x2A + ICON_SIZE * y } +#define SONG_ICON_POS(x, y) \ + { 0x49 + SONG_WIDTH * x, 0x45 + SONG_HEIGHT * y } +#define UPGRADE_ICON_POS(x, y) \ + { 0x5A + ICON_SIZE * x, 0x2A + ICON_SIZE * y } +#define STONE_ICON_POS(i) \ + { 0x29 + ICON_SIZE * i, 0x31 } +#define OCARINA_BUTTON_ICON_POS(i) \ + { 0xA8 + ICON_SIZE * i, 0x00 } +#define RANDO_ONLY_ITEM_ICON_POS(i) \ + { 0xA8 + ICON_SIZE * i, 0x2A } +// clang-format on + +static ItemData itemData[] = { + { CREATE_SPRITE_32(dgItemIconDekuStickTex, 1), ITEM_STICK, INVENTORY_ICON_POS(0, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconDekuNutTex, 0), ITEM_NUT, INVENTORY_ICON_POS(1, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBombTex, 2), ITEM_BOMB, INVENTORY_ICON_POS(2, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBowTex, 3), ITEM_BOW, INVENTORY_ICON_POS(3, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconArrowFireTex, 4), ITEM_ARROW_FIRE, INVENTORY_ICON_POS(4, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconDinsFireTex, 5), ITEM_DINS_FIRE, INVENTORY_ICON_POS(5, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBottleEmptyTex, 20), ITEM_BOTTLE, INVENTORY_ICON_POS(6, 0), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconSlingshotTex, 6), ITEM_SLINGSHOT, INVENTORY_ICON_POS(0, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconOcarinaFairyTex, 7), ITEM_OCARINA_FAIRY, INVENTORY_ICON_POS(1, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconOcarinaOfTimeTex, 7), ITEM_OCARINA_TIME, INVENTORY_ICON_POS(1, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBombchuTex, 9), ITEM_BOMBCHU, INVENTORY_ICON_POS(2, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconHookshotTex, 10), ITEM_HOOKSHOT, INVENTORY_ICON_POS(3, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconLongshotTex, 10), ITEM_LONGSHOT, INVENTORY_ICON_POS(3, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconArrowIceTex, 12), ITEM_ARROW_ICE, INVENTORY_ICON_POS(4, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconFaroresWindTex, 13), ITEM_FARORES_WIND, INVENTORY_ICON_POS(5, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconWeirdEggTex, 37), ITEM_WEIRD_EGG, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconChickenTex, 37), ITEM_CHICKEN, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconZeldasLetterTex, 37), ITEM_LETTER_ZELDA, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskKeatonTex, 37), ITEM_MASK_KEATON, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskSkullTex, 37), ITEM_MASK_SKULL, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskSpookyTex, 37), ITEM_MASK_SPOOKY, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskBunnyHoodTex, 37), ITEM_MASK_BUNNY, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskGoronTex, 37), ITEM_MASK_GORON, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskZoraTex, 37), ITEM_MASK_ZORA, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskGerudoTex, 37), ITEM_MASK_GERUDO, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMaskTruthTex, 37), ITEM_MASK_TRUTH, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconSoldOutTex, 37), ITEM_SOLD_OUT, INVENTORY_ICON_POS(6, 1), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconBoomerangTex, 14), ITEM_BOOMERANG, INVENTORY_ICON_POS(0, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconLensOfTruthTex, 15), ITEM_LENS, INVENTORY_ICON_POS(1, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconMagicBeanTex, 16), ITEM_BEAN, INVENTORY_ICON_POS(2, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconHammerTex, 17), ITEM_HAMMER, INVENTORY_ICON_POS(3, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconArrowLightTex, 18), ITEM_ARROW_LIGHT, INVENTORY_ICON_POS(4, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconNayrusLoveTex, 19), ITEM_NAYRUS_LOVE, INVENTORY_ICON_POS(5, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconPocketEggTex, 53), ITEM_POCKET_EGG, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconPocketCuccoTex, 53), ITEM_POCKET_CUCCO, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconCojiroTex, 53), ITEM_COJIRO, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconOddMushroomTex, 53), ITEM_ODD_MUSHROOM, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconOddPotionTex, 53), ITEM_ODD_POTION, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconPoachersSawTex, 53), ITEM_SAW, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBrokenGoronsSwordTex, 53), ITEM_SWORD_BROKEN, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconPrescriptionTex, 53), ITEM_PRESCRIPTION, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconEyeballFrogTex, 53), ITEM_FROG, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconEyeDropsTex, 53), ITEM_EYEDROPS, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconClaimCheckTex, 53), ITEM_CLAIM_CHECK, INVENTORY_ICON_POS(6, 2), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconSwordKokiriTex, 54), ITEM_SWORD_KOKIRI, EQUIPMENT_ICON_POS(0, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconSwordMasterTex, 55), ITEM_SWORD_MASTER, EQUIPMENT_ICON_POS(1, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconSwordBiggoronTex, 56), ITEM_SWORD_BGS, EQUIPMENT_ICON_POS(2, 0), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconShieldDekuTex, 57), ITEM_SHIELD_DEKU, EQUIPMENT_ICON_POS(0, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconShieldHylianTex, 58), ITEM_SHIELD_HYLIAN, EQUIPMENT_ICON_POS(1, 1), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconShieldMirrorTex, 59), ITEM_SHIELD_MIRROR, EQUIPMENT_ICON_POS(2, 1), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconTunicKokiriTex, 60), ITEM_TUNIC_KOKIRI, EQUIPMENT_ICON_POS(0, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconTunicGoronTex, 61), ITEM_TUNIC_GORON, EQUIPMENT_ICON_POS(1, 2), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconTunicZoraTex, 62), ITEM_TUNIC_ZORA, EQUIPMENT_ICON_POS(2, 2), SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconBootsKokiriTex, 63), ITEM_BOOTS_KOKIRI, EQUIPMENT_ICON_POS(0, 3), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBootsIronTex, 64), ITEM_BOOTS_IRON, EQUIPMENT_ICON_POS(1, 3), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconBootsHoverTex, 65), ITEM_BOOTS_HOVER, EQUIPMENT_ICON_POS(2, 3), SIZE_NORMAL }, + + { CREATE_SPRITE_24(dgQuestIconKokiriEmeraldTex, 87), ITEM_KOKIRI_EMERALD, STONE_ICON_POS(-1), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconGoronRubyTex, 88), ITEM_GORON_RUBY, STONE_ICON_POS(0), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconZoraSapphireTex, 89), ITEM_ZORA_SAPPHIRE, STONE_ICON_POS(1), SIZE_NORMAL }, + + { CREATE_SPRITE_24(dgQuestIconMedallionForestTex, 81), ITEM_MEDALLION_FOREST, { 0x37, 0x0A }, SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMedallionFireTex, 82), ITEM_MEDALLION_FIRE, { 0x37, 0x1A }, SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMedallionWaterTex, 83), ITEM_MEDALLION_WATER, { 0x29, 0x22 }, SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMedallionSpiritTex, 84), ITEM_MEDALLION_SPIRIT, { 0x1B, 0x1A }, SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMedallionShadowTex, 85), ITEM_MEDALLION_SHADOW, { 0x1B, 0x0A }, SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMedallionLightTex, 86), ITEM_MEDALLION_LIGHT, { 0x29, 0x02 }, SIZE_NORMAL }, + + { CREATE_SPRITE_32(dgItemIconGoronsBraceletTex, 71), ITEM_BRACELET, UPGRADE_ICON_POS(0, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconSilverGauntletsTex, 71), ITEM_GAUNTLETS_SILVER, UPGRADE_ICON_POS(0, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconGoldenGauntletsTex, 71), ITEM_GAUNTLETS_GOLD, UPGRADE_ICON_POS(0, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconScaleSilverTex, 74), ITEM_SCALE_SILVER, UPGRADE_ICON_POS(1, 0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconScaleGoldenTex, 74), ITEM_SCALE_GOLDEN, UPGRADE_ICON_POS(1, 0), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMagicJarSmallTex, 97), ITEM_SINGLE_MAGIC, UPGRADE_ICON_POS(2, 0), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconMagicJarBigTex, 97), ITEM_DOUBLE_MAGIC, UPGRADE_ICON_POS(2, 0), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconGerudosCardTex, 91), ITEM_GERUDO_CARD, UPGRADE_ICON_POS(1, 1), SIZE_NORMAL }, + { CREATE_SPRITE_24(dgQuestIconStoneOfAgonyTex, 90), ITEM_STONE_OF_AGONY, UPGRADE_ICON_POS(2, 1), SIZE_NORMAL }, + + { CREATE_SPRITE_SONG(224, 107, 255), ITEM_SONG_LULLABY, SONG_ICON_POS(0, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 195, 60), ITEM_SONG_EPONA, SONG_ICON_POS(1, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(127, 255, 137), ITEM_SONG_SARIA, SONG_ICON_POS(2, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 255, 60), ITEM_SONG_SUN, SONG_ICON_POS(3, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(119, 236, 255), ITEM_SONG_TIME, SONG_ICON_POS(4, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(165, 165, 165), ITEM_SONG_STORMS, SONG_ICON_POS(5, 0), SIZE_SONG }, + { CREATE_SPRITE_SONG(150, 255, 100), ITEM_SONG_MINUET, SONG_ICON_POS(0, 1), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 80, 40), ITEM_SONG_BOLERO, SONG_ICON_POS(1, 1), SIZE_SONG }, + { CREATE_SPRITE_SONG(100, 150, 255), ITEM_SONG_SERENADE, SONG_ICON_POS(2, 1), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 160, 0), ITEM_SONG_REQUIEM, SONG_ICON_POS(3, 1), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 100, 255), ITEM_SONG_NOCTURNE, SONG_ICON_POS(4, 1), SIZE_SONG }, + { CREATE_SPRITE_SONG(255, 240, 100), ITEM_SONG_PRELUDE, SONG_ICON_POS(5, 1), SIZE_SONG }, + + { CREATE_SPRITE_24(dgQuestIconHeartContainerTex, 101), ITEM_DOUBLE_DEFENSE, { 0x05, -0x04 }, SIZE_COUNTER }, + + // using 0xB0 and later as they're not real item ids + // TODO: improve this (RandomizerGet doesn't work) + + // disabled due to lus issue + /* + { CREATE_SPRITE_OCARINA_BUTTON(dgMsgChar9FButtonATex, 115), 0xB0, OCARINA_BUTTON_ICON_POS(0), SIZE_NORMAL }, + { CREATE_SPRITE_OCARINA_BUTTON(dgMsgCharA5ButtonCUpTex, 116), 0xB1, OCARINA_BUTTON_ICON_POS(1), SIZE_NORMAL }, + { CREATE_SPRITE_OCARINA_BUTTON(dgMsgCharA6ButtonCDownTex, 117), 0xB2, OCARINA_BUTTON_ICON_POS(2), SIZE_NORMAL }, + { CREATE_SPRITE_OCARINA_BUTTON(dgMsgCharA7ButtonCLeftTex, 118), 0xB3, OCARINA_BUTTON_ICON_POS(3), SIZE_NORMAL }, + { CREATE_SPRITE_OCARINA_BUTTON(dgMsgCharA8ButtonCRightTex, 119), 0xB4, OCARINA_BUTTON_ICON_POS(4), SIZE_NORMAL }, + */ + + { CREATE_SPRITE_RUPEE(0xC8, 0xFF, 0x64), ITEM_RUPEE_GREEN, RANDO_ONLY_ITEM_ICON_POS(0), SIZE_NORMAL }, + { CREATE_SPRITE_32(dgItemIconFishingPoleTex, 120), ITEM_FISHING_POLE, RANDO_ONLY_ITEM_ICON_POS(1), SIZE_NORMAL }, +}; + +static u8 ColorProduct(u8 c1, u8 c2) { + u16 prod = (u16)c1 * (u16)c2; + u16 div255 = (prod + 1 + (prod >> 8)) >> 8; + return (u8)div255; +} + +static const Color_RGBA8 DIM = { 0x40, 0x40, 0x40, 0x90 }; + +extern "C" void SpriteLoad(FileChooseContext* thisx, Sprite* sprite); +extern "C" void SpriteDraw(FileChooseContext* thisx, Sprite* sprite, int left, int top, int width, int height); + +static bool HasItem(s16 fileIndex, u8 item) { + for (int i = 0; i < ARRAY_COUNT(Save_GetSaveMetaInfo(fileIndex)->inventoryItems); i += 1) { + u8 it = Save_GetSaveMetaInfo(fileIndex)->inventoryItems[i]; + if (it == item || (item == ITEM_BOTTLE && it >= ITEM_BOTTLE && it <= ITEM_POE)) { + return true; + } + } + + if (item >= ITEM_SONG_MINUET && item <= ITEM_SONG_STORMS) { + return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x54))) != 0; + } + + if (item >= ITEM_MEDALLION_FOREST && item <= ITEM_MEDALLION_LIGHT) { + return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x66))) != 0; + } + + if (item >= ITEM_KOKIRI_EMERALD && item <= ITEM_GERUDO_CARD) { + return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x5A))) != 0; + } + + if (item >= ITEM_SWORD_KOKIRI && item <= ITEM_SWORD_BGS) { + return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x3B))) != 0; + } + + if (item >= ITEM_SHIELD_DEKU && item <= ITEM_SHIELD_MIRROR) { + return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x3E + 4))) != 0; + } + + if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_TUNIC_ZORA) { + return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x41 + 8))) != 0; + } + + if (item >= ITEM_BOOTS_KOKIRI && item <= ITEM_BOOTS_HOVER) { + return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x44 + 12))) != 0; + } + + if (item == ITEM_SINGLE_MAGIC) { + return Save_GetSaveMetaInfo(fileIndex)->isMagicAcquired; + } + + if (item == ITEM_DOUBLE_MAGIC) { + return Save_GetSaveMetaInfo(fileIndex)->isDoubleMagicAcquired; + } + + if (item == ITEM_BRACELET) { + return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> + gUpgradeShifts[UPG_STRENGTH]) == 1; + } + + if (item == ITEM_GAUNTLETS_SILVER) { + return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> + gUpgradeShifts[UPG_STRENGTH]) == 2; + } + + if (item == ITEM_GAUNTLETS_GOLD) { + return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> + gUpgradeShifts[UPG_STRENGTH]) == 3; + } + + if (item == ITEM_SCALE_SILVER) { + return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_SCALE]) >> gUpgradeShifts[UPG_SCALE]) == + 1; + } + + if (item == ITEM_SCALE_GOLDEN) { + return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_SCALE]) >> gUpgradeShifts[UPG_SCALE]) == + 2; + } + + if (item == ITEM_DOUBLE_DEFENSE) { + return Save_GetSaveMetaInfo(fileIndex)->isDoubleDefenseAcquired; + } + + // greg + if (item == ITEM_RUPEE_GREEN) { + return Save_GetSaveMetaInfo(fileIndex)->gregFound; + } + + if (item == ITEM_FISHING_POLE) { + return Save_GetSaveMetaInfo(fileIndex)->hasFishingRod; + } + + return false; +} + +static bool ShouldRenderItem(s16 fileIndex, u8 item) { + // strength + if (item == ITEM_BRACELET && + (HasItem(fileIndex, ITEM_GAUNTLETS_SILVER) || HasItem(fileIndex, ITEM_GAUNTLETS_GOLD))) { + return false; + } + + if (item == ITEM_GAUNTLETS_SILVER && !HasItem(fileIndex, ITEM_GAUNTLETS_SILVER)) { + return false; + } + + if (item == ITEM_GAUNTLETS_GOLD && !HasItem(fileIndex, ITEM_GAUNTLETS_GOLD)) { + return false; + } + + // magic + if (item == ITEM_SINGLE_MAGIC && HasItem(fileIndex, ITEM_DOUBLE_MAGIC)) { + return false; + } + + if (item == ITEM_DOUBLE_MAGIC && !HasItem(fileIndex, ITEM_DOUBLE_MAGIC)) { + return false; + } + + // scales + if (item == ITEM_SCALE_SILVER && HasItem(fileIndex, ITEM_SCALE_GOLDEN)) { + return false; + } + + if (item == ITEM_SCALE_GOLDEN && !HasItem(fileIndex, ITEM_SCALE_GOLDEN)) { + return false; + } + + // hookshot/longshot + if (item == ITEM_HOOKSHOT && HasItem(fileIndex, ITEM_LONGSHOT)) { + return false; + } + + if (item == ITEM_LONGSHOT && !HasItem(fileIndex, ITEM_LONGSHOT)) { + return false; + } + + // ocarinas + if (item == ITEM_OCARINA_FAIRY && HasItem(fileIndex, ITEM_OCARINA_TIME)) { + return false; + } + + if (item == ITEM_OCARINA_TIME && !HasItem(fileIndex, ITEM_OCARINA_TIME)) { + return false; + } + + // trade child + if (item == ITEM_WEIRD_EGG && !HasItem(fileIndex, ITEM_WEIRD_EGG)) { + return false; + } + + if (item == ITEM_CHICKEN && !HasItem(fileIndex, ITEM_CHICKEN)) { + return false; + } + + if (item == ITEM_LETTER_ZELDA && !HasItem(fileIndex, ITEM_LETTER_ZELDA)) { + return false; + } + + if (item == ITEM_MASK_KEATON && (HasItem(fileIndex, ITEM_WEIRD_EGG) || HasItem(fileIndex, ITEM_CHICKEN) || + HasItem(fileIndex, ITEM_LETTER_ZELDA) || HasItem(fileIndex, ITEM_MASK_SKULL) || + HasItem(fileIndex, ITEM_MASK_SPOOKY) || HasItem(fileIndex, ITEM_MASK_BUNNY) || + HasItem(fileIndex, ITEM_MASK_GORON) || HasItem(fileIndex, ITEM_MASK_ZORA) || + HasItem(fileIndex, ITEM_MASK_GERUDO) || HasItem(fileIndex, ITEM_MASK_TRUTH) || + HasItem(fileIndex, ITEM_SOLD_OUT))) { + return false; + } + + if (item == ITEM_MASK_SKULL && !HasItem(fileIndex, ITEM_MASK_SKULL)) { + return false; + } + + if (item == ITEM_MASK_SPOOKY && !HasItem(fileIndex, ITEM_MASK_SPOOKY)) { + return false; + } + + if (item == ITEM_MASK_BUNNY && !HasItem(fileIndex, ITEM_MASK_BUNNY)) { + return false; + } + + if (item == ITEM_MASK_GORON && !HasItem(fileIndex, ITEM_MASK_GORON)) { + return false; + } + + if (item == ITEM_MASK_ZORA && !HasItem(fileIndex, ITEM_MASK_ZORA)) { + return false; + } + + if (item == ITEM_MASK_GERUDO && !HasItem(fileIndex, ITEM_MASK_GERUDO)) { + return false; + } + + if (item == ITEM_MASK_TRUTH && !HasItem(fileIndex, ITEM_MASK_TRUTH)) { + return false; + } + + if (item == ITEM_SOLD_OUT && !HasItem(fileIndex, ITEM_SOLD_OUT)) { + return false; + } + + // trade adult + if (item == ITEM_POCKET_EGG && + (HasItem(fileIndex, ITEM_POCKET_CUCCO) || HasItem(fileIndex, ITEM_COJIRO) || + HasItem(fileIndex, ITEM_ODD_MUSHROOM) || HasItem(fileIndex, ITEM_ODD_POTION) || HasItem(fileIndex, ITEM_SAW) || + HasItem(fileIndex, ITEM_SWORD_BROKEN) || HasItem(fileIndex, ITEM_PRESCRIPTION) || + HasItem(fileIndex, ITEM_FROG) || HasItem(fileIndex, ITEM_EYEDROPS) || HasItem(fileIndex, ITEM_CLAIM_CHECK))) { + return false; + } + + if (item == ITEM_POCKET_CUCCO && !HasItem(fileIndex, ITEM_POCKET_CUCCO)) { + return false; + } + + if (item == ITEM_COJIRO && !HasItem(fileIndex, ITEM_COJIRO)) { + return false; + } + + if (item == ITEM_ODD_MUSHROOM && !HasItem(fileIndex, ITEM_ODD_MUSHROOM)) { + return false; + } + + if (item == ITEM_ODD_POTION && !HasItem(fileIndex, ITEM_ODD_POTION)) { + return false; + } + + if (item == ITEM_SAW && !HasItem(fileIndex, ITEM_SAW)) { + return false; + } + + if (item == ITEM_SWORD_BROKEN && !HasItem(fileIndex, ITEM_SWORD_BROKEN)) { + return false; + } + + if (item == ITEM_PRESCRIPTION && !HasItem(fileIndex, ITEM_PRESCRIPTION)) { + return false; + } + + if (item == ITEM_FROG && !HasItem(fileIndex, ITEM_FROG)) { + return false; + } + + if (item == ITEM_EYEDROPS && !HasItem(fileIndex, ITEM_EYEDROPS)) { + return false; + } + + if (item == ITEM_CLAIM_CHECK && !HasItem(fileIndex, ITEM_CLAIM_CHECK)) { + return false; + } + + if (item == ITEM_DOUBLE_DEFENSE && !Save_GetSaveMetaInfo(fileIndex)->isDoubleDefenseAcquired) { + return false; + } + + // greg + if (item == ITEM_RUPEE_GREEN) { + return Save_GetSaveMetaInfo(fileIndex)->randoSave; + } + + if (item == ITEM_FISHING_POLE) { + return Save_GetSaveMetaInfo(fileIndex)->fishingPoleShuffled; + } + + return true; +} + +static void DrawItems(FileChooseContext* thisx, s16 fileIndex, u8 alpha) { + OPEN_DISPS(thisx->state.gfxCtx); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + for (int i = 0; i < ARRAY_COUNT(itemData); i += 1) { + ItemData* data = &itemData[i]; + + if (ShouldRenderItem(fileIndex, data->item)) { + if (HasItem(fileIndex, data->item)) { + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, data->color.r, data->color.g, data->color.b, + ColorProduct(data->color.a, alpha)); + } else { + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, ColorProduct(data->color.r, DIM.r), + ColorProduct(data->color.g, DIM.g), ColorProduct(data->color.b, DIM.b), + ColorProduct(ColorProduct(data->color.a, DIM.a), alpha)); + } + + SpriteLoad(thisx, &(data->sprite)); + SpriteDraw(thisx, &(data->sprite), LEFT_OFFSET + data->pos.left, TOP_OFFSET + data->pos.top, + data->size.width, data->size.height); + } + } + + gDPPipeSync(POLY_OPA_DISP++); + CLOSE_DISPS(thisx->state.gfxCtx); +} + +typedef enum CounterID { + /* 0x00 */ COUNTER_HEALTH, + /* 0x01 */ COUNTER_WALLET_NONE, + /* 0x02 */ COUNTER_WALLET_CHILD, + /* 0x03 */ COUNTER_WALLET_ADULT, + /* 0x04 */ COUNTER_WALLET_GIANT, + /* 0x05 */ COUNTER_WALLET_TYCOON, + /* 0x06 */ COUNTER_SKULLTULLAS, + /* 0x07 */ COUNTER_DEATHS, + /* 0x08 */ COUNTER_TRIFORCE_PIECES, + /* 0x09 */ COUNTER_MAX, +} CounterID; + +typedef struct CounterData { + Sprite sprite; + Color_RGBA8 color; + CounterID id; + IconPosition pos; + IconSize size; +} CounterData; + +static CounterData counterData[COUNTER_MAX] = { + { CREATE_SPRITE_24(dgQuestIconHeartContainerTex, 101), COUNTER_HEALTH, { 0x05, 0x00 }, SIZE_COUNTER }, + { CREATE_SPRITE_RUPEE(0x32, 0x40, 0x19), COUNTER_WALLET_NONE, { 0x05, 0x15 }, SIZE_COUNTER }, + { CREATE_SPRITE_RUPEE(0xC8, 0xFF, 0x64), COUNTER_WALLET_CHILD, { 0x05, 0x15 }, SIZE_COUNTER }, + { CREATE_SPRITE_RUPEE(0x82, 0x82, 0xFF), COUNTER_WALLET_ADULT, { 0x05, 0x15 }, SIZE_COUNTER }, + { CREATE_SPRITE_RUPEE(0xFF, 0x64, 0x64), COUNTER_WALLET_GIANT, { 0x05, 0x15 }, SIZE_COUNTER }, + { CREATE_SPRITE_RUPEE(0xFF, 0x5A, 0xFF), COUNTER_WALLET_TYCOON, { 0x05, 0x15 }, SIZE_COUNTER }, + { CREATE_SPRITE_24(dgQuestIconGoldSkulltulaTex, 103), COUNTER_SKULLTULLAS, { 0x05, 0x2A }, SIZE_COUNTER }, + { CREATE_SPRITE_SKULL, COUNTER_DEATHS, { 0x48, 0x2A }, SIZE_COUNTER }, + { CREATE_SPRITE_32(dgTriforcePiece, 121), COUNTER_TRIFORCE_PIECES, { 0x27, 0x10 }, SIZE_COUNTER }, +}; + +static Sprite counterDigitSprites[10] = { + CREATE_SPRITE_COUNTER_DIGIT(0), CREATE_SPRITE_COUNTER_DIGIT(1), CREATE_SPRITE_COUNTER_DIGIT(2), + CREATE_SPRITE_COUNTER_DIGIT(3), CREATE_SPRITE_COUNTER_DIGIT(4), CREATE_SPRITE_COUNTER_DIGIT(5), + CREATE_SPRITE_COUNTER_DIGIT(6), CREATE_SPRITE_COUNTER_DIGIT(7), CREATE_SPRITE_COUNTER_DIGIT(8), + CREATE_SPRITE_COUNTER_DIGIT(9), +}; + +static bool ShouldRenderCounter(s16 fileIndex, CounterID counterId) { + if (counterId == COUNTER_WALLET_NONE) { + return !Save_GetSaveMetaInfo(fileIndex)->hasWallet; + } + + if (counterId == COUNTER_WALLET_CHILD) { + return Save_GetSaveMetaInfo(fileIndex)->hasWallet && + ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> + gUpgradeShifts[UPG_WALLET]) == 0; + } + + if (counterId == COUNTER_WALLET_ADULT) { + return Save_GetSaveMetaInfo(fileIndex)->hasWallet && + ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> + gUpgradeShifts[UPG_WALLET]) == 1; + } + + if (counterId == COUNTER_WALLET_GIANT) { + return Save_GetSaveMetaInfo(fileIndex)->hasWallet && + ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> + gUpgradeShifts[UPG_WALLET]) == 2; + } + + if (counterId == COUNTER_WALLET_TYCOON) { + return Save_GetSaveMetaInfo(fileIndex)->hasWallet && + ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> + gUpgradeShifts[UPG_WALLET]) == 3; + } + + if (counterId == COUNTER_TRIFORCE_PIECES) { + return Save_GetSaveMetaInfo(fileIndex)->maxTriforcePieces != 0; + } + + return true; +} + +static u16 GetCurrentCounterValue(s16 fileIndex, CounterID counter) { + // one heart is 16 healthCapacity + if (counter == COUNTER_HEALTH) { + return Save_GetSaveMetaInfo(fileIndex)->healthCapacity / 16; + } + + if (counter >= COUNTER_WALLET_CHILD && counter <= COUNTER_WALLET_TYCOON) { + return Save_GetSaveMetaInfo(fileIndex)->rupees; + } + + if (counter == COUNTER_SKULLTULLAS) { + return Save_GetSaveMetaInfo(fileIndex)->gsTokens; + } + + if (counter == COUNTER_DEATHS) { + return Save_GetSaveMetaInfo(fileIndex)->deaths; + } + + if (counter == COUNTER_TRIFORCE_PIECES) { + return Save_GetSaveMetaInfo(fileIndex)->triforcePieces; + } + + return 0; +} + +static u16 GetMaxCounterValue(s16 fileIndex, CounterID counter) { + if (counter == COUNTER_HEALTH) { + return 20; + } + + if (counter == COUNTER_WALLET_CHILD) { + return 99; + } + + if (counter == COUNTER_WALLET_ADULT) { + return 200; + } + + if (counter == COUNTER_WALLET_GIANT) { + return 500; + } + + if (counter == COUNTER_WALLET_TYCOON) { + return 999; + } + + if (counter == COUNTER_SKULLTULLAS) { + return 100; + } + + if (counter == COUNTER_DEATHS) { + return 999; + } + + if (counter == COUNTER_TRIFORCE_PIECES) { + return Save_GetSaveMetaInfo(fileIndex)->maxTriforcePieces; + } + + return 0; +} + +static void DrawCounterValue(FileChooseContext* thisx, s16 fileIndex, u8 alpha, CounterData* data) { + u16 currentValue; + u16 maxValue; + + currentValue = GetCurrentCounterValue(fileIndex, data->id); + maxValue = GetMaxCounterValue(fileIndex, data->id); + + // to prevent crashes if you use the save editor + if (currentValue > 999) { + currentValue = 999; + } + + OPEN_DISPS(thisx->state.gfxCtx); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (currentValue == 0) { + // grey + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 130, 130, 130, alpha); + } else if (currentValue == maxValue) { + // green + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 120, 255, 0, alpha); + } else if (currentValue > maxValue) { + // cyan + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 255, 255, alpha); + } else { + // white + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, alpha); + } + + s16 hundreds; + s16 tens; + + for (hundreds = 0; currentValue >= 100; hundreds++) { + currentValue -= 100; + } + + for (tens = 0; currentValue >= 10; tens++) { + currentValue -= 10; + } + + if (hundreds != 0) { + SpriteLoad(thisx, &counterDigitSprites[hundreds]); + SpriteDraw(thisx, &counterDigitSprites[hundreds], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET - 6 + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + + SpriteLoad(thisx, &counterDigitSprites[tens]); + SpriteDraw(thisx, &counterDigitSprites[tens], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + + SpriteLoad(thisx, &counterDigitSprites[currentValue]); + SpriteDraw(thisx, &counterDigitSprites[currentValue], + LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + 6 + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + } else if (tens != 0) { + SpriteLoad(thisx, &counterDigitSprites[tens]); + SpriteDraw(thisx, &counterDigitSprites[tens], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET - 3 + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + + SpriteLoad(thisx, &counterDigitSprites[currentValue]); + SpriteDraw(thisx, &counterDigitSprites[currentValue], + LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + 3 + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + } else { + SpriteLoad(thisx, &counterDigitSprites[currentValue]); + SpriteDraw(thisx, &counterDigitSprites[currentValue], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + data->pos.left, + TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); + } + + gDPPipeSync(POLY_OPA_DISP++); + CLOSE_DISPS(thisx->state.gfxCtx); +} + +static void DrawCounters(FileChooseContext* thisx, s16 fileIndex, u8 alpha) { + OPEN_DISPS(thisx->state.gfxCtx); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + for (int i = 0; i < ARRAY_COUNT(counterData); i += 1) { + CounterData* data = &counterData[i]; + + if (ShouldRenderCounter(fileIndex, data->id)) { + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, data->color.r, data->color.g, data->color.b, + ColorProduct(data->color.a, alpha)); + + SpriteLoad(thisx, &(data->sprite)); + SpriteDraw(thisx, &(data->sprite), LEFT_OFFSET + data->pos.left, TOP_OFFSET + data->pos.top, + data->size.width, data->size.height); + + DrawCounterValue(thisx, fileIndex, alpha, data); + } + } + + gDPPipeSync(POLY_OPA_DISP++); + CLOSE_DISPS(thisx->state.gfxCtx); +} + +static void DrawMoreInfo(FileChooseContext* thisx, s16 fileIndex, u8 alpha) { + DrawItems(thisx, fileIndex, alpha); + DrawCounters(thisx, fileIndex, alpha); +} + +#define CVAR_FILE_SELECT_MORE_INFO_DEFAULT false +#define CVAR_FILE_SELECT_MORE_INFO_NAME CVAR_ENHANCEMENT("FileSelectMoreInfo") +#define CVAR_FILE_SELECT_MORE_INFO_VALUE \ + CVarGetInteger(CVAR_FILE_SELECT_MORE_INFO_NAME, CVAR_FILE_SELECT_MORE_INFO_DEFAULT) + +void RegisterFileSelectMoreInfo() { + COND_VB_SHOULD(VB_FILE_SELECT_DRAW_DEATHS, CVAR_FILE_SELECT_MORE_INFO_VALUE, { + FileChooseContext* thisx = va_arg(args, FileChooseContext*); + *should = thisx->menuMode != FS_MENU_MODE_SELECT; + }); + + COND_VB_SHOULD(VB_FILE_SELECT_DRAW_HEARTS, CVAR_FILE_SELECT_MORE_INFO_VALUE, { + FileChooseContext* thisx = va_arg(args, FileChooseContext*); + *should = thisx->menuMode != FS_MENU_MODE_SELECT; + }); + + COND_VB_SHOULD(VB_FILE_SELECT_DRAW_QUEST_ITEMS, CVAR_FILE_SELECT_MORE_INFO_VALUE, { + FileChooseContext* thisx = va_arg(args, FileChooseContext*); + s16 fileIndex = va_arg(args, s16); + u8 textAlpha = va_arg(args, u8); + + if (thisx->menuMode == FS_MENU_MODE_SELECT) { + DrawMoreInfo(thisx, fileIndex, textAlpha); + *should = false; + } + }); + + COND_VB_SHOULD(VB_FILE_SELECT_DRAW_FILE_INFO_BOX, CVAR_FILE_SELECT_MORE_INFO_VALUE, { + FileChooseContext* thisx = va_arg(args, FileChooseContext*); + + // Draw the small file name box instead when more meta info is enabled + if (thisx->menuMode == FS_MENU_MODE_SELECT) { + OPEN_DISPS(thisx->state.gfxCtx); + + // Location of file 1 small name box vertices + gSPVertex(POLY_OPA_DISP++, (uintptr_t)&thisx->windowContentVtx[68], 4, 0); + + gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0); + + CLOSE_DISPS(thisx->state.gfxCtx); + *should = false; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterFileSelectMoreInfo, { CVAR_FILE_SELECT_MORE_INFO_NAME }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 101b13641..6c4729309 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2405,6 +2405,40 @@ typedef enum { // - `*BgHidanKowarerukabe` VB_FIRE_TEMPLE_BOMBABLE_WALL_BREAK, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*FileChooseContext` + VB_FILE_SELECT_DRAW_DEATHS, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*FileChooseContext` + VB_FILE_SELECT_DRAW_HEARTS, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*FileChooseContext` + // - `s16` + // - `u8` + VB_FILE_SELECT_DRAW_QUEST_ITEMS, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*FileChooseContext` + VB_FILE_SELECT_DRAW_FILE_INFO_BOX, + // #### `result` // ```c // true diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 4d0068e16..c945b491e 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -602,10 +602,19 @@ void SaveManager::InitMeta(int fileNum) { fileMetaInfo[fileNum].gregFound = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND); fileMetaInfo[fileNum].filenameLanguage = gSaveContext.ship.filenameLanguage; fileMetaInfo[fileNum].hasWallet = Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) || !IS_RANDO; + fileMetaInfo[fileNum].triforcePieces = + IS_RANDO ? gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected : 0; + fileMetaInfo[fileNum].hasFishingRod = Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND) || !IS_RANDO; fileMetaInfo[fileNum].defense = gSaveContext.inventory.defenseHearts; fileMetaInfo[fileNum].health = gSaveContext.health; auto randoContext = Rando::Context::GetInstance(); + fileMetaInfo[fileNum].maxTriforcePieces = IS_RANDO && (bool)randoContext->GetOption(RSK_TRIFORCE_HUNT) + ? randoContext->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1 + : 0; + fileMetaInfo[fileNum].fishingPoleShuffled = + IS_RANDO ? (bool)randoContext->GetOption(RSK_SHUFFLE_FISHING_POLE) : false; + for (int i = 0; i < ARRAY_COUNT(fileMetaInfo[fileNum].seedHash); i++) { fileMetaInfo[fileNum].seedHash[i] = randoContext->hashIconIndexes[i]; } diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 42c608844..80f58b915 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -30,8 +30,12 @@ typedef struct { s16 gsTokens; u8 isDoubleDefenseAcquired; s32 filenameLanguage; - s32 gregFound; - s32 hasWallet; + bool gregFound; + bool hasWallet; + u8 triforcePieces; + u8 maxTriforcePieces; + bool hasFishingRod; + bool fishingPoleShuffled; } SaveFileMetaInfo; typedef enum { diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 1870e760d..bd64839c3 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -28,681 +28,6 @@ #include "soh/ResourceManagerHelpers.h" #include "soh/ShipUtils.h" -typedef struct { - s16 left; - s16 top; -} IconPosition; - -typedef struct { - s16 width; - s16 height; -} IconSize; - -typedef struct { - Sprite sprite; - Color_RGBA8 color; - u8 item; - IconPosition pos; - IconSize size; -} ItemData; - -#define CREATE_SPRITE_24(iconTex, spriteId) \ - { iconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, spriteId }, { \ - 0xFF, 0xFF, 0xFF, 0xFF \ - } -#define CREATE_SPRITE_32(iconTex, spriteId) \ - { iconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, spriteId }, { \ - 0xFF, 0xFF, 0xFF, 0xFF \ - } -#define CREATE_SPRITE_SONG(colorR, colorG, colorB) \ - { dgSongNoteTex, 16, 24, G_IM_FMT_IA, G_IM_SIZ_8b, 100 }, { \ - colorR, colorG, colorB, 0xFF \ - } -#define CREATE_SPRITE_RUPEE(colorR, colorG, colorB) \ - { dgRupeeCounterIconTex, 16, 16, G_IM_FMT_IA, G_IM_SIZ_8b, 102 }, { \ - colorR, colorG, colorB, 0xFF \ - } -#define CREATE_SPRITE_SKULL \ - { dgDungeonMapSkullTex, 16, 16, G_IM_FMT_RGBA, G_IM_SIZ_16b, 104 }, { \ - 0xFF, 0xFF, 0xFF, 0xFF \ - } -#define CREATE_SPRITE_COUNTER_DIGIT(i) \ - { dgAmmoDigit##i##Tex, 8, 8, G_IM_FMT_IA, G_IM_SIZ_8b, 105 + i } - -#define ICON_SIZE 12 -#define COUNTER_SIZE 16 -#define SONG_WIDTH 8 -#define SONG_HEIGHT 12 - -#define LEFT_OFFSET (int)0x37 -#define TOP_OFFSET (int)0x5C - -#define COUNTER_DIGITS_LEFT_OFFSET COUNTER_SIZE / 2 - 3 -#define COUNTER_DIGITS_TOP_OFFSET COUNTER_SIZE - 3 - -#define SIZE_NORMAL \ - { ICON_SIZE, ICON_SIZE } -#define SIZE_COUNTER \ - { COUNTER_SIZE, COUNTER_SIZE } -#define SIZE_SONG \ - { SONG_WIDTH, SONG_HEIGHT } - -#define INV_IC_POS(x, y) \ - { 0x4E + ICON_SIZE *x, 0x00 + ICON_SIZE *y } -#define EQP_IC_POS(x, y) \ - { 0x7E + ICON_SIZE *x, 0x2A + ICON_SIZE *y } -#define SNG_IC_POS(x, y) \ - { 0x49 + SONG_WIDTH *x, 0x45 + SONG_HEIGHT *y } -#define UPG_IC_POS(x, y) \ - { 0x5A + ICON_SIZE *x, 0x2A + ICON_SIZE *y } -#define STN_IC_POS(i) \ - { 0x29 + ICON_SIZE *i, 0x31 } - -static ItemData itemData[88] = { - { CREATE_SPRITE_32(dgItemIconDekuStickTex, 1), ITEM_STICK, INV_IC_POS(0, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconDekuNutTex, 0), ITEM_NUT, INV_IC_POS(1, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBombTex, 2), ITEM_BOMB, INV_IC_POS(2, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBowTex, 3), ITEM_BOW, INV_IC_POS(3, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconArrowFireTex, 4), ITEM_ARROW_FIRE, INV_IC_POS(4, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconDinsFireTex, 5), ITEM_DINS_FIRE, INV_IC_POS(5, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBottleEmptyTex, 20), ITEM_BOTTLE, INV_IC_POS(6, 0), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconSlingshotTex, 6), ITEM_SLINGSHOT, INV_IC_POS(0, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconOcarinaFairyTex, 7), ITEM_OCARINA_FAIRY, INV_IC_POS(1, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconOcarinaOfTimeTex, 7), ITEM_OCARINA_TIME, INV_IC_POS(1, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBombchuTex, 9), ITEM_BOMBCHU, INV_IC_POS(2, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconHookshotTex, 10), ITEM_HOOKSHOT, INV_IC_POS(3, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconLongshotTex, 10), ITEM_LONGSHOT, INV_IC_POS(3, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconArrowIceTex, 12), ITEM_ARROW_ICE, INV_IC_POS(4, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconFaroresWindTex, 13), ITEM_FARORES_WIND, INV_IC_POS(5, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconWeirdEggTex, 37), ITEM_WEIRD_EGG, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconChickenTex, 37), ITEM_CHICKEN, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconZeldasLetterTex, 37), ITEM_LETTER_ZELDA, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskKeatonTex, 37), ITEM_MASK_KEATON, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskSkullTex, 37), ITEM_MASK_SKULL, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskSpookyTex, 37), ITEM_MASK_SPOOKY, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskBunnyHoodTex, 37), ITEM_MASK_BUNNY, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskGoronTex, 37), ITEM_MASK_GORON, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskZoraTex, 37), ITEM_MASK_ZORA, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskGerudoTex, 37), ITEM_MASK_GERUDO, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMaskTruthTex, 37), ITEM_MASK_TRUTH, INV_IC_POS(6, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconSoldOutTex, 37), ITEM_SOLD_OUT, INV_IC_POS(6, 1), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconBoomerangTex, 14), ITEM_BOOMERANG, INV_IC_POS(0, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconLensOfTruthTex, 15), ITEM_LENS, INV_IC_POS(1, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconMagicBeanTex, 16), ITEM_BEAN, INV_IC_POS(2, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconHammerTex, 17), ITEM_HAMMER, INV_IC_POS(3, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconArrowLightTex, 18), ITEM_ARROW_LIGHT, INV_IC_POS(4, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconNayrusLoveTex, 19), ITEM_NAYRUS_LOVE, INV_IC_POS(5, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconPocketEggTex, 53), ITEM_POCKET_EGG, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconPocketCuccoTex, 53), ITEM_POCKET_CUCCO, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconCojiroTex, 53), ITEM_COJIRO, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconOddMushroomTex, 53), ITEM_ODD_MUSHROOM, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconOddPotionTex, 53), ITEM_ODD_POTION, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconPoachersSawTex, 53), ITEM_SAW, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBrokenGoronsSwordTex, 53), ITEM_SWORD_BROKEN, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconPrescriptionTex, 53), ITEM_PRESCRIPTION, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconEyeballFrogTex, 53), ITEM_FROG, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconEyeDropsTex, 53), ITEM_EYEDROPS, INV_IC_POS(6, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconClaimCheckTex, 53), ITEM_CLAIM_CHECK, INV_IC_POS(6, 2), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconSwordKokiriTex, 54), ITEM_SWORD_KOKIRI, EQP_IC_POS(0, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconSwordMasterTex, 55), ITEM_SWORD_MASTER, EQP_IC_POS(1, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconSwordBiggoronTex, 56), ITEM_SWORD_BGS, EQP_IC_POS(2, 0), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconShieldDekuTex, 57), ITEM_SHIELD_DEKU, EQP_IC_POS(0, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconShieldHylianTex, 58), ITEM_SHIELD_HYLIAN, EQP_IC_POS(1, 1), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconShieldMirrorTex, 59), ITEM_SHIELD_MIRROR, EQP_IC_POS(2, 1), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconTunicKokiriTex, 60), ITEM_TUNIC_KOKIRI, EQP_IC_POS(0, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconTunicGoronTex, 61), ITEM_TUNIC_GORON, EQP_IC_POS(1, 2), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconTunicZoraTex, 62), ITEM_TUNIC_ZORA, EQP_IC_POS(2, 2), SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconBootsKokiriTex, 63), ITEM_BOOTS_KOKIRI, EQP_IC_POS(0, 3), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBootsIronTex, 64), ITEM_BOOTS_IRON, EQP_IC_POS(1, 3), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconBootsHoverTex, 65), ITEM_BOOTS_HOVER, EQP_IC_POS(2, 3), SIZE_NORMAL }, - - { CREATE_SPRITE_24(dgQuestIconKokiriEmeraldTex, 87), ITEM_KOKIRI_EMERALD, STN_IC_POS(-1), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconGoronRubyTex, 88), ITEM_GORON_RUBY, STN_IC_POS(0), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconZoraSapphireTex, 89), ITEM_ZORA_SAPPHIRE, STN_IC_POS(1), SIZE_NORMAL }, - - { CREATE_SPRITE_24(dgQuestIconMedallionForestTex, 81), ITEM_MEDALLION_FOREST, { 0x37, 0x0A }, SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMedallionFireTex, 82), ITEM_MEDALLION_FIRE, { 0x37, 0x1A }, SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMedallionWaterTex, 83), ITEM_MEDALLION_WATER, { 0x29, 0x22 }, SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMedallionSpiritTex, 84), ITEM_MEDALLION_SPIRIT, { 0x1B, 0x1A }, SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMedallionShadowTex, 85), ITEM_MEDALLION_SHADOW, { 0x1B, 0x0A }, SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMedallionLightTex, 86), ITEM_MEDALLION_LIGHT, { 0x29, 0x02 }, SIZE_NORMAL }, - - { CREATE_SPRITE_32(dgItemIconGoronsBraceletTex, 71), ITEM_BRACELET, UPG_IC_POS(0, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconSilverGauntletsTex, 71), ITEM_GAUNTLETS_SILVER, UPG_IC_POS(0, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconGoldenGauntletsTex, 71), ITEM_GAUNTLETS_GOLD, UPG_IC_POS(0, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconScaleSilverTex, 74), ITEM_SCALE_SILVER, UPG_IC_POS(1, 0), SIZE_NORMAL }, - { CREATE_SPRITE_32(dgItemIconScaleGoldenTex, 74), ITEM_SCALE_GOLDEN, UPG_IC_POS(1, 0), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMagicJarSmallTex, 97), ITEM_SINGLE_MAGIC, UPG_IC_POS(2, 0), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconMagicJarBigTex, 97), ITEM_DOUBLE_MAGIC, UPG_IC_POS(2, 0), SIZE_NORMAL }, - { CREATE_SPRITE_RUPEE(0xC8, 0xFF, 0x64), ITEM_RUPEE_GREEN, UPG_IC_POS(0, 1), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconGerudosCardTex, 91), ITEM_GERUDO_CARD, UPG_IC_POS(1, 1), SIZE_NORMAL }, - { CREATE_SPRITE_24(dgQuestIconStoneOfAgonyTex, 90), ITEM_STONE_OF_AGONY, UPG_IC_POS(2, 1), SIZE_NORMAL }, - - { CREATE_SPRITE_SONG(224, 107, 255), ITEM_SONG_LULLABY, SNG_IC_POS(0, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 195, 60), ITEM_SONG_EPONA, SNG_IC_POS(1, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(127, 255, 137), ITEM_SONG_SARIA, SNG_IC_POS(2, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 255, 60), ITEM_SONG_SUN, SNG_IC_POS(3, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(119, 236, 255), ITEM_SONG_TIME, SNG_IC_POS(4, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(165, 165, 165), ITEM_SONG_STORMS, SNG_IC_POS(5, 0), SIZE_SONG }, - { CREATE_SPRITE_SONG(150, 255, 100), ITEM_SONG_MINUET, SNG_IC_POS(0, 1), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 80, 40), ITEM_SONG_BOLERO, SNG_IC_POS(1, 1), SIZE_SONG }, - { CREATE_SPRITE_SONG(100, 150, 255), ITEM_SONG_SERENADE, SNG_IC_POS(2, 1), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 160, 0), ITEM_SONG_REQUIEM, SNG_IC_POS(3, 1), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 100, 255), ITEM_SONG_NOCTURNE, SNG_IC_POS(4, 1), SIZE_SONG }, - { CREATE_SPRITE_SONG(255, 240, 100), ITEM_SONG_PRELUDE, SNG_IC_POS(5, 1), SIZE_SONG }, - - { CREATE_SPRITE_24(dgQuestIconHeartContainerTex, 101), ITEM_DOUBLE_DEFENSE, { 0x05, -0x04 }, SIZE_COUNTER }, -}; - -static u8 color_product(u8 c1, u8 c2) { - u16 prod = (u16)c1 * (u16)c2; - u16 div255 = (prod + 1 + (prod >> 8)) >> 8; - return (u8)div255; -} - -static const Color_RGBA8 DIM = { 0x40, 0x40, 0x40, 0x90 }; - -void SpriteLoad(FileChooseContext* this, Sprite* sprite); -void SpriteDraw(FileChooseContext* this, Sprite* sprite, int left, int top, int width, int height); - -u8 HasItem(s16 fileIndex, u8 item) { - for (int i = 0; i < ARRAY_COUNT(Save_GetSaveMetaInfo(fileIndex)->inventoryItems); i += 1) { - u8 it = Save_GetSaveMetaInfo(fileIndex)->inventoryItems[i]; - if (it == item || (item == ITEM_BOTTLE && it >= ITEM_BOTTLE && it <= ITEM_POE)) { - return 1; - } - } - - if (item >= ITEM_SONG_MINUET && item <= ITEM_SONG_STORMS) { - return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x54))) != 0; - } - - if (item >= ITEM_MEDALLION_FOREST && item <= ITEM_MEDALLION_LIGHT) { - return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x66))) != 0; - } - - if (item >= ITEM_KOKIRI_EMERALD && item <= ITEM_GERUDO_CARD) { - return (Save_GetSaveMetaInfo(fileIndex)->questItems & (1 << (item - 0x5A))) != 0; - } - - if (item >= ITEM_SWORD_KOKIRI && item <= ITEM_SWORD_BGS) { - return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x3B))) != 0; - } - - if (item >= ITEM_SHIELD_DEKU && item <= ITEM_SHIELD_MIRROR) { - return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x3E + 4))) != 0; - } - - if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_TUNIC_ZORA) { - return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x41 + 8))) != 0; - } - - if (item >= ITEM_BOOTS_KOKIRI && item <= ITEM_BOOTS_HOVER) { - return (Save_GetSaveMetaInfo(fileIndex)->equipment & (1 << (item - 0x44 + 12))) != 0; - } - - if (item == ITEM_SINGLE_MAGIC) { - return Save_GetSaveMetaInfo(fileIndex)->isMagicAcquired; - } - - if (item == ITEM_DOUBLE_MAGIC) { - return Save_GetSaveMetaInfo(fileIndex)->isDoubleMagicAcquired; - } - - if (item == ITEM_BRACELET) { - return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> - gUpgradeShifts[UPG_STRENGTH]) == 1; - } - - if (item == ITEM_GAUNTLETS_SILVER) { - return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> - gUpgradeShifts[UPG_STRENGTH]) == 2; - } - - if (item == ITEM_GAUNTLETS_GOLD) { - return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_STRENGTH]) >> - gUpgradeShifts[UPG_STRENGTH]) == 3; - } - - if (item == ITEM_SCALE_SILVER) { - return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_SCALE]) >> gUpgradeShifts[UPG_SCALE]) == - 1; - } - - if (item == ITEM_SCALE_GOLDEN) { - return ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_SCALE]) >> gUpgradeShifts[UPG_SCALE]) == - 2; - } - - if (item == ITEM_DOUBLE_DEFENSE) { - return Save_GetSaveMetaInfo(fileIndex)->isDoubleDefenseAcquired; - } - - // greg - if (item == ITEM_RUPEE_GREEN) { - return Save_GetSaveMetaInfo(fileIndex)->gregFound; - } - - return 0; -} - -u8 ShouldRenderItem(s16 fileIndex, u8 item) { - // strength - if (item == ITEM_BRACELET && - (HasItem(fileIndex, ITEM_GAUNTLETS_SILVER) || HasItem(fileIndex, ITEM_GAUNTLETS_GOLD))) { - return 0; - } - - if (item == ITEM_GAUNTLETS_SILVER && !HasItem(fileIndex, ITEM_GAUNTLETS_SILVER)) { - return 0; - } - - if (item == ITEM_GAUNTLETS_GOLD && !HasItem(fileIndex, ITEM_GAUNTLETS_GOLD)) { - return 0; - } - - // magic - if (item == ITEM_SINGLE_MAGIC && HasItem(fileIndex, ITEM_DOUBLE_MAGIC)) { - return 0; - } - - if (item == ITEM_DOUBLE_MAGIC && !HasItem(fileIndex, ITEM_DOUBLE_MAGIC)) { - return 0; - } - - // scales - if (item == ITEM_SCALE_SILVER && HasItem(fileIndex, ITEM_SCALE_GOLDEN)) { - return 0; - } - - if (item == ITEM_SCALE_GOLDEN && !HasItem(fileIndex, ITEM_SCALE_GOLDEN)) { - return 0; - } - - // hookshot/longshot - if (item == ITEM_HOOKSHOT && HasItem(fileIndex, ITEM_LONGSHOT)) { - return 0; - } - - if (item == ITEM_LONGSHOT && !HasItem(fileIndex, ITEM_LONGSHOT)) { - return 0; - } - - // ocarinas - if (item == ITEM_OCARINA_FAIRY && HasItem(fileIndex, ITEM_OCARINA_TIME)) { - return 0; - } - - if (item == ITEM_OCARINA_TIME && !HasItem(fileIndex, ITEM_OCARINA_TIME)) { - return 0; - } - - // trade child - if (item == ITEM_WEIRD_EGG && !HasItem(fileIndex, ITEM_WEIRD_EGG)) { - return 0; - } - - if (item == ITEM_CHICKEN && !HasItem(fileIndex, ITEM_CHICKEN)) { - return 0; - } - - if (item == ITEM_LETTER_ZELDA && !HasItem(fileIndex, ITEM_LETTER_ZELDA)) { - return 0; - } - - if (item == ITEM_MASK_KEATON && (HasItem(fileIndex, ITEM_WEIRD_EGG) || HasItem(fileIndex, ITEM_CHICKEN) || - HasItem(fileIndex, ITEM_LETTER_ZELDA) || HasItem(fileIndex, ITEM_MASK_SKULL) || - HasItem(fileIndex, ITEM_MASK_SPOOKY) || HasItem(fileIndex, ITEM_MASK_BUNNY) || - HasItem(fileIndex, ITEM_MASK_GORON) || HasItem(fileIndex, ITEM_MASK_ZORA) || - HasItem(fileIndex, ITEM_MASK_GERUDO) || HasItem(fileIndex, ITEM_MASK_TRUTH) || - HasItem(fileIndex, ITEM_SOLD_OUT))) { - return 0; - } - - if (item == ITEM_MASK_SKULL && !HasItem(fileIndex, ITEM_MASK_SKULL)) { - return 0; - } - - if (item == ITEM_MASK_SPOOKY && !HasItem(fileIndex, ITEM_MASK_SPOOKY)) { - return 0; - } - - if (item == ITEM_MASK_BUNNY && !HasItem(fileIndex, ITEM_MASK_BUNNY)) { - return 0; - } - - if (item == ITEM_MASK_GORON && !HasItem(fileIndex, ITEM_MASK_GORON)) { - return 0; - } - - if (item == ITEM_MASK_ZORA && !HasItem(fileIndex, ITEM_MASK_ZORA)) { - return 0; - } - - if (item == ITEM_MASK_GERUDO && !HasItem(fileIndex, ITEM_MASK_GERUDO)) { - return 0; - } - - if (item == ITEM_MASK_TRUTH && !HasItem(fileIndex, ITEM_MASK_TRUTH)) { - return 0; - } - - if (item == ITEM_SOLD_OUT && !HasItem(fileIndex, ITEM_SOLD_OUT)) { - return 0; - } - - // trade adult - if (item == ITEM_POCKET_EGG && - (HasItem(fileIndex, ITEM_POCKET_CUCCO) || HasItem(fileIndex, ITEM_COJIRO) || - HasItem(fileIndex, ITEM_ODD_MUSHROOM) || HasItem(fileIndex, ITEM_ODD_POTION) || HasItem(fileIndex, ITEM_SAW) || - HasItem(fileIndex, ITEM_SWORD_BROKEN) || HasItem(fileIndex, ITEM_PRESCRIPTION) || - HasItem(fileIndex, ITEM_FROG) || HasItem(fileIndex, ITEM_EYEDROPS) || HasItem(fileIndex, ITEM_CLAIM_CHECK))) { - return 0; - } - - if (item == ITEM_POCKET_CUCCO && !HasItem(fileIndex, ITEM_POCKET_CUCCO)) { - return 0; - } - - if (item == ITEM_COJIRO && !HasItem(fileIndex, ITEM_COJIRO)) { - return 0; - } - - if (item == ITEM_ODD_MUSHROOM && !HasItem(fileIndex, ITEM_ODD_MUSHROOM)) { - return 0; - } - - if (item == ITEM_ODD_POTION && !HasItem(fileIndex, ITEM_ODD_POTION)) { - return 0; - } - - if (item == ITEM_SAW && !HasItem(fileIndex, ITEM_SAW)) { - return 0; - } - - if (item == ITEM_SWORD_BROKEN && !HasItem(fileIndex, ITEM_SWORD_BROKEN)) { - return 0; - } - - if (item == ITEM_PRESCRIPTION && !HasItem(fileIndex, ITEM_PRESCRIPTION)) { - return 0; - } - - if (item == ITEM_FROG && !HasItem(fileIndex, ITEM_FROG)) { - return 0; - } - - if (item == ITEM_EYEDROPS && !HasItem(fileIndex, ITEM_EYEDROPS)) { - return 0; - } - - if (item == ITEM_CLAIM_CHECK && !HasItem(fileIndex, ITEM_CLAIM_CHECK)) { - return 0; - } - - if (item == ITEM_DOUBLE_DEFENSE && !Save_GetSaveMetaInfo(fileIndex)->isDoubleDefenseAcquired) { - return 0; - } - - // greg - if (item == ITEM_RUPEE_GREEN) { - return Save_GetSaveMetaInfo(fileIndex)->randoSave; - } - - return 1; -} - -static void DrawItems(FileChooseContext* this, s16 fileIndex, u8 alpha) { - OPEN_DISPS(this->state.gfxCtx); - gDPPipeSync(POLY_OPA_DISP++); - gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - - for (int i = 0; i < ARRAY_COUNT(itemData); i += 1) { - ItemData* data = &itemData[i]; - - if (ShouldRenderItem(fileIndex, data->item)) { - if (HasItem(fileIndex, data->item)) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, data->color.r, data->color.g, data->color.b, - color_product(data->color.a, alpha)); - } else { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, color_product(data->color.r, DIM.r), - color_product(data->color.g, DIM.g), color_product(data->color.b, DIM.b), - color_product(color_product(data->color.a, DIM.a), alpha)); - } - - SpriteLoad(this, &(data->sprite)); - SpriteDraw(this, &(data->sprite), LEFT_OFFSET + data->pos.left, TOP_OFFSET + data->pos.top, - data->size.width, data->size.height); - } - } - - gDPPipeSync(POLY_OPA_DISP++); - CLOSE_DISPS(this->state.gfxCtx); -} - -typedef enum { - /* 0x00 */ COUNTER_HEALTH, - /* 0x01 */ COUNTER_WALLET_NONE, - /* 0x02 */ COUNTER_WALLET_CHILD, - /* 0x03 */ COUNTER_WALLET_ADULT, - /* 0x04 */ COUNTER_WALLET_GIANT, - /* 0x05 */ COUNTER_WALLET_TYCOON, - /* 0x06 */ COUNTER_SKULLTULLAS, - /* 0x07 */ COUNTER_DEATHS, -} CounterID; - -typedef struct { - Sprite sprite; - Color_RGBA8 color; - u8 id; - IconPosition pos; - IconSize size; -} CounterData; - -static CounterData counterData[8] = { - { CREATE_SPRITE_24(dgQuestIconHeartContainerTex, 101), COUNTER_HEALTH, { 0x05, 0x00 }, SIZE_COUNTER }, - { CREATE_SPRITE_RUPEE(0x32, 0x40, 0x19), COUNTER_WALLET_NONE, { 0x05, 0x15 }, SIZE_COUNTER }, - { CREATE_SPRITE_RUPEE(0xC8, 0xFF, 0x64), COUNTER_WALLET_CHILD, { 0x05, 0x15 }, SIZE_COUNTER }, - { CREATE_SPRITE_RUPEE(0x82, 0x82, 0xFF), COUNTER_WALLET_ADULT, { 0x05, 0x15 }, SIZE_COUNTER }, - { CREATE_SPRITE_RUPEE(0xFF, 0x64, 0x64), COUNTER_WALLET_GIANT, { 0x05, 0x15 }, SIZE_COUNTER }, - { CREATE_SPRITE_RUPEE(0xFF, 0x5A, 0xFF), COUNTER_WALLET_TYCOON, { 0x05, 0x15 }, SIZE_COUNTER }, - { CREATE_SPRITE_24(dgQuestIconGoldSkulltulaTex, 103), COUNTER_SKULLTULLAS, { 0x05, 0x2A }, SIZE_COUNTER }, - { CREATE_SPRITE_SKULL, COUNTER_DEATHS, { 0x48, 0x2A }, SIZE_COUNTER }, -}; - -static Sprite counterDigitSprites[10] = { - CREATE_SPRITE_COUNTER_DIGIT(0), CREATE_SPRITE_COUNTER_DIGIT(1), CREATE_SPRITE_COUNTER_DIGIT(2), - CREATE_SPRITE_COUNTER_DIGIT(3), CREATE_SPRITE_COUNTER_DIGIT(4), CREATE_SPRITE_COUNTER_DIGIT(5), - CREATE_SPRITE_COUNTER_DIGIT(6), CREATE_SPRITE_COUNTER_DIGIT(7), CREATE_SPRITE_COUNTER_DIGIT(8), - CREATE_SPRITE_COUNTER_DIGIT(9), -}; - -u8 ShouldRenderCounter(s16 fileIndex, u8 counterId) { - if (counterId == COUNTER_WALLET_NONE) { - return !Save_GetSaveMetaInfo(fileIndex)->hasWallet; - } - - if (counterId == COUNTER_WALLET_CHILD) { - return Save_GetSaveMetaInfo(fileIndex)->hasWallet && - ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> - gUpgradeShifts[UPG_WALLET]) == 0; - } - - if (counterId == COUNTER_WALLET_ADULT) { - return Save_GetSaveMetaInfo(fileIndex)->hasWallet && - ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> - gUpgradeShifts[UPG_WALLET]) == 1; - } - - if (counterId == COUNTER_WALLET_GIANT) { - return Save_GetSaveMetaInfo(fileIndex)->hasWallet && - ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> - gUpgradeShifts[UPG_WALLET]) == 2; - } - - if (counterId == COUNTER_WALLET_TYCOON) { - return Save_GetSaveMetaInfo(fileIndex)->hasWallet && - ((Save_GetSaveMetaInfo(fileIndex)->upgrades & gUpgradeMasks[UPG_WALLET]) >> - gUpgradeShifts[UPG_WALLET]) == 3; - } - - return 1; -} - -u16 GetCurrentCounterValue(s16 fileIndex, u8 counter) { - // one heart is 16 healthCapacity - if (counter == COUNTER_HEALTH) { - return Save_GetSaveMetaInfo(fileIndex)->healthCapacity / 16; - } - - if (counter >= COUNTER_WALLET_CHILD && counter <= COUNTER_WALLET_TYCOON) { - return Save_GetSaveMetaInfo(fileIndex)->rupees; - } - - if (counter == COUNTER_SKULLTULLAS) { - return Save_GetSaveMetaInfo(fileIndex)->gsTokens; - } - - if (counter == COUNTER_DEATHS) { - return Save_GetSaveMetaInfo(fileIndex)->deaths; - } - - return 0; -} - -u16 GetMaxCounterValue(s16 fileIndex, u8 counter) { - if (counter == COUNTER_HEALTH) { - return 20; - } - - if (counter == COUNTER_WALLET_CHILD) { - return 99; - } - - if (counter == COUNTER_WALLET_ADULT) { - return 200; - } - - if (counter == COUNTER_WALLET_GIANT) { - return 500; - } - - if (counter == COUNTER_WALLET_TYCOON) { - return 999; - } - - if (counter == COUNTER_SKULLTULLAS) { - return 100; - } - - if (counter == COUNTER_DEATHS) { - return 999; - } - - return 0; -} - -void DrawCounterValue(FileChooseContext* this, s16 fileIndex, u8 alpha, CounterData* data) { - u16 currentValue; - u16 maxValue; - s16 hundreds; - s16 tens; - - currentValue = GetCurrentCounterValue(fileIndex, data->id); - maxValue = GetMaxCounterValue(fileIndex, data->id); - - // to prevent crashes if you use the save editor - if (currentValue > 999) { - currentValue = 999; - } - - OPEN_DISPS(this->state.gfxCtx); - gDPPipeSync(POLY_OPA_DISP++); - gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - - if (currentValue == 0) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 130, 130, 130, alpha); - } else if (currentValue == maxValue) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 120, 255, 0, alpha); - } else { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, alpha); - } - - for (hundreds = 0; currentValue >= 100; hundreds++) { - currentValue -= 100; - } - - for (tens = 0; currentValue >= 10; tens++) { - currentValue -= 10; - } - - if (hundreds != 0) { - SpriteLoad(this, &counterDigitSprites[hundreds]); - SpriteDraw(this, &counterDigitSprites[hundreds], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET - 6 + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - - SpriteLoad(this, &counterDigitSprites[tens]); - SpriteDraw(this, &counterDigitSprites[tens], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - - SpriteLoad(this, &counterDigitSprites[currentValue]); - SpriteDraw(this, &counterDigitSprites[currentValue], - LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + 6 + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - } else if (tens != 0) { - SpriteLoad(this, &counterDigitSprites[tens]); - SpriteDraw(this, &counterDigitSprites[tens], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET - 3 + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - - SpriteLoad(this, &counterDigitSprites[currentValue]); - SpriteDraw(this, &counterDigitSprites[currentValue], - LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + 3 + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - } else { - SpriteLoad(this, &counterDigitSprites[currentValue]); - SpriteDraw(this, &counterDigitSprites[currentValue], LEFT_OFFSET + COUNTER_DIGITS_LEFT_OFFSET + data->pos.left, - TOP_OFFSET + COUNTER_DIGITS_TOP_OFFSET + data->pos.top, 8, 8); - } - - gDPPipeSync(POLY_OPA_DISP++); - CLOSE_DISPS(this->state.gfxCtx); -} - -static void DrawCounters(FileChooseContext* this, s16 fileIndex, u8 alpha) { - OPEN_DISPS(this->state.gfxCtx); - gDPPipeSync(POLY_OPA_DISP++); - gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - - for (int i = 0; i < ARRAY_COUNT(counterData); i += 1) { - CounterData* data = &counterData[i]; - - if (ShouldRenderCounter(fileIndex, data->id)) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, data->color.r, data->color.g, data->color.b, - color_product(data->color.a, alpha)); - - SpriteLoad(this, &(data->sprite)); - SpriteDraw(this, &(data->sprite), LEFT_OFFSET + data->pos.left, TOP_OFFSET + data->pos.top, - data->size.width, data->size.height); - - DrawCounterValue(this, fileIndex, alpha, data); - } - } - - gDPPipeSync(POLY_OPA_DISP++); - CLOSE_DISPS(this->state.gfxCtx); -} - -static void DrawMoreInfo(FileChooseContext* this, s16 fileIndex, u8 alpha) { - DrawItems(this, fileIndex, alpha); - DrawCounters(this, fileIndex, alpha); -} - #define MIN_QUEST (ResourceMgr_GameHasOriginal() ? QUEST_NORMAL : QUEST_MASTER) #define MAX_QUEST QUEST_BOSSRUSH @@ -951,7 +276,11 @@ void SpriteLoad(FileChooseContext* this, Sprite* sprite) { * defines internally. */ - if (sprite->im_siz == G_IM_SIZ_8b) { + if (sprite->im_siz == G_IM_SIZ_4b) { + gDPLoadTextureBlock(POLY_OPA_DISP++, sprite->tex, sprite->im_fmt, G_IM_SIZ_32b, sprite->width, sprite->height, + 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else if (sprite->im_siz == G_IM_SIZ_8b) { gDPLoadTextureBlock(POLY_OPA_DISP++, sprite->tex, sprite->im_fmt, G_IM_SIZ_8b, sprite->width, sprite->height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); @@ -2185,7 +1514,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) { &deathCountSplit[2]); // draw death count - if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT) { + if (GameInteractor_Should(VB_FILE_SELECT_DRAW_DEATHS, true, this)) { for (i = 0, vtxOffset = 0; i < 3; i++, vtxOffset += 4) { FileChoose_DrawCharacter(this->state.gfxCtx, sp54->fontBuf + deathCountSplit[i] * FONT_CHAR_TEX_SIZE, vtxOffset); @@ -2211,7 +1540,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) { i = Save_GetSaveMetaInfo(fileIndex)->healthCapacity / FULL_HEART_HEALTH; - if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT) { + if (GameInteractor_Should(VB_FILE_SELECT_DRAW_HEARTS, true, this)) { // draw hearts for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) { gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex] + vtxOffset] + 0x30, 4, 0); @@ -2228,9 +1557,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) { textAlpha = 255; } - if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) != 0 && this->menuMode == FS_MENU_MODE_SELECT) { - DrawMoreInfo(this, fileIndex, textAlpha); - } else { + if (GameInteractor_Should(VB_FILE_SELECT_DRAW_QUEST_ITEMS, true, this, fileIndex, textAlpha)) { // draw quest items for (vtxOffset = 0, j = 0; j < 9; j++, vtxOffset += 4) { if (Save_GetSaveMetaInfo(fileIndex)->questItems & gBitFlags[sQuestItemFlags[j]]) { @@ -2560,17 +1887,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2], this->fileInfoAlpha[fileIndex]); - // Draw the small file name box instead when more meta info is enabled - if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) != 0 && - this->menuMode == FS_MENU_MODE_SELECT) { - // Location of file 1 small name box vertices - gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[68], 4, 0); - - gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOLOD); - gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0); - } else { + if (GameInteractor_Should(VB_FILE_SELECT_DRAW_FILE_INFO_BOX, true, this)) { gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0); for (quadVtxIndex = 0, i = 0; i < 5; i++, quadVtxIndex += 4) {