diff --git a/src/itdelatrisu/opsu/Utils.java b/src/itdelatrisu/opsu/Utils.java index 7ebc1117..507818df 100644 --- a/src/itdelatrisu/opsu/Utils.java +++ b/src/itdelatrisu/opsu/Utils.java @@ -189,6 +189,21 @@ public class Utils { return high; return val; } + /** + * Clamps a value between a lower and upper bound. + * @param val the value to clamp + * @param low the lower bound + * @param high the upper bound + * @return the clamped value + * @author fluddokt + */ + public static double clamp(double val, double low, double high) { + if (val < low) + return low; + if (val > high) + return high; + return val; + } /** * Returns the distance between two points. diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index fc885166..bd1eff14 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -209,9 +209,9 @@ public class Slider extends GameObject { final int fadeInTime = game.getFadeInTime(); float scale = timeDiff / (float) approachTime; float approachScale = 1 + scale * 3; - float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime; - float alpha = Utils.clamp(1 - fadeinScale, 0, 1); - float decorationsAlpha = Utils.clamp(-2.0f * fadeinScale, 0, 1); + double fadeinScale = (timeDiff - approachTime + fadeInTime) / (double) fadeInTime; + float alpha = Utils.clamp(1 - (float) fadeinScale, 0, 1); + float decorationsAlpha = Utils.clamp(-2.0f * (float) fadeinScale, 0, 1); boolean overlayAboveNumber = Options.getSkin().isHitCircleOverlayAboveNumber(); float oldAlpha = Colors.WHITE_FADE.a; Colors.WHITE_FADE.a = color.a = alpha; @@ -225,7 +225,7 @@ public class Slider extends GameObject { } curveColor.a = curveAlpha; - boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, alpha); + boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, Utils.clamp(1d - fadeinScale, 0d, 1d)); color.a = alpha; g.pushTransform(); @@ -401,40 +401,39 @@ public class Slider extends GameObject { } } - private boolean drawSliderTrack(int trackPosition, float snakingSliderProgress) { - float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; - float curveIntervalFrom = 0f; + private boolean drawSliderTrack(int trackPosition, double snakingSliderProgress) { + double curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1d; + double curveIntervalFrom = 0d; if (Options.isShrinkingSliders()) { - float sliderprogress = (trackPosition - getTime() - (sliderTime * (repeats - 1))) / sliderTime; + double sliderprogress = (trackPosition - getTime() - ((double) sliderTime * (repeats - 1))) / (double) sliderTime; if (sliderprogress > 0) { curveIntervalFrom = sliderprogress; } } + int curvelen = curve.getCurvePoints().length; if (Options.isMergingSliders()) { if (Options.isShrinkingSliders() && curveIntervalFrom > 0) { - int curvelen = curve.getCurvePoints().length; if (repeats % 2 == 0) { - game.spliceSliderCurve(baseSliderFrom + (int) ((1f - curveIntervalFrom) * curvelen), baseSliderFrom + curvelen); + game.spliceSliderCurve(baseSliderFrom + (int) ((1d - curveIntervalFrom) * curvelen), baseSliderFrom + curvelen + 1); } else { - game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curvelen) + 1); + game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curvelen)); } } game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); } else { if (Options.isFallbackSliders() && curveIntervalFrom > 0 && repeats % 2 == 0) { - curve.draw(curveColor, 1f - curveIntervalTo, 1f - curveIntervalFrom); + curve.draw(curveColor, (int) (curveIntervalFrom * curvelen), (int) (curveIntervalTo * curvelen)); } else { if (Options.isShrinkingSliders() && curveIntervalFrom > 0 && !Options.isFallbackSliders()) { - int curvelen = curve.getCurvePoints().length; if (repeats % 2 == 0) { - curve.splice((int) ((1f - curveIntervalFrom) * curvelen), curvelen); - curveIntervalFrom = 0f; + curve.splice((int) ((1d - curveIntervalFrom) * curvelen), curvelen); + curveIntervalFrom = 0d; } } - curve.draw(curveColor, curveIntervalFrom, curveIntervalTo); + curve.draw(curveColor, (int) (curveIntervalFrom * curvelen), (int) (curveIntervalTo * curvelen)); } } - return curveIntervalTo == 1f; + return curveIntervalTo == 1d; } /** diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 8e75e701..94b6c91e 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -121,32 +121,27 @@ public abstract class Curve { * Draws the full curve to the graphics context. * @param color the color filter */ - public void draw(Color color) { draw(color, 0f, 1f); } + public void draw(Color color) { draw(color, 0, curve.length); } /** * Draws the curve in the range [0, t] (where the full range is [0, 1]) to the graphics context. * @param color the color filter - * @param t1 interval to draw from - * @param t2 interval to draw to + * @param from index to draw from + * @param to index to draw to (exclusive) */ - public void draw(Color color, float t1, float t2) { + public void draw(Color color, int from, int to) { if (curve == null) return; - t1 = Utils.clamp(t1, 0f, 1f); - t2 = Utils.clamp(t2, 0f, 1f); - // peppysliders if (Options.isFallbackSliders() || Options.getSkin().getSliderStyle() == Skin.STYLE_PEPPYSLIDER || !mmsliderSupported) { - int drawFrom = (int) (curve.length * t1); - int drawUpTo = (int) (curve.length * t2); Image hitCircle = GameImage.HITCIRCLE.getImage(); Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage(); - for (int i = drawFrom; i < drawUpTo; i++) + for (int i = from; i < to; i++) hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Colors.WHITE_FADE); float a = fallbackSliderColor.a; fallbackSliderColor.a = color.a; - for (int i = drawFrom; i < drawUpTo; i++) + for (int i = from; i < to; i++) hitCircle.drawCentered(curve[i].x, curve[i].y, fallbackSliderColor); fallbackSliderColor.a = a; } @@ -155,7 +150,7 @@ public abstract class Curve { else { if (renderState == null) renderState = new CurveRenderState(hitObject, curve); - renderState.draw(color, borderColor, t1, t2); + renderState.draw(color, borderColor, from, to); } } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 65deeeab..03f8cbad 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -89,7 +89,7 @@ public class CurveRenderState { /** * Undo the static state. Static state setup caused by calls to - * {@link #draw(org.newdawn.slick.Color, org.newdawn.slick.Color, float, float)} + * {@link #draw(org.newdawn.slick.Color, org.newdawn.slick.Color, int, int)} * are undone. */ public static void shutdown() { @@ -129,17 +129,13 @@ public class CurveRenderState { * runs it just draws the cached copy to the screen. * @param color tint of the curve * @param borderColor the curve border color - * @param t2 the point up to which the curve should be drawn (in the interval [0, 1]) + * @param from index to draw from + * @param to index to draw to (exclusive) */ - public void draw(Color color, Color borderColor, float t1, float t2) { - t1 = Utils.clamp(t1, 0.0f, 1.0f); - t2 = Utils.clamp(t2, 0.0f, 1.0f); + public void draw(Color color, Color borderColor, int from, int to) { float alpha = color.a; - int drawFrom = (int) (t1 * curve.length); - int drawUpTo = (int) (t2 * curve.length); - - if (lastPointDrawn != drawUpTo || firstPointDrawn != drawFrom) { + if (lastPointDrawn != to || firstPointDrawn != from) { int oldFb = GL11.glGetInteger(EXTFramebufferObject.GL_FRAMEBUFFER_BINDING_EXT); int oldTex = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); //glGetInteger requires a buffer of size 16, even though just 4 @@ -148,20 +144,20 @@ public class CurveRenderState { GL11.glGetInteger(GL11.GL_VIEWPORT, oldViewport); EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo.getID()); GL11.glViewport(0, 0, fbo.width, fbo.height); - if (lastPointDrawn <= 0 || lastPointDrawn > drawUpTo) { + if (lastPointDrawn <= 0 || lastPointDrawn > to) { lastPointDrawn = 0; GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } - if (firstPointDrawn != drawFrom) { + if (firstPointDrawn != from) { GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); - firstPointDrawn = drawFrom; - this.renderCurve(color, borderColor, drawFrom, drawUpTo, true); + this.renderCurve(color, borderColor, from, to, true); } else { - this.renderCurve(color, borderColor, lastPointDrawn, drawUpTo, false); + this.renderCurve(color, borderColor, lastPointDrawn, to, false); } - lastPointDrawn = drawUpTo; + lastPointDrawn = to; + firstPointDrawn = from; color.a = 1f; GL11.glBindTexture(GL11.GL_TEXTURE_2D, oldTex); diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 10c75d10..b77e5480 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -329,7 +329,7 @@ public class Game extends BasicGameState { int obj = objectIndex; while (obj < gameObjects.length) { if (gameObjects[obj] instanceof Slider) { - slidercurveFrom = slidercurveTo = (float) ((Slider) gameObjects[obj]).baseSliderFrom / knorkesliders.getCurvePoints().length; + slidercurveFrom = slidercurveTo = ((Slider) gameObjects[obj]).baseSliderFrom; break; } obj++; @@ -1582,17 +1582,15 @@ public class Game extends BasicGameState { GameMod.loadModState(previousMods); } - private float slidercurveFrom; - private float slidercurveTo; + private int slidercurveFrom; + private int slidercurveTo; public void setSlidercurveFrom(int slidercurveFrom) { - float pos = (float) slidercurveFrom / knorkesliders.getCurvePoints().length; - this.slidercurveFrom = Math.max(pos, this.slidercurveFrom); + this.slidercurveFrom = Math.max(slidercurveFrom, this.slidercurveFrom); } public void setSlidercurveTo(int slidercurveTo) { - float pos = (float) slidercurveTo / knorkesliders.getCurvePoints().length; - this.slidercurveTo = Math.max(pos, this.slidercurveTo); + this.slidercurveTo = Math.max(slidercurveTo, this.slidercurveTo); } public void spliceSliderCurve(int from, int to) {