summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2026-02-22 07:12:58 -0600
committerGitHub <noreply@github.com>2026-02-22 07:12:58 -0600
commitd6492412db91e34b498cd8609dee1ea4f253e02c (patch)
tree53c134d20ada302af1d9315cd240bd6dd5bc7a85
parentf8bf9bb3b66f467a8a433f8b204a1c575880c6d7 (diff)
Simplify hearts & magic cosmetics and expand where they are shown (#1562)
-rw-r--r--mm/2s2h/BenGui/CosmeticEditor.cpp392
-rw-r--r--mm/2s2h/BenGui/CosmeticEditor.h24
-rw-r--r--mm/2s2h/BenGui/HudEditor.cpp4
-rw-r--r--mm/src/code/z_lifemeter.c50
-rw-r--r--mm/src/code/z_parameter.c44
-rw-r--r--mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c21
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<uint8_t>(changedColor.g);
returnedColor.b = static_cast<uint8_t>(changedColor.b);
returnedColor.a = static_cast<uint8_t>(255);
+
+ switch (mode) {
+ case COSMETIC_COLOR_MODE_DEFAULT:
+ break;
+ case COSMETIC_COLOR_MODE_MULTIPLY:
+ returnedColor.r = MAX(MIN(static_cast<uint8_t>(returnedColor.r * modifier), 255), 0);
+ returnedColor.g = MAX(MIN(static_cast<uint8_t>(returnedColor.g * modifier), 255), 0);
+ returnedColor.b = MAX(MIN(static_cast<uint8_t>(returnedColor.b * modifier), 255), 0);
+ break;
+ case COSMETIC_COLOR_MODE_DIVIDE:
+ if (modifier != 0) {
+ returnedColor.r = MAX(MIN(static_cast<uint8_t>(returnedColor.r / modifier), 255), 0);
+ returnedColor.g = MAX(MIN(static_cast<uint8_t>(returnedColor.g / modifier), 255), 0);
+ returnedColor.b = MAX(MIN(static_cast<uint8_t>(returnedColor.b / modifier), 255), 0);
+ }
+ break;
+ case COSMETIC_COLOR_MODE_ADD:
+ returnedColor.r = MAX(MIN(static_cast<uint8_t>(returnedColor.r + modifier), 255), 0);
+ returnedColor.g = MAX(MIN(static_cast<uint8_t>(returnedColor.g + modifier), 255), 0);
+ returnedColor.b = MAX(MIN(static_cast<uint8_t>(returnedColor.b + modifier), 255), 0);
+ break;
+ case COSMETIC_COLOR_MODE_SUBTRACT:
+ returnedColor.r = MAX(MIN(static_cast<uint8_t>(returnedColor.r - modifier), 255), 0);
+ returnedColor.g = MAX(MIN(static_cast<uint8_t>(returnedColor.g - modifier), 255), 0);
+ returnedColor.b = MAX(MIN(static_cast<uint8_t>(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<uint8_t>((r1 + m) * 255.0f);
+ returnedColor.g = static_cast<uint8_t>((g1 + m) * 255.0f);
+ returnedColor.b = static_cast<uint8_t>((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) {