From d6492412db91e34b498cd8609dee1ea4f253e02c Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 22 Feb 2026 07:12:58 -0600 Subject: Simplify hearts & magic cosmetics and expand where they are shown (#1562) --- mm/2s2h/BenGui/CosmeticEditor.cpp | 392 +++++++++++++++++++++-- mm/2s2h/BenGui/CosmeticEditor.h | 24 +- mm/2s2h/BenGui/HudEditor.cpp | 4 +- mm/src/code/z_lifemeter.c | 50 +-- mm/src/code/z_parameter.c | 44 +-- mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c | 21 +- 6 files changed, 453 insertions(+), 82 deletions(-) diff --git a/mm/2s2h/BenGui/CosmeticEditor.cpp b/mm/2s2h/BenGui/CosmeticEditor.cpp index 605780694..0aa7da463 100644 --- a/mm/2s2h/BenGui/CosmeticEditor.cpp +++ b/mm/2s2h/BenGui/CosmeticEditor.cpp @@ -26,16 +26,8 @@ void gfx_texture_cache_clear(); // clang-format off CosmeticEditorElement cosmeticEditorElements[COSMETIC_ELEMENT_MAX] = { - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_NORMAL, "Hearts", "Normal", "Hearts.Normal", 255, 70, 50, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_NORMAL_BEATING, "Hearts", "Beating", "Hearts.Beating", 255, 70, 50, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_BORDER, "Hearts", "Border", "Hearts.Border", 50, 40, 60, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_DD, "Hearts", "DD", "Hearts.DD", 200, 0, 0, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_DD_BEATING, "Hearts", "DD Beating", "Hearts.DDBeating", 200, 0, 0, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEART_DD_BORDER, "Hearts", "DD Border", "Hearts.DDBorder", 255, 255, 255, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MAGIC_NORMAL, "Magic Meter", "Normal", "Magic.Normal", 0, 200, 0, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MAGIC_CHATEAU, "Magic Meter", "Chateau", "Magic.Chateau", 0, 0, 200, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MAGIC_CONSUMED, "Magic Meter", "Active", "Magic.Active", 250, 250, 0, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MAGIC_BORDER, "Magic Meter", "Border", "Magic.Border", 255, 255, 255, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HEARTS, "HUD", "Hearts", "HUD.Hearts", 255, 70, 50, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MAGIC, "HUD", "Magic", "HUD.Magic", 0, 200, 0, 255), COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_SMALL_KEY, "HUD", "Small Key", "HUD.SmallKey", 0, 200, 230, 255), COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_RUPEE_ICON, "HUD", "Rupee Icon", "HUD.RupeeIcon", 200, 255, 100, 255), COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_MINIMAP, "HUD", "Minimap", "HUD.Minimap", 0, 255, 255, 160), @@ -58,13 +50,13 @@ CosmeticEditorElement cosmeticEditorElements[COSMETIC_ELEMENT_MAX] = { COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_START_BUTTON, "Buttons", "Start", "Buttons.Start", 255, 130, 60, 255), COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_FILE_SELECT_MENU, "Menus", "File Select Window", "Menus.FileWindow", 100, 150, 255, 255), COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_FILE_SELECT_PLATES, "Menus", "File Select Plates", "Menus.FilePlates", 100, 150, 255, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HUMAN_TUNIC, "Player", "Human Tunic", "Player.HumanTunic", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HUMAN_HAIR, "Player", "Human Hair", "Player.HumanHair", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_DEKU_TUNIC, "Player", "Deku Tunic", "Player.DekuTunic", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_DEKU_HAIR, "Player", "Deku Hair", "Player.DekuHair", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_GORON_TUNIC, "Player", "Goron Tunic", "Player.GoronTunic", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_ZORA_TUNIC, "Player", "Zora Tunic", "Player.ZoraTunic", 30, 105, 27, 255), - COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_KAFEI_HAIR, "Player", "Kafei Hair", "Player.KafeiHair", 30, 105, 27, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HUMAN_TUNIC, "Player", "Human Tunic", "Player.HumanTunic", 30, 105, 27, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_HUMAN_HAIR, "Player", "Human Hair", "Player.HumanHair", 255, 240, 0, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_DEKU_TUNIC, "Player", "Deku Tunic", "Player.DekuTunic", 30, 105, 27, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_DEKU_HAIR, "Player", "Deku Hair", "Player.DekuHair", 255, 240, 0, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_GORON_TUNIC, "Player", "Goron Tunic", "Player.GoronTunic", 30, 105, 27, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_ZORA_TUNIC, "Player", "Zora Tunic", "Player.ZoraTunic", 30, 105, 27, 255), + COSMETIC_EDITOR_ELEMENT(COSMETIC_ELEMENT_KAFEI_HAIR, "Player", "Kafei Hair", "Player.KafeiHair", 64, 0, 163, 255), }; // clang-format on @@ -116,6 +108,17 @@ Gfx backToWhite[] = { gsSPEndDisplayList(), }; +Gfx enableGrayscale[] = { + gsSPGrayscale(1), + gsDPPipeSync(), + gsSPEndDisplayList(), +}; + +Gfx disableGrayscale[] = { + gsSPGrayscale(0), + gsSPEndDisplayList(), +}; + // First, it pulls all colors from the palette. Then it finds the average color across the range, and calculates the // difference between the average color and the target color. It then colors the range according to newBase, // and shades it lighter or darker based on the difference between the average color and the target color. @@ -253,6 +256,102 @@ void ShadePaletteGradient(const char* path, uint32_t begin, uint32_t end, Color_ } } +// Patches a single pixel in a raw RGBA16 (RGBA5551) texture, preserving the original alpha bit. +void PatchRGBA16Pixel(const char* path, int index, uint8_t r, uint8_t g, uint8_t b) { + auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path); + auto data = (uint8_t*)res->GetRawPointer(); + + if (!originalRGB.contains(path) || !originalRGB[path].contains(index)) { + originalRGB[path][index] = { + data[index * 2], + data[index * 2 + 1], + }; + } + + // Preserve the original alpha bit so transparent pixels stay transparent. + uint8_t a = data[index * 2 + 1] & 1; + uint16_t col16 = (r << 11) | (g << 6) | (b << 1) | a; + data[index * 2] = col16 >> 8; + data[index * 2 + 1] = col16 & 0xff; +} + +/* + * Recolors a raw RGBA16 (RGBA5551) texture. Unlike ShadePaletteNewBase, this preserves each + * pixel's alpha bit and skips fully transparent pixels when computing the luminance reference, + * so transparent background areas are left untouched. + */ +void ShadeRGBA16NewBase(const char* path, uint32_t begin, uint32_t end, Color_RGBA8 newBase, SHADE_MODE mode) { + auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path); + auto data = (uint8_t*)res->GetRawPointer(); + + uint32_t maxR = 0; + uint32_t maxG = 0; + uint32_t maxB = 0; + + for (uint32_t i = begin; i <= end; i++) { + UnpatchPalette(path, i); + + uint16_t col16 = (data[i * 2] << 8) | data[i * 2 + 1]; + uint8_t a = col16 & 1; + if (a == 0) { + continue; // skip transparent pixels + } + + uint8_t r = col16 >> 11; + uint8_t g = (col16 >> 6) & 0x1f; + uint8_t b = (col16 >> 1) & 0x1f; + + maxR = MAX(maxR, r); + maxG = MAX(maxG, g); + maxB = MAX(maxB, b); + } + + if (mode == MODE_REVERT) { + return; + } + + for (uint32_t i = begin; i <= end; i++) { + uint16_t col16 = (data[i * 2] << 8) | data[i * 2 + 1]; + uint8_t a = col16 & 1; + uint8_t r = col16 >> 11; + uint8_t g = (col16 >> 6) & 0x1f; + uint8_t b = (col16 >> 1) & 0x1f; + + if (a == 0) { + // Set transparent pixels to black so that bilinear filtering at edges + // blends toward black (neutral) rather than bleeding the original color. + // Using full brightness here would create a harsh colored halo at edges. + PatchRGBA16Pixel(path, i, 0, 0, 0); + continue; + } + + int8_t diffR = maxR - r; + int8_t diffG = maxG - g; + int8_t diffB = maxB - b; + + int8_t diff = 0; + if (mode == MODE_AVG) { + diff = (diffR + diffG + diffB) / 3; + } else if (mode == MODE_MIN) { + diff = MIN(MIN(diffR, diffG), diffB); + } else if (mode == MODE_MAX) { + diff = MAX(MAX(diffR, diffG), diffB); + } + + diff = MIN(MAX(31 - diff, 0), 31); + + r = (diff * newBase.r) / 255; + g = (diff * newBase.g) / 255; + b = (diff * newBase.b) / 255; + + PatchRGBA16Pixel(path, i, r, g, b); + } +} + +void ShadeRGBA16Revert(const char* path, uint32_t begin, uint32_t end) { + ShadeRGBA16NewBase(path, begin, end, whiteBase, MODE_REVERT); +} + void CopyFloatArray(CosmeticEditorElementID id, float currentColor[4], bool isChanged) { if (isChanged) { Color_RGBA8 changedColor = CVarGetColor(cosmeticEditorElements[id].colorCvar, {}); @@ -268,7 +367,7 @@ void CopyFloatArray(CosmeticEditorElementID id, float currentColor[4], bool isCh } }; -extern "C" Color_RGBA8 CosmeticEditor_GetChangedColor(u8 r, u8 g, u8 b, u8 a, u8 elementId) { +extern "C" Color_RGBA8 CosmeticEditor_GetChangedColorEx(u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, f32 modifier) { CosmeticEditorElement element = cosmeticEditorElements[elementId]; Color_RGBA8 returnedColor; @@ -279,6 +378,96 @@ extern "C" Color_RGBA8 CosmeticEditor_GetChangedColor(u8 r, u8 g, u8 b, u8 a, u8 returnedColor.g = static_cast(changedColor.g); returnedColor.b = static_cast(changedColor.b); returnedColor.a = static_cast(255); + + switch (mode) { + case COSMETIC_COLOR_MODE_DEFAULT: + break; + case COSMETIC_COLOR_MODE_MULTIPLY: + returnedColor.r = MAX(MIN(static_cast(returnedColor.r * modifier), 255), 0); + returnedColor.g = MAX(MIN(static_cast(returnedColor.g * modifier), 255), 0); + returnedColor.b = MAX(MIN(static_cast(returnedColor.b * modifier), 255), 0); + break; + case COSMETIC_COLOR_MODE_DIVIDE: + if (modifier != 0) { + returnedColor.r = MAX(MIN(static_cast(returnedColor.r / modifier), 255), 0); + returnedColor.g = MAX(MIN(static_cast(returnedColor.g / modifier), 255), 0); + returnedColor.b = MAX(MIN(static_cast(returnedColor.b / modifier), 255), 0); + } + break; + case COSMETIC_COLOR_MODE_ADD: + returnedColor.r = MAX(MIN(static_cast(returnedColor.r + modifier), 255), 0); + returnedColor.g = MAX(MIN(static_cast(returnedColor.g + modifier), 255), 0); + returnedColor.b = MAX(MIN(static_cast(returnedColor.b + modifier), 255), 0); + break; + case COSMETIC_COLOR_MODE_SUBTRACT: + returnedColor.r = MAX(MIN(static_cast(returnedColor.r - modifier), 255), 0); + returnedColor.g = MAX(MIN(static_cast(returnedColor.g - modifier), 255), 0); + returnedColor.b = MAX(MIN(static_cast(returnedColor.b - modifier), 255), 0); + break; + case COSMETIC_COLOR_MODE_ROTATE: { + // Rotate hue by modifier degrees (0-360). Example: green (0,200,0) + 120 => blue (0,0,200) + float rf = returnedColor.r / 255.0f; + float gf = returnedColor.g / 255.0f; + float bf = returnedColor.b / 255.0f; + + float maxC = std::max({ rf, gf, bf }); + float minC = std::min({ rf, gf, bf }); + float delta = maxC - minC; + + float h = 0.0f, s = 0.0f, v = maxC; + if (delta > 0.0f) { + s = delta / maxC; + if (maxC == rf) { + h = 60.0f * fmodf((gf - bf) / delta, 6.0f); + } else if (maxC == gf) { + h = 60.0f * ((bf - rf) / delta + 2.0f); + } else { + h = 60.0f * ((rf - gf) / delta + 4.0f); + } + if (h < 0.0f) + h += 360.0f; + } + + h = fmodf(h + modifier, 360.0f); + if (h < 0.0f) + h += 360.0f; + + float c = v * s; + float x = c * (1.0f - fabsf(fmodf(h / 60.0f, 2.0f) - 1.0f)); + float m = v - c; + float r1 = 0.0f, g1 = 0.0f, b1 = 0.0f; + if (h < 60.0f) { + r1 = c; + g1 = x; + b1 = 0; + } else if (h < 120.0f) { + r1 = x; + g1 = c; + b1 = 0; + } else if (h < 180.0f) { + r1 = 0; + g1 = c; + b1 = x; + } else if (h < 240.0f) { + r1 = 0; + g1 = x; + b1 = c; + } else if (h < 300.0f) { + r1 = x; + g1 = 0; + b1 = c; + } else { + r1 = c; + g1 = 0; + b1 = x; + } + + returnedColor.r = static_cast((r1 + m) * 255.0f); + returnedColor.g = static_cast((g1 + m) * 255.0f); + returnedColor.b = static_cast((b1 + m) * 255.0f); + break; + } + } } else { returnedColor.r = r; returnedColor.g = g; @@ -289,16 +478,29 @@ extern "C" Color_RGBA8 CosmeticEditor_GetChangedColor(u8 r, u8 g, u8 b, u8 a, u8 return returnedColor; } -extern "C" void gDPSetEnvColorOverride(Gfx* pkt, u8 r, u8 g, u8 b, u8 a, u8 elementId) { - Color_RGBA8 setColor = CosmeticEditor_GetChangedColor(r, g, b, a, elementId); +extern "C" Color_RGBA8 CosmeticEditor_GetChangedColor(u8 r, u8 g, u8 b, u8 a, u8 elementId) { + return CosmeticEditor_GetChangedColorEx(r, g, b, a, elementId, COSMETIC_COLOR_MODE_DEFAULT, 0.0f); +} + +extern "C" void gDPSetEnvColorOverrideEx(Gfx* pkt, u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, f32 modifier) { + Color_RGBA8 setColor = CosmeticEditor_GetChangedColorEx(r, g, b, a, elementId, mode, modifier); gDPSetEnvColor(pkt, setColor.r, setColor.g, setColor.b, a); } -extern "C" void gDPSetPrimColorOverride(Gfx* pkt, u8 m, u8 l, u8 r, u8 g, u8 b, u8 a, u8 elementId) { - Color_RGBA8 setColor = CosmeticEditor_GetChangedColor(r, g, b, a, elementId); +extern "C" void gDPSetEnvColorOverride(Gfx* pkt, u8 r, u8 g, u8 b, u8 a, u8 elementId) { + return gDPSetEnvColorOverrideEx(pkt, r, g, b, a, elementId, COSMETIC_COLOR_MODE_DEFAULT, 0.0f); +} + +extern "C" void gDPSetPrimColorOverrideEx(Gfx* pkt, u8 m, u8 l, u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, + f32 modifier) { + Color_RGBA8 setColor = CosmeticEditor_GetChangedColorEx(r, g, b, a, elementId, mode, modifier); gDPSetPrimColor(pkt, m, l, setColor.r, setColor.g, setColor.b, a); } +extern "C" void gDPSetPrimColorOverride(Gfx* pkt, u8 m, u8 l, u8 r, u8 g, u8 b, u8 a, u8 elementId) { + return gDPSetPrimColorOverrideEx(pkt, m, l, r, g, b, a, elementId, COSMETIC_COLOR_MODE_DEFAULT, 0.0f); +} + extern "C" Gfx* Gfx_DrawTexRectIA8_DropShadowOverride(Gfx* pkt, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b, s16 a, u8 elementId) { @@ -767,3 +969,149 @@ static RegisterShipInitFunc zoraTunicPatch( gfx_texture_cache_clear(); }, { cosmeticEditorElements[COSMETIC_ELEMENT_ZORA_TUNIC].colorChangedCvar }); + +// COSMETIC_ELEMENT_HEARTS + +Gfx heartsColorDL[] = { + gsDPSetPrimColor(0, 0, 0, 0, 0, 0), + gsDPSetGrayscaleColor(0, 0, 0, 0), + gsSPEndDisplayList(), +}; + +Gfx heartsEnvColorDL[] = { + gsDPSetEnvColor(0, 0, 0, 0), + gsSPEndDisplayList(), +}; + +static RegisterShipInitFunc heartsColorDLPatch( + []() { + if (CVarGetInteger(cosmeticEditorElements[COSMETIC_ELEMENT_HEARTS].colorChangedCvar, 0)) { + ResourceMgr_PatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "enableGrayscale", 2, + gsSPDisplayList(enableGrayscale)); + ResourceMgr_PatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "setPrim", 5, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "disableGrayscale", 36, + gsSPBranchList(disableGrayscale)); + ResourceMgr_PatchGfxByName("objects/gameplay_keep/gHeartPieceInteriorDL", "setPrim", 56, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_hearts/gGiHeartPieceDL", "setPrim", 2, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_hearts/gGiHeartPieceDL", "setEnv", 6, + gsSPDisplayList(heartsEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_hearts/gGiHeartContainerDL", "setPrim", 2, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_hearts/gGiHeartContainerDL", "setEnv", 6, + gsSPDisplayList(heartsEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_bottle_red/gGiRedPotionBottleDL", "setPrim", 5, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_bottle_red/gGiRedPotionBottleDL", "setEnv", 6, + gsSPDisplayList(heartsEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPotColorDL", "setPrim", 3, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPotColorDL", "setEnv", 4, + gsSPDisplayList(heartsEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPatternColorDL", "setPrim", 3, + gsSPDisplayList(heartsColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPatternColorDL", "setEnv", 4, + gsSPDisplayList(heartsEnvColorDL)); + + Color_RGBA8 changedColor = CVarGetColor(cosmeticEditorElements[COSMETIC_ELEMENT_HEARTS].colorCvar, {}); + ShadeRGBA16NewBase("objects/gameplay_keep/gDropRecoveryHeartTex", 0, 1023, changedColor, MODE_AVG); + } else { + ResourceMgr_UnpatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "enableGrayscale"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_heart/gGiRecoveryHeartDL", "disableGrayscale"); + ResourceMgr_UnpatchGfxByName("objects/gameplay_keep/gHeartPieceInteriorDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_hearts/gGiHeartPieceDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_hearts/gGiHeartPieceDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_hearts/gGiHeartContainerDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_hearts/gGiHeartContainerDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_bottle_red/gGiRedPotionBottleDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_bottle_red/gGiRedPotionBottleDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPotColorDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPotColorDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPatternColorDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerRedPatternColorDL", "setEnv"); + + ShadeRGBA16Revert("objects/gameplay_keep/gDropRecoveryHeartTex", 0, 1023); + } + gfx_texture_cache_clear(); + }, + { cosmeticEditorElements[COSMETIC_ELEMENT_HEARTS].colorChangedCvar }); + +static RegisterShipInitFunc heartsColorDLUpdate( + []() { + Color_RGBA8 primColor = CosmeticEditor_GetChangedColor(0, 0, 0, 0, COSMETIC_ELEMENT_HEARTS); + heartsColorDL[0] = gsDPSetPrimColor(0, 0, primColor.r, primColor.g, primColor.b, 255); + heartsColorDL[1] = gsDPSetGrayscaleColor(primColor.r, primColor.g, primColor.b, 255); + + Color_RGBA8 envColor = + CosmeticEditor_GetChangedColorEx(0, 0, 0, 0, COSMETIC_ELEMENT_HEARTS, COSMETIC_COLOR_MODE_DIVIDE, 2.0f); + heartsEnvColorDL[0] = gsDPSetEnvColor(envColor.r, envColor.g, envColor.b, 255); + }, + { cosmeticEditorElements[COSMETIC_ELEMENT_HEARTS].colorCvar }); + +// COSMETIC_ELEMENT_MAGIC + +Gfx magicColorDL[] = { + gsDPSetPrimColor(0, 0, 0, 0, 0, 0), + gsDPSetGrayscaleColor(0, 0, 0, 0), + gsSPEndDisplayList(), +}; + +Gfx magicEnvColorDL[] = { + gsDPSetEnvColor(0, 0, 0, 0), + gsSPEndDisplayList(), +}; + +static RegisterShipInitFunc magicColorDLPatch( + []() { + if (CVarGetInteger(cosmeticEditorElements[COSMETIC_ELEMENT_MAGIC].colorChangedCvar, 0)) { + ResourceMgr_PatchGfxByName("objects/object_gi_magicpot/gGiMagicJarLargeDL", "setPrim", 31, + gsSPDisplayList(magicColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_magicpot/gGiMagicJarLargeDL", "setEnv", 32, + gsSPDisplayList(magicEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_magicpot/gGiMagicJarSmallDL", "setPrim", 31, + gsSPDisplayList(magicColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_magicpot/gGiMagicJarSmallDL", "setEnv", 32, + gsSPDisplayList(magicEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPotColorDL", "setPrim", 3, + gsSPDisplayList(magicColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPotColorDL", "setEnv", 4, + gsSPDisplayList(magicEnvColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPatternColorDL", "setPrim", 3, + gsSPDisplayList(magicColorDL)); + ResourceMgr_PatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPatternColorDL", "setEnv", 4, + gsSPDisplayList(magicEnvColorDL)); + + Color_RGBA8 changedColor = CVarGetColor(cosmeticEditorElements[COSMETIC_ELEMENT_MAGIC].colorCvar, {}); + ShadeRGBA16NewBase("objects/gameplay_keep/gDropMagicSmallTex", 0, 1023, changedColor, MODE_AVG); + ShadeRGBA16NewBase("objects/gameplay_keep/gDropMagicLargeTex", 0, 1023, changedColor, MODE_AVG); + } else { + ResourceMgr_UnpatchGfxByName("objects/object_gi_magicpot/gGiMagicJarLargeDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_magicpot/gGiMagicJarLargeDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_magicpot/gGiMagicJarSmallDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_magicpot/gGiMagicJarSmallDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPotColorDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPotColorDL", "setEnv"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPatternColorDL", "setPrim"); + ResourceMgr_UnpatchGfxByName("objects/object_gi_liquid/gGiPotionContainerGreenPatternColorDL", "setEnv"); + + ShadeRGBA16Revert("objects/gameplay_keep/gDropMagicSmallTex", 0, 1023); + ShadeRGBA16Revert("objects/gameplay_keep/gDropMagicLargeTex", 0, 1023); + } + gfx_texture_cache_clear(); + }, + { cosmeticEditorElements[COSMETIC_ELEMENT_MAGIC].colorChangedCvar }); + +static RegisterShipInitFunc magicColorDLUpdate( + []() { + Color_RGBA8 primColor = CosmeticEditor_GetChangedColor(0, 0, 0, 0, COSMETIC_ELEMENT_MAGIC); + magicColorDL[0] = gsDPSetPrimColor(0, 0, primColor.r, primColor.g, primColor.b, 255); + magicColorDL[1] = gsDPSetGrayscaleColor(primColor.r, primColor.g, primColor.b, 255); + + Color_RGBA8 envColor = + CosmeticEditor_GetChangedColorEx(0, 0, 0, 0, COSMETIC_ELEMENT_MAGIC, COSMETIC_COLOR_MODE_DIVIDE, 2.0f); + magicEnvColorDL[0] = gsDPSetEnvColor(envColor.r, envColor.g, envColor.b, 255); + }, + { cosmeticEditorElements[COSMETIC_ELEMENT_MAGIC].colorCvar }); diff --git a/mm/2s2h/BenGui/CosmeticEditor.h b/mm/2s2h/BenGui/CosmeticEditor.h index b3d522711..e4558ec85 100644 --- a/mm/2s2h/BenGui/CosmeticEditor.h +++ b/mm/2s2h/BenGui/CosmeticEditor.h @@ -15,7 +15,9 @@ class CosmeticEditorWindow : public Ship::GuiWindow { extern "C" { #endif //__cplusplus +void gDPSetPrimColorOverrideEx(Gfx* pkt, u8 m, u8 l, u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, f32 modifier); void gDPSetPrimColorOverride(Gfx* pkt, u8 m, u8 l, u8 r, u8 g, u8 b, u8 a, u8 elementId); +void gDPSetEnvColorOverrideEx(Gfx* pkt, u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, f32 modifier); void gDPSetEnvColorOverride(Gfx* pkt, u8 r, u8 g, u8 b, u8 a, u8 elementId); Gfx* Gfx_DrawTexRectIA8_DropShadowOverride(Gfx* pkt, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, @@ -29,19 +31,12 @@ Gfx* Gfx_DrawTexRectIA8_DropShadowOffsetOverride(Gfx* pkt, TexturePtr texture, s s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b, s16 a, s32 masks, s32 rects, u8 elementId); +Color_RGBA8 CosmeticEditor_GetChangedColorEx(u8 r, u8 g, u8 b, u8 a, u8 elementId, u8 mode, f32 modifier); Color_RGBA8 CosmeticEditor_GetChangedColor(u8 r, u8 g, u8 b, u8 a, u8 elementId); typedef enum { - COSMETIC_ELEMENT_HEART_NORMAL, - COSMETIC_ELEMENT_HEART_NORMAL_BEATING, - COSMETIC_ELEMENT_HEART_BORDER, - COSMETIC_ELEMENT_HEART_DD, - COSMETIC_ELEMENT_HEART_DD_BEATING, - COSMETIC_ELEMENT_HEART_DD_BORDER, - COSMETIC_ELEMENT_MAGIC_NORMAL, - COSMETIC_ELEMENT_MAGIC_CHATEAU, - COSMETIC_ELEMENT_MAGIC_CONSUMED, - COSMETIC_ELEMENT_MAGIC_BORDER, + COSMETIC_ELEMENT_HEARTS, + COSMETIC_ELEMENT_MAGIC, COSMETIC_ELEMENT_SMALL_KEY, COSMETIC_ELEMENT_RUPEE_ICON, COSMETIC_ELEMENT_MINIMAP, @@ -74,6 +69,15 @@ typedef enum { COSMETIC_ELEMENT_MAX } CosmeticEditorElementID; +typedef enum { + COSMETIC_COLOR_MODE_DEFAULT, + COSMETIC_COLOR_MODE_MULTIPLY, + COSMETIC_COLOR_MODE_DIVIDE, + COSMETIC_COLOR_MODE_ADD, + COSMETIC_COLOR_MODE_SUBTRACT, + COSMETIC_COLOR_MODE_ROTATE, +} CosmeticEditorColorMode; + typedef struct { CosmeticEditorElementID id; const char* parentName; diff --git a/mm/2s2h/BenGui/HudEditor.cpp b/mm/2s2h/BenGui/HudEditor.cpp index 08cd56e91..07f05b1a7 100644 --- a/mm/2s2h/BenGui/HudEditor.cpp +++ b/mm/2s2h/BenGui/HudEditor.cpp @@ -21,8 +21,8 @@ HudEditorElement hudEditorElements[HUD_EDITOR_ELEMENT_MAX] = { HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_START, "Start Button", "Start", 136, 17, 255, 130, 60, 255, COSMETIC_ELEMENT_START_BUTTON), HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_CARROT, "Horse Carrots", "Carrots", 160, 64, 236, 92, 41, 255, HUD_EDITOR_NO_COSMETIC), HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_CLOCK, "Three Day Clock", "Clock", 160, 206, 255, 255, 255, 255, HUD_EDITOR_NO_COSMETIC), - HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_HEARTS, "Hearts", "Hearts", 30, 26, 255, 70, 50, 255, COSMETIC_ELEMENT_HEART_NORMAL), - HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_MAGIC_METER, "Magic", "Magic", 18, 34, 0, 200, 0, 255, COSMETIC_ELEMENT_MAGIC_NORMAL), + HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_HEARTS, "Hearts", "Hearts", 30, 26, 255, 70, 50, 255, COSMETIC_ELEMENT_HEARTS), + HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_MAGIC_METER, "Magic", "Magic", 18, 34, 0, 200, 0, 255, COSMETIC_ELEMENT_MAGIC), HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_TIMERS, "Timers", "Timers", 26, 46, 255, 255, 255, 255, HUD_EDITOR_NO_COSMETIC), HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_TIMERS_MOON_CRASH, "Timer - Skull Kid", "SkullKidTimer", 115, 200, 255, 255, 255, 255, HUD_EDITOR_NO_COSMETIC), HUD_EDITOR_ELEMENT(HUD_EDITOR_ELEMENT_MINIGAME_COUNTER, "Minigames", "Minigames", 20, 67, 255, 255, 255, 255, HUD_EDITOR_NO_COSMETIC), diff --git a/mm/src/code/z_lifemeter.c b/mm/src/code/z_lifemeter.c index d003ca287..45406350a 100644 --- a/mm/src/code/z_lifemeter.c +++ b/mm/src/code/z_lifemeter.c @@ -253,10 +253,11 @@ void LifeMeter_Draw(PlayState* play) { // Normal Heart gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0], interfaceCtx->heartsPrimB[0], - interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEART_NORMAL); + interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEARTS); // Normal Heart Border - gDPSetEnvColorOverride(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0], - interfaceCtx->heartsEnvB[0], 255, COSMETIC_ELEMENT_HEART_BORDER); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0], + interfaceCtx->heartsEnvB[0], 255, COSMETIC_ELEMENT_HEARTS, + COSMETIC_COLOR_MODE_DIVIDE, 4.0f); } } else if (i == fullHeartCount) { if (curColorSet != 1) { @@ -265,11 +266,11 @@ void LifeMeter_Draw(PlayState* play) { // Normal Beating Heart gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, interfaceCtx->beatingHeartPrim[0], interfaceCtx->beatingHeartPrim[1], interfaceCtx->beatingHeartPrim[2], - interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEART_NORMAL_BEATING); + interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEARTS); // Normal Beating Heart Border - gDPSetEnvColorOverride(OVERLAY_DISP++, interfaceCtx->beatingHeartEnv[0], - interfaceCtx->beatingHeartEnv[1], interfaceCtx->beatingHeartEnv[2], 255, - COSMETIC_ELEMENT_HEART_BORDER); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, interfaceCtx->beatingHeartEnv[0], + interfaceCtx->beatingHeartEnv[1], interfaceCtx->beatingHeartEnv[2], 255, + COSMETIC_ELEMENT_HEARTS, COSMETIC_COLOR_MODE_DIVIDE, 4.0f); } } else if (fullHeartCount < i) { if (curColorSet != 2) { @@ -277,9 +278,10 @@ void LifeMeter_Draw(PlayState* play) { gDPPipeSync(OVERLAY_DISP++); gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0], interfaceCtx->heartsPrimB[0], - interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEART_NORMAL); - gDPSetEnvColorOverride(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0], - interfaceCtx->heartsEnvB[0], 255, COSMETIC_ELEMENT_HEART_BORDER); + interfaceCtx->healthAlpha, COSMETIC_ELEMENT_HEARTS); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0], + interfaceCtx->heartsEnvB[0], 255, COSMETIC_ELEMENT_HEARTS, + COSMETIC_COLOR_MODE_DIVIDE, 4.0f); } } else { if (curColorSet != 3) { @@ -305,36 +307,34 @@ void LifeMeter_Draw(PlayState* play) { curColorSet = 4; gDPPipeSync(OVERLAY_DISP++); // Double Defense Heart Border - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], - sHeartsDDPrim[0][2], interfaceCtx->healthAlpha, - COSMETIC_ELEMENT_HEART_DD_BORDER); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2], + interfaceCtx->healthAlpha); // Double Defense Non Active Heart - gDPSetEnvColorOverride(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], - 255, COSMETIC_ELEMENT_HEART_DD); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], + 255, COSMETIC_ELEMENT_HEARTS, COSMETIC_COLOR_MODE_SUBTRACT, 55.0f); } } else if (i == fullHeartCount) { if (curColorSet != 5) { curColorSet = 5; gDPPipeSync(OVERLAY_DISP++); // Double Defense Beating Heart Border - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, sBeatingHeartsDDPrim[0], sBeatingHeartsDDPrim[1], - sBeatingHeartsDDPrim[2], interfaceCtx->healthAlpha, - COSMETIC_ELEMENT_HEART_DD_BORDER); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sBeatingHeartsDDPrim[0], sBeatingHeartsDDPrim[1], + sBeatingHeartsDDPrim[2], interfaceCtx->healthAlpha); // Double Defense Beating Heart - gDPSetEnvColorOverride(OVERLAY_DISP++, sBeatingHeartsDDEnv[0], sBeatingHeartsDDEnv[1], - sBeatingHeartsDDEnv[2], 255, COSMETIC_ELEMENT_HEART_DD_BEATING); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, sBeatingHeartsDDEnv[0], sBeatingHeartsDDEnv[1], + sBeatingHeartsDDEnv[2], 255, COSMETIC_ELEMENT_HEARTS, + COSMETIC_COLOR_MODE_SUBTRACT, 55.0f); } } else if (i > fullHeartCount) { if (curColorSet != 6) { curColorSet = 6; gDPPipeSync(OVERLAY_DISP++); // Double Defense Empty Heart Border - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], - sHeartsDDPrim[0][2], interfaceCtx->healthAlpha, - COSMETIC_ELEMENT_HEART_DD_BORDER); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2], + interfaceCtx->healthAlpha); // Double Defense Empty Heart - gDPSetEnvColorOverride(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], - 255, COSMETIC_ELEMENT_HEART_DD); + gDPSetEnvColorOverrideEx(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], + 255, COSMETIC_ELEMENT_HEARTS, COSMETIC_COLOR_MODE_SUBTRACT, 55.0f); } } else if (curColorSet != 7) { curColorSet = 7; diff --git a/mm/src/code/z_parameter.c b/mm/src/code/z_parameter.c index 911c319dd..9972a1e00 100644 --- a/mm/src/code/z_parameter.c +++ b/mm/src/code/z_parameter.c @@ -5642,20 +5642,19 @@ void Magic_DrawMeter(PlayState* play) { gDPSetEnvColor(OVERLAY_DISP++, 100, 50, 50, 255); HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_MAGIC_METER); - OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadowOverride(OVERLAY_DISP, gMagicMeterEndTex, 8, 16, 18, magicBarY, 8, - 16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, - sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue, - interfaceCtx->magicAlpha, COSMETIC_ELEMENT_MAGIC_BORDER); + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadow( + OVERLAY_DISP, gMagicMeterEndTex, 8, 16, 18, magicBarY, 8, 16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, + sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha); HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_MAGIC_METER); - OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadowOverride( - OVERLAY_DISP, gMagicMeterMidTex, 24, 16, 26, magicBarY, ((void)0, gSaveContext.magicCapacity), 16, 1 << 10, - 1 << 10, sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue, - interfaceCtx->magicAlpha, COSMETIC_ELEMENT_MAGIC_BORDER); + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadow(OVERLAY_DISP, gMagicMeterMidTex, 24, 16, 26, magicBarY, + ((void)0, gSaveContext.magicCapacity), 16, 1 << 10, 1 << 10, + sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen, + sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha); HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_MAGIC_METER); - OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadowOffsetOverride( + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadowOffset( OVERLAY_DISP, gMagicMeterEndTex, 8, 16, ((void)0, gSaveContext.magicCapacity) + 26, magicBarY, 8, 16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue, - interfaceCtx->magicAlpha, 3, 0x100, COSMETIC_ELEMENT_MAGIC_BORDER); + interfaceCtx->magicAlpha, 3, 0x100); gDPPipeSync(OVERLAY_DISP++); gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE, PRIMITIVE, @@ -5664,8 +5663,8 @@ void Magic_DrawMeter(PlayState* play) { if (gSaveContext.magicState == MAGIC_STATE_METER_FLASH_2) { // Yellow part of the meter indicating the amount of magic to be subtracted - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha, - COSMETIC_ELEMENT_MAGIC_CONSUMED); + gDPSetPrimColorOverrideEx(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha, + COSMETIC_ELEMENT_MAGIC, COSMETIC_COLOR_MODE_ROTATE, -60.0f); gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 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); @@ -5702,12 +5701,12 @@ void Magic_DrawMeter(PlayState* play) { gDPPipeSync(OVERLAY_DISP++); if (CHECK_WEEKEVENTREG(WEEKEVENTREG_DRANK_CHATEAU_ROMANI)) { // Blue magic - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha, - COSMETIC_ELEMENT_MAGIC_CHATEAU); + gDPSetPrimColorOverrideEx(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha, + COSMETIC_ELEMENT_MAGIC, COSMETIC_COLOR_MODE_ROTATE, 120.0f); } else { // Green magic (default) gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha, - COSMETIC_ELEMENT_MAGIC_NORMAL); + COSMETIC_ELEMENT_MAGIC); } // #region 2S2H [Cosmetic] Hud Editor @@ -5744,12 +5743,12 @@ void Magic_DrawMeter(PlayState* play) { // Fill the whole meter with the normal magic color if (CHECK_WEEKEVENTREG(WEEKEVENTREG_DRANK_CHATEAU_ROMANI)) { // Blue magic - gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha, - COSMETIC_ELEMENT_MAGIC_CHATEAU); + gDPSetPrimColorOverrideEx(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha, + COSMETIC_ELEMENT_MAGIC, COSMETIC_COLOR_MODE_ROTATE, 120.0f); } else { // Green magic (default) gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha, - COSMETIC_ELEMENT_MAGIC_NORMAL); + COSMETIC_ELEMENT_MAGIC); } gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, @@ -6056,11 +6055,14 @@ void Interface_DrawItemButtons(PlayState* play) { for (temp = EQUIP_SLOT_C_LEFT; temp <= EQUIP_SLOT_C_RIGHT; temp++) { if (GET_CUR_FORM_BTN_ITEM(temp) > 0xF0) { if (temp == EQUIP_SLOT_C_LEFT) { - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cLeftAlpha); + gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cLeftAlpha, + COSMETIC_ELEMENT_C_LEFT_BUTTON); } else if (temp == EQUIP_SLOT_C_DOWN) { - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cDownAlpha); + gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cDownAlpha, + COSMETIC_ELEMENT_C_DOWN_BUTTON); } else { // EQUIP_SLOT_C_RIGHT - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cRightAlpha); + gDPSetPrimColorOverride(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cRightAlpha, + COSMETIC_ELEMENT_C_RIGHT_BUTTON); } HudEditor_SetActiveElement(temp); OVERLAY_DISP = diff --git a/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c b/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c index eaa0a11e1..6e0ccfab7 100644 --- a/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c +++ b/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c @@ -9,6 +9,7 @@ #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/BenGui/CosmeticEditor.h" #define FLAGS \ (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \ @@ -1185,8 +1186,24 @@ void EnSlime_Draw(Actor* thisx, PlayState* play) { primColor = &sPrimColors[this->actor.params]; envColor = &sEnvColors[this->actor.params]; AnimatedMat_Draw(play, sSlimeTexAnim); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 100, primColor->r, primColor->g, primColor->b, primColor->a); - gDPSetEnvColor(POLY_XLU_DISP++, envColor->r, envColor->g, envColor->b, 255); + switch (this->actor.params) { + case EN_SLIME_TYPE_GREEN: + gDPSetPrimColorOverride(POLY_XLU_DISP++, 0, 100, primColor->r, primColor->g, primColor->b, primColor->a, + COSMETIC_ELEMENT_MAGIC); + gDPSetEnvColorOverride(POLY_XLU_DISP++, envColor->r, envColor->g, envColor->b, 255, + COSMETIC_ELEMENT_MAGIC); + break; + case EN_SLIME_TYPE_RED: + gDPSetPrimColorOverride(POLY_XLU_DISP++, 0, 100, primColor->r, primColor->g, primColor->b, primColor->a, + COSMETIC_ELEMENT_HEARTS); + gDPSetEnvColorOverride(POLY_XLU_DISP++, envColor->r, envColor->g, envColor->b, 255, + COSMETIC_ELEMENT_HEARTS); + break; + default: + gDPSetPrimColor(POLY_XLU_DISP++, 0, 100, primColor->r, primColor->g, primColor->b, primColor->a); + gDPSetEnvColor(POLY_XLU_DISP++, envColor->r, envColor->g, envColor->b, 255); + break; + } } if (this->actionFunc == EnSlime_Damaged) { -- cgit v1.2.3