Skip to content

Commit

Permalink
Added interpolation settings
Browse files Browse the repository at this point in the history
  • Loading branch information
dima-dencep committed Jan 1, 2025
1 parent 6cb94f6 commit ec17dee
Show file tree
Hide file tree
Showing 7 changed files with 328 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.redlance.dima_dencep.mods.rrls.config.DoubleLoad;
import org.redlance.dima_dencep.mods.rrls.config.HideType;
import org.redlance.dima_dencep.mods.rrls.config.Type;
import org.redlance.dima_dencep.mods.rrls.utils.Ease;

public class RrlsConfig {
public static final Pair<RrlsConfig, ModConfigSpec> CONFIG_SPEC_PAIR = new ModConfigSpec.Builder()
Expand All @@ -32,6 +33,11 @@ public class RrlsConfig {
public final ModConfigSpec.ConfigValue<String> reloadText;
public final ModConfigSpec.ConfigValue<Double> animationSpeed;

// Interpolation
public final ModConfigSpec.BooleanValue interpolateProgress;
public final ModConfigSpec.EnumValue<Ease> ease;
public final ModConfigSpec.ConfigValue<Double> easingArg;

// Other
public final ModConfigSpec.BooleanValue resetResources;
public final ModConfigSpec.BooleanValue reInitScreen;
Expand All @@ -56,6 +62,12 @@ protected RrlsConfig(ModConfigSpec.Builder builder) {
this.animationSpeed = builder.define("animationSpeed", 1000.0);
builder.pop();

builder.push("interpolation");
this.interpolateProgress = builder.define("interpolateProgress", false);
this.ease = builder.defineEnum("ease", Ease.OUTCIRC);
this.easingArg = builder.define("easingArg", Double.NaN, RrlsConfig::isFloatLike);
builder.pop();

builder.push("other");
this.resetResources = builder.define("resetResources", true);
this.reInitScreen = builder.define("reInitScreen", true);
Expand Down Expand Up @@ -96,6 +108,23 @@ public static String reloadText() {
return CONFIG_SPEC_PAIR.getKey().reloadText.get();
}

public static boolean interpolateProgress() {
return CONFIG_SPEC_PAIR.getKey().interpolateProgress.get();
}

public static Ease easing() {
return CONFIG_SPEC_PAIR.getKey().ease.get();
}

public static Float easingArg() {
float easingArg = CONFIG_SPEC_PAIR.getKey().easingArg.get().floatValue();
if (Float.isNaN(easingArg)) {
return null;
}

return easingArg;
}

public static float animationSpeed() {
return CONFIG_SPEC_PAIR.getKey().animationSpeed.get()
.floatValue();
Expand All @@ -120,4 +149,24 @@ public static DoubleLoad doubleLoad() {
public static boolean skipForgeOverlay() {
return CONFIG_SPEC_PAIR.getKey().skipForgeOverlay.get();
}

private static boolean isFloatLike(Object obj) {
if (obj == null) {
return false;
}

return switch (obj) {
case Float ignored -> true;
case Double ignored -> true;
case String str -> {
try {
Float.valueOf(str);
yield true;
} catch (Throwable th) {
yield false;
}
}
default -> false;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
package org.redlance.dima_dencep.mods.rrls.mixins;

import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.Util;
import net.minecraft.client.gui.components.FocusableTextWidget;
import net.minecraft.network.chat.Component;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import org.redlance.dima_dencep.mods.rrls.RrlsConfig;
import org.redlance.dima_dencep.mods.rrls.config.Type;
Expand Down Expand Up @@ -49,19 +51,13 @@ public abstract class LoadingOverlayMixin extends Overlay {
@Shadow
public float currentProgress;
@Shadow
private static int replaceAlpha(int color, int alpha) {
return 0;
}

private long fadeOutStart;
@Shadow
private long fadeInStart;
@Shadow
public abstract void drawProgressBar(GuiGraphics guiGraphics, int minX, int minY, int maxX, int maxY, float partialTick);
@Unique
private FocusableTextWidget rrls$textWidget;
@Unique
private float rrls$fadeOutTime;

@Inject(
method = "<init>",
Expand All @@ -81,31 +77,44 @@ private static int replaceAlpha(int color, int alpha) {
int i = graphics.guiWidth();
int j = graphics.guiHeight();

float ease = 1.0F;
if (RrlsConfig.interpolateProgress()) {
ease -= RrlsConfig.easing().invoke(this.currentProgress, RrlsConfig.easingArg());

} else if (this.fadeOutStart > -1L) {
float f = (float)(Util.getMillis() - this.fadeOutStart) / RrlsConfig.animationSpeed();
ease -= RrlsConfig.easing().invoke(Mth.clamp(f, 0.0F, 1.0F), RrlsConfig.easingArg());
}

int easeAlpha = Math.max(Math.round(ease * 255.0F), 4); // Fuck Font#adjustColor
int easeColor = ARGB.color(easeAlpha, 255, 255, 255);

switch (RrlsConfig.type()) {
case Type.PROGRESS -> {
int s = (int) ((double) j * 0.8325);
int r = (int) (Math.min(i * 0.75, j) * 0.5);

this.drawProgressBar(graphics, i / 2 - r, s - 5, i / 2 + r, s + 5, this.rrls$fadeOutTime);
this.drawProgressBar(graphics, i / 2 - r, s - 5, i / 2 + r, s + 5, ease);
}

case Type.TEXT -> graphics.drawCenteredString(
minecraft.font, RrlsConfig.reloadText(), i / 2, 70,
RrlsConfig.rgbProgress() ? RainbowUtils.rainbowColor() : -1
RrlsConfig.rgbProgress() ? RainbowUtils.rainbowColor(easeAlpha) : easeColor
);

case Type.TEXT_WITH_BACKGROUND -> {
if (rrls$textWidget != null) {
rrls$textWidget.setMaxWidth(i);
rrls$textWidget.setX(i / 2 - rrls$textWidget.getWidth() / 2);
rrls$textWidget.setY(j - j / 3);
rrls$textWidget.setColor(easeColor);

if (RrlsConfig.rgbProgress())
rrls$textWidget.setColor(RainbowUtils.rainbowColor());
rrls$textWidget.setColor(RainbowUtils.rainbowColor(easeAlpha));

// This will make sure the widget is rendered above other widgets in Pause screen
graphics.pose().pushPose();
graphics.pose().translate(0, 0,255);
graphics.pose().translate(0, 0, 255);

rrls$textWidget.render(graphics, 0, 0, partialTick);

Expand Down Expand Up @@ -134,18 +143,6 @@ private static int replaceAlpha(int color, int alpha) {
rrls$setState(OverlayHelper.lookupState(minecraft.screen, rrls$getState() != OverlayHelper.State.WAIT));
}

@Inject(
method = "render",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/gui/screens/LoadingOverlay;fadeInStart:J",
ordinal = 2
)
)
public void rrls$hookPartialTick(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci, @Local(ordinal = 1) float f) {
this.rrls$fadeOutTime = 1.0F - Mth.clamp(f, 0.0F, 1.0F);
}

@WrapWithCondition(
method = "render",
at = @At(
Expand Down Expand Up @@ -198,16 +195,31 @@ private static int replaceAlpha(int color, int alpha) {
original.call(red, green, blue, alpha);
}

@WrapOperation(
method = "drawProgressBar",
at = @At(
value = "INVOKE",
target = "Ljava/lang/Math;round(F)I"
)
)
public int rrls$lerp(float i, Operation<Integer> original, @Local(argsOnly = true) float partialTick) {
if (RrlsConfig.interpolateProgress()) {
return Mth.ceil(Mth.lerp(partialTick, 0.0F, 255.0F));
}

return original.call(i);
}

@WrapOperation(
method = "drawProgressBar",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/ARGB;color(IIII)I"
)
)
public int rrls$rainbowProgress(int alpha, int red, int green, int blue, Operation<Integer> original) {
public int rrls$rainbowProgress(int alpha, int red, int green, int blue, Operation<Integer> original, @Local(argsOnly = true) float partialTick) {
if (RrlsConfig.rgbProgress() && rrls$getState() != OverlayHelper.State.DEFAULT) {
return replaceAlpha(RainbowUtils.rainbowColor(), alpha);
return RainbowUtils.rainbowColor(partialTick);
}

return original.call(alpha, red, green, blue);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright 2023 - 2024 dima_dencep.
*
* Licensed under the Open Software License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* https://spdx.org/licenses/OSL-3.0.txt
*/

package org.redlance.dima_dencep.mods.rrls.utils;

import java.util.function.Function;

/**
* Easings form <a href="https://easings.net/">easings.net</a><br>
* + constant + linear
*/
public enum Ease {
LINEAR(0, arg -> easeIn(f -> f)),
CONSTANT(1, arg -> easeIn(f -> 0f)),

// Sine
INSINE(6, arg -> easeIn(Easing::sine)),
OUTSINE(7, arg -> easeOut(Easing::sine)),
INOUTSINE(8, arg -> easeInOut(Easing::sine)),

// Cubic
INCUBIC(9, arg -> easeIn(Easing::cubic)),
OUTCUBIC(10, arg -> easeOut(Easing::cubic)),
INOUTCUBIC(11, arg -> easeInOut(Easing::cubic)),

// Quadratic
INQUAD(12, arg -> easeIn(Easing::quadratic)),
OUTQUAD(13, arg -> easeOut(Easing::quadratic)),
INOUTQUAD(14, arg -> easeInOut(Easing::quadratic)),

// Quart
INQUART(15, arg -> easeIn(Easing.pow(4))),
OUTQUART(16, arg -> easeOut(Easing.pow(4))),
INOUTQUART(17, arg -> easeInOut(Easing.pow(4))),

// Quint
INQUINT(18, arg -> easeIn(Easing.pow(5))),
OUTQUINT(19, arg -> easeOut(Easing.pow(5))),
INOUTQUINT(20, arg -> easeInOut(Easing.pow(5))),

// Expo
INEXPO(21, arg -> easeIn(Easing::exp)),
OUTEXPO(22, arg -> easeOut(Easing::exp)),
INOUTEXPO(23, arg -> easeInOut(Easing::exp)),

// Cricle
INCIRC(24, arg -> easeIn(Easing::circle)),
OUTCIRC(25, arg -> easeOut(Easing::circle)),
INOUTCIRC(26, arg -> easeInOut(Easing::circle)),

// Back
INBACK(27, arg -> easeIn(Easing.back(arg))),
OUTBACK(28, arg -> easeOut(Easing.back(arg))),
INOUTBACK(29, arg -> easeInOut(Easing.back(arg))),

// Elastic
INELASTIC(30, arg -> easeIn(Easing.elastic(arg))),
OUTELASTIC(31, arg -> easeOut(Easing.elastic(arg))),
INOUTELASTIC(32, arg -> easeInOut(Easing.elastic(arg))),

// Bounce
INBOUNCE(33, arg -> easeIn(Easing.bounce(arg))),
OUTBOUNCE(34, arg -> easeOut(Easing.bounce(arg))),
INOUTBOUNCE(35, arg -> easeInOut(Easing.bounce(arg))),

CATMULLROM(36, arg -> easeInOut(Easing::catmullRom)),
STEP(37, arg -> easeIn(Easing.step(arg)));

final byte id;
private final Function<Float, Function<Float, Float>> impl;

/**
* @param id id
* @param impl implementation
*/
Ease(byte id, Function<Float, Function<Float, Float>> impl) {
this.id = id;
this.impl = impl;
}

/**
* @param id id
* @param impl implementation
*/
Ease(int id, Function<Float, Function<Float, Float>> impl) {
this((byte) id, impl);
}

/**
* Run the easing
* @param t float between 0 and 1
* @param n float easing argument
* @return ease(t, n)
*/
public float invoke(float t, Float n) {
return this.impl.apply(n).apply(t);
}

public static Function<Float, Float> easeIn(Function<Float, Float> function) {
return function;
}

public static Function<Float, Float> easeOut(Function<Float, Float> function) {
return time -> 1 - function.apply(1 - time);
}

public static Function<Float, Float> easeInOut(Function<Float, Float> function) {
return time -> {
if (time < 0.5F) {
return function.apply(time * 2F) / 2F;
}

return 1 - function.apply((1 - time) * 2F) / 2F;
};
}
}
Loading

0 comments on commit ec17dee

Please sign in to comment.