From 08834471fc1c8395235a6e929035011cad2b5da3 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 3 Dec 2016 18:18:18 +0100 Subject: [PATCH 01/11] first attemt at shrinking sliders --- src/itdelatrisu/opsu/objects/Slider.java | 2 +- .../opsu/objects/curves/Curve.java | 16 ++++++---- .../opsu/render/CurveRenderState.java | 32 +++++++++++-------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 7a2c95b0..2b0b46d2 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -220,7 +220,7 @@ public class Slider extends GameObject { curveColor.a = curveAlpha; float curveInterval = Options.isSliderSnaking() ? alpha : 1f; - curve.draw(curveColor, curveInterval); + curve.draw(curveColor, Math.max(0, (trackPosition - getTime()) / sliderTimeTotal), curveInterval); color.a = alpha; g.pushTransform(); diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 2a881b3a..6b5dd293 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -60,7 +60,7 @@ public abstract class Curve { private CurveRenderState renderState; /** Points along the curve (set by inherited classes). */ - protected Vec2f[] curve; + public Vec2f[] curve; private Color fallbackSliderColor = new Color(20, 20, 20); @@ -117,25 +117,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, 1f); } + public void draw(Color color) { draw(color, 0f, 1f); } /** * 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 t set the curve interval to [0, t] */ - public void draw(Color color, float t) { + public void draw(Color color, float t1, float t2) { if (curve == null) return; - t = Utils.clamp(t, 0f, 1f); + t1 = Utils.clamp(t1, 0f, 1f); + t2 = Utils.clamp(t2, 0f, 1f); // peppysliders if (Options.isFallbackSliders() || Options.getSkin().getSliderStyle() == Skin.STYLE_PEPPYSLIDER || !mmsliderSupported) { - int drawUpTo = (int) (curve.length * t); + 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 = 0; i < drawUpTo; i++) + for (int i = drawFrom; i < drawUpTo; i++) hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Colors.WHITE_FADE); float a = fallbackSliderColor.a; fallbackSliderColor.a = color.a; @@ -148,7 +150,7 @@ public abstract class Curve { else { if (renderState == null) renderState = new CurveRenderState(hitObject, curve); - renderState.draw(color, borderColor, t); + renderState.draw(color, borderColor, t1, t2); } } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 34080c0c..64ff3cfd 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -64,6 +64,7 @@ public class CurveRenderState { /** The point to which the curve has last been rendered into the texture (as an index into {@code curve}). */ private int lastPointDrawn; + private int firstPointDrawn; /** * Set the width and height of the container that Curves get drawn into. @@ -85,7 +86,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)} + * {@link #draw(org.newdawn.slick.Color, org.newdawn.slick.Color, float, float)} * are undone. */ public static void shutdown() { @@ -110,10 +111,11 @@ 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 t the point up to which the curve should be drawn (in the interval [0, 1]) + * @param t2 the point up to which the curve should be drawn (in the interval [0, 1]) */ - public void draw(Color color, Color borderColor, float t) { - t = Utils.clamp(t, 0.0f, 1.0f); + 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); float alpha = color.a; // if this curve hasn't been drawn, draw it and cache the result @@ -127,13 +129,11 @@ public class CurveRenderState { //write impossible value to make sure the fbo is cleared lastPointDrawn = -1; } - - int drawUpTo = (int) (t * curve.length); - - if (lastPointDrawn != drawUpTo) { - if (drawUpTo == lastPointDrawn) - return; + int drawFrom = (int) (t1 * curve.length); + int drawUpTo = (int) (t2 * curve.length); + + if (lastPointDrawn != drawUpTo || firstPointDrawn != drawFrom) { 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 @@ -147,8 +147,11 @@ public class CurveRenderState { GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } - - this.renderCurve(color, borderColor, lastPointDrawn, drawUpTo); + if (firstPointDrawn != drawFrom) { + this.renderCurve(color, borderColor, drawFrom, drawUpTo, true); + } else { + this.renderCurve(color, borderColor, lastPointDrawn, drawUpTo, false); + } lastPointDrawn = drawUpTo; color.a = 1f; @@ -295,7 +298,7 @@ public class CurveRenderState { * @param color the color of the curve * @param borderColor the curve border color */ - private void renderCurve(Color color, Color borderColor, int from, int to) { + private void renderCurve(Color color, Color borderColor, int from, int to, boolean clearFirst) { staticState.initGradient(); RenderState state = saveRenderState(); staticState.initShaderProgram(); @@ -310,6 +313,9 @@ public class CurveRenderState { //2*4 is for skipping the first 2 floats (u,v) GL20.glVertexAttribPointer(staticState.attribLoc, 4, GL11.GL_FLOAT, false, 6 * 4, 2 * 4); GL20.glVertexAttribPointer(staticState.texCoordLoc, 2, GL11.GL_FLOAT, false, 6 * 4, 0); + if (clearFirst) { + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); + } for (int i = from * 2; i < to * 2 - 1; ++i) GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2); GL11.glFlush(); From 89245d99761e5af8d3ad5884b4bed85544f179d1 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 3 Dec 2016 18:39:20 +0100 Subject: [PATCH 02/11] first attempt at merging sliders --- src/itdelatrisu/opsu/objects/Slider.java | 2 +- .../opsu/objects/curves/Curve.java | 4 ++ src/itdelatrisu/opsu/states/Game.java | 32 +++++++++++-- .../objects/curves/FakeCombinedCurve.java | 46 +++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/yugecin/opsudance/objects/curves/FakeCombinedCurve.java diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 7a2c95b0..cabd0ca4 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -220,7 +220,7 @@ public class Slider extends GameObject { curveColor.a = curveAlpha; float curveInterval = Options.isSliderSnaking() ? alpha : 1f; - curve.draw(curveColor, curveInterval); + //curve.draw(curveColor, curveInterval); color.a = alpha; g.pushTransform(); diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 2a881b3a..703747b2 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -62,6 +62,10 @@ public abstract class Curve { /** Points along the curve (set by inherited classes). */ protected Vec2f[] curve; + public Vec2f[] getCurvePoints() { + return curve; + } + private Color fallbackSliderColor = new Color(20, 20, 20); /** diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index d47ba2ec..96fe6d47 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -44,7 +44,9 @@ import itdelatrisu.opsu.objects.Slider; import itdelatrisu.opsu.objects.Spinner; import itdelatrisu.opsu.objects.curves.Curve; import itdelatrisu.opsu.objects.curves.Vec2f; +import itdelatrisu.opsu.render.CurveRenderState; import itdelatrisu.opsu.render.FrameBufferCache; +import itdelatrisu.opsu.render.KnorkeCurveRenderStuff; import itdelatrisu.opsu.replay.PlaybackSpeed; import itdelatrisu.opsu.replay.Replay; import itdelatrisu.opsu.replay.ReplayFrame; @@ -52,9 +54,7 @@ import itdelatrisu.opsu.ui.*; import itdelatrisu.opsu.ui.animations.AnimationEquation; import java.io.File; -import java.util.IdentityHashMap; -import java.util.LinkedList; -import java.util.Stack; +import java.util.*; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.Display; @@ -72,6 +72,7 @@ import org.newdawn.slick.state.transition.EasedFadeOutTransition; import org.newdawn.slick.state.transition.EmptyTransition; import org.newdawn.slick.state.transition.FadeInTransition; import yugecin.opsudance.*; +import yugecin.opsudance.objects.curves.FakeCombinedCurve; import yugecin.opsudance.ui.SBOverlay; /** @@ -281,6 +282,8 @@ public class Game extends BasicGameState { private final Cursor mirrorCursor; private final SBOverlay sbOverlay; + private FakeCombinedCurve knorkesliders; + public Game(int state) { this.state = state; mirrorCursor = new Cursor(true); @@ -1453,6 +1456,15 @@ public class Game extends BasicGameState { } this.leadInTime += epiImgTime; SoundController.mute(false); + + // let's create knorkesliders + List curvepoints = new ArrayList<>(); + for (GameObject gameObject : gameObjects) { + if (gameObject.isSlider()) { + curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); + } + } + knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } @@ -1495,12 +1507,26 @@ public class Game extends BasicGameState { GameMod.loadModState(previousMods); } + private float slidercurveFrom; + private float slidercurveTo; + + public void setSlidercurveFrom(int slidercurveFrom) { + float pos = slidercurveFrom / knorkesliders.getCurvePoints().length; + this.slidercurveFrom = Math.min(pos, this.slidercurveFrom); + } + + public void setSlidercurveTo(int slidercurveTo) { + float pos = slidercurveTo / knorkesliders.getCurvePoints().length; + this.slidercurveTo = Math.max(pos, this.slidercurveTo); + } + /** * Draws hit objects, hit results, and follow points. * @param g the graphics context * @param trackPosition the track position */ private void drawHitObjects(Graphics g, int trackPosition) { + knorkesliders.draw(Color.white, this.slidercurveFrom, this.slidercurveTo); // include previous object in follow points int lastObjectIndex = -1; if (objectIndex > 0 && objectIndex < beatmap.objects.length && diff --git a/src/yugecin/opsudance/objects/curves/FakeCombinedCurve.java b/src/yugecin/opsudance/objects/curves/FakeCombinedCurve.java new file mode 100644 index 00000000..788c3886 --- /dev/null +++ b/src/yugecin/opsudance/objects/curves/FakeCombinedCurve.java @@ -0,0 +1,46 @@ +/* + * opsu!dance - fork of opsu! with cursordance auto + * Copyright (C) 2016 yugecin + * + * opsu!dance is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu!dance is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!dance. If not, see . + */ +package yugecin.opsudance.objects.curves; + +import itdelatrisu.opsu.beatmap.HitObject; +import itdelatrisu.opsu.objects.curves.Curve; +import itdelatrisu.opsu.objects.curves.Vec2f; + +public class FakeCombinedCurve extends Curve { + + public FakeCombinedCurve(Vec2f[] points) { + super(new HitObject(0, 0, 0), false); + this.curve = points; + } + + @Override + public Vec2f pointAt(float t) { + return null; + } + + @Override + public float getEndAngle() { + return 0; + } + + @Override + public float getStartAngle() { + return 0; + } + +} From 580f11a3d3c8ed1f5b8a092f5cb861bfe1655ac4 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 3 Dec 2016 19:11:36 +0100 Subject: [PATCH 03/11] draw sliders on correct times --- src/itdelatrisu/opsu/objects/Slider.java | 7 +++++++ src/itdelatrisu/opsu/states/Game.java | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index cabd0ca4..858e4767 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -122,6 +122,8 @@ public class Slider extends GameObject { private int tickExpand = 0; private final int TICKEXPAND = 200; + public int baseSliderFrom; + /** * Initializes the Slider data type with images and dimensions. * @param container the game container @@ -221,6 +223,11 @@ public class Slider extends GameObject { float curveInterval = Options.isSliderSnaking() ? alpha : 1f; //curve.draw(curveColor, curveInterval); + float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; + if (sliderprogress > 0) { + game.setSlidercurveFrom(baseSliderFrom + (int) (sliderprogress * curve.getCurvePoints().length)); + } + game.setSlidercurveTo(baseSliderFrom + (int) (curveInterval * curve.getCurvePoints().length)); color.a = alpha; g.pushTransform(); diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 96fe6d47..d18ca304 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -44,9 +44,7 @@ import itdelatrisu.opsu.objects.Slider; import itdelatrisu.opsu.objects.Spinner; import itdelatrisu.opsu.objects.curves.Curve; import itdelatrisu.opsu.objects.curves.Vec2f; -import itdelatrisu.opsu.render.CurveRenderState; import itdelatrisu.opsu.render.FrameBufferCache; -import itdelatrisu.opsu.render.KnorkeCurveRenderStuff; import itdelatrisu.opsu.replay.PlaybackSpeed; import itdelatrisu.opsu.replay.Replay; import itdelatrisu.opsu.replay.ReplayFrame; @@ -1461,12 +1459,15 @@ public class Game extends BasicGameState { List curvepoints = new ArrayList<>(); for (GameObject gameObject : gameObjects) { if (gameObject.isSlider()) { + ((Slider) gameObject).baseSliderFrom = curvepoints.size(); curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); } } knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } + slidercurveFrom = 0; + slidercurveTo = 0; Dancer.instance.setGameObjects(gameObjects); sbOverlay.setGameObjects(gameObjects); @@ -1511,12 +1512,12 @@ public class Game extends BasicGameState { private float slidercurveTo; public void setSlidercurveFrom(int slidercurveFrom) { - float pos = slidercurveFrom / knorkesliders.getCurvePoints().length; - this.slidercurveFrom = Math.min(pos, this.slidercurveFrom); + float pos = (float) slidercurveFrom / knorkesliders.getCurvePoints().length; + this.slidercurveFrom = Math.max(pos, this.slidercurveFrom); } public void setSlidercurveTo(int slidercurveTo) { - float pos = slidercurveTo / knorkesliders.getCurvePoints().length; + float pos = (float) slidercurveTo / knorkesliders.getCurvePoints().length; this.slidercurveTo = Math.max(pos, this.slidercurveTo); } From 8f9f16de98c4f9b9ad42133de768d6d5c6953fb0 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 3 Dec 2016 19:25:22 +0100 Subject: [PATCH 04/11] try fix the slidercones inbetween --- .../opsu/render/CurveRenderState.java | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 64ff3cfd..f136bbcb 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -20,6 +20,7 @@ package itdelatrisu.opsu.render; import itdelatrisu.opsu.GameImage; import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.beatmap.HitObject; +import itdelatrisu.opsu.objects.Circle; import itdelatrisu.opsu.objects.curves.Vec2f; import java.nio.ByteBuffer; @@ -59,9 +60,8 @@ public class CurveRenderState { /** The HitObject associated with the curve to be drawn. */ protected HitObject hitObject; - /** The points along the curve to be drawn. */ protected Vec2f[] curve; - + /** The point to which the curve has last been rendered into the texture (as an index into {@code curve}). */ private int lastPointDrawn; private int firstPointDrawn; @@ -100,9 +100,16 @@ public class CurveRenderState { * @param curve the points along the curve to be drawn */ public CurveRenderState(HitObject hitObject, Vec2f[] curve) { - fbo = null; this.hitObject = hitObject; this.curve = curve; + FrameBufferCache cache = FrameBufferCache.getInstance(); + Rendertarget mapping = cache.get(hitObject); + if (mapping == null) + mapping = cache.insert(hitObject); + fbo = mapping; + createVertexBuffer(fbo.getVbo()); + //write impossible value to make sure the fbo is cleared + lastPointDrawn = -1; } /** @@ -118,18 +125,6 @@ public class CurveRenderState { t2 = Utils.clamp(t2, 0.0f, 1.0f); float alpha = color.a; - // if this curve hasn't been drawn, draw it and cache the result - if (fbo == null) { - FrameBufferCache cache = FrameBufferCache.getInstance(); - Rendertarget mapping = cache.get(hitObject); - if (mapping == null) - mapping = cache.insert(hitObject); - fbo = mapping; - createVertexBuffer(fbo.getVbo()); - //write impossible value to make sure the fbo is cleared - lastPointDrawn = -1; - } - int drawFrom = (int) (t1 * curve.length); int drawUpTo = (int) (t2 * curve.length); @@ -148,6 +143,7 @@ public class CurveRenderState { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } if (firstPointDrawn != drawFrom) { + firstPointDrawn = drawFrom; this.renderCurve(color, borderColor, drawFrom, drawUpTo, true); } else { this.renderCurve(color, borderColor, lastPointDrawn, drawUpTo, false); @@ -273,19 +269,26 @@ public class CurveRenderState { private void createVertexBuffer(int bufferID) { int arrayBufferBinding = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (2 * curve.length - 1) * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer(); - for (int i = 0; i < curve.length; ++i) { + if (curve.length > 0) { + fillCone(buff, curve[0].x, curve[0].y); + } + for (int i = 1; i < curve.length; ++i) { float x = curve[i].x; float y = curve[i].y; fillCone(buff, x, y); - if (i != 0) { - float last_x = curve[i - 1].x; - float last_y = curve[i - 1].y; - double diff_x = x - last_x; - double diff_y = y - last_y; + float last_x = curve[i - 1].x; + float last_y = curve[i - 1].y; + double diff_x = x - last_x; + double diff_y = y - last_y; + if (diff_x < Circle.diameter / 8 && diff_y < Circle.diameter / 8) { x = (float) (x - diff_x / 2); y = (float) (y - diff_y / 2); - fillCone(buff, x, y); + } else { + x = curve[i+1].x; + y = curve[i+1].y; + System.out.println("next"); } + fillCone(buff, x, y); } buff.flip(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferID); From 06445e59c4d077823ecc53241abb068680464741 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 3 Dec 2016 20:13:58 +0100 Subject: [PATCH 05/11] fix slider leftovers being drawn --- src/itdelatrisu/opsu/GameData.java | 2 +- src/itdelatrisu/opsu/objects/Slider.java | 1 + src/itdelatrisu/opsu/render/CurveRenderState.java | 9 +++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 7a051a53..3e735760 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -913,7 +913,7 @@ public class GameData { float oldColorAlpha = hitResult.color.a; Colors.WHITE_FADE.a = alpha; hitResult.color.a = alpha; - hitResult.curve.draw(hitResult.color); + //hitResult.curve.draw(hitResult.color); Colors.WHITE_FADE.a = oldWhiteAlpha; hitResult.color.a = oldColorAlpha; } diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 858e4767..0157b4dc 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -557,6 +557,7 @@ public class Slider extends GameObject { // calculate and send slider result hitResult(); + game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); return true; } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index f136bbcb..c4275a4a 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -280,13 +280,14 @@ public class CurveRenderState { float last_y = curve[i - 1].y; double diff_x = x - last_x; double diff_y = y - last_y; - if (diff_x < Circle.diameter / 8 && diff_y < Circle.diameter / 8) { + float dist = Utils.distance(x, y, last_x, last_y); + if (dist < Circle.diameter / 8) { x = (float) (x - diff_x / 2); y = (float) (y - diff_y / 2); } else { - x = curve[i+1].x; - y = curve[i+1].y; - System.out.println("next"); + // don't mind me + x = -100f; + y = -100f; } fillCone(buff, x, y); } From 00fcf0ebc190be89a9c16d5e0833bec8b5a4562b Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 17:35:55 +0100 Subject: [PATCH 06/11] add options for slider styles and make it all work --- src/itdelatrisu/opsu/GameData.java | 4 +- src/itdelatrisu/opsu/Options.java | 10 +++++ src/itdelatrisu/opsu/objects/Slider.java | 39 ++++++++++++++----- .../opsu/objects/curves/Curve.java | 7 ++-- .../opsu/render/CurveRenderState.java | 2 + src/itdelatrisu/opsu/states/Game.java | 20 ++++++---- src/itdelatrisu/opsu/states/OptionsMenu.java | 2 + 7 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 3e735760..11aac0a3 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -913,7 +913,9 @@ public class GameData { float oldColorAlpha = hitResult.color.a; Colors.WHITE_FADE.a = alpha; hitResult.color.a = alpha; - //hitResult.curve.draw(hitResult.color); + if (!Options.isShrinkingSliders()) { + hitResult.curve.draw(hitResult.color); + } Colors.WHITE_FADE.a = oldWhiteAlpha; hitResult.color.a = oldColorAlpha; } diff --git a/src/itdelatrisu/opsu/Options.java b/src/itdelatrisu/opsu/Options.java index 37f6efb9..cfc6a366 100644 --- a/src/itdelatrisu/opsu/Options.java +++ b/src/itdelatrisu/opsu/Options.java @@ -502,7 +502,14 @@ public class Options { FORCE_DEFAULT_PLAYFIELD ("Force Default Playfield", "ForceDefaultPlayfield", "Override the song background with the default playfield background.", false), IGNORE_BEATMAP_SKINS ("Ignore All Beatmap Skins", "IgnoreBeatmapSkins", "Never use skin element overrides provided by beatmaps.", false), SNAKING_SLIDERS ("Snaking sliders", "SnakingSliders", "Sliders gradually snake out from their starting point.", true), + SHRINKING_SLIDERS ("Shrinking sliders", "ShrinkingSliders", "Sliders shrinks when sliderball passes - unstable!", false), FALLBACK_SLIDERS ("Fallback sliders", "FallbackSliders", "Enable this if sliders won't render", false), + MERGING_SLIDERS ("Merging sliders", "MergingSliders", "Merge sliders (aka knorkesliders) - unstable!", false) { + @Override + public boolean showCondition() { + return !FALLBACK_SLIDERS.bool; + } + }, SHOW_HIT_LIGHTING ("Show Hit Lighting", "HitLighting", "Adds an effect behind hit explosions.", true), SHOW_COMBO_BURSTS ("Show Combo Bursts", "ComboBurst", "A character image is displayed at combo milestones.", true), SHOW_PERFECT_HIT ("Show Perfect Hits", "PerfectHit", "Whether to show perfect hit result bursts (300s, slider ticks).", true), @@ -1775,6 +1782,9 @@ public class Options { public static boolean isFallbackSliders() { return GameOption.FALLBACK_SLIDERS.getBooleanValue(); } + public static boolean isShrinkingSliders() { return GameOption.SHRINKING_SLIDERS.getBooleanValue(); } + public static boolean isMergingSliders() { return !isFallbackSliders() && GameOption.MERGING_SLIDERS.getBooleanValue(); } + /** * Returns the fixed circle size override, if any. * @return the CS value (0, 10], 0f if disabled diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 0157b4dc..c2064bbb 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -195,6 +195,9 @@ public class Slider extends GameObject { @Override public void draw(Graphics g, int trackPosition, boolean mirror) { + if (trackPosition > getEndTime()) { + return; + } Color orig = color; if (mirror) { color = mirrorColor; @@ -219,15 +222,9 @@ public class Slider extends GameObject { if (GameMod.HIDDEN.isActive() && trackPosition > getTime()) { curveAlpha = Math.max(0f, 1f - ((float) (trackPosition - getTime()) / (getEndTime() - getTime())) * 1.05f); } - curveColor.a = curveAlpha; - float curveInterval = Options.isSliderSnaking() ? alpha : 1f; - //curve.draw(curveColor, curveInterval); - float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; - if (sliderprogress > 0) { - game.setSlidercurveFrom(baseSliderFrom + (int) (sliderprogress * curve.getCurvePoints().length)); - } - game.setSlidercurveTo(baseSliderFrom + (int) (curveInterval * curve.getCurvePoints().length)); + curveColor.a = curveAlpha; + boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, alpha); color.a = alpha; g.pushTransform(); @@ -292,7 +289,7 @@ public class Slider extends GameObject { g.popTransform(); // repeats - if (curveInterval == 1.0f) { + if (isCurveCompletelyDrawn) { for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) { if (hitObject.getRepeatCount() - 1 > tcurRepeat) { Image arrow = GameImage.REVERSEARROW.getImage(); @@ -376,6 +373,26 @@ public class Slider extends GameObject { color = orig; } + private boolean drawSliderTrack(int trackPosition, float snakingSliderProgress) { + float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; + float curveIntervalFrom = 0f; + if (Options.isShrinkingSliders()) { + float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; + if (sliderprogress > 0) { + curveIntervalFrom = sliderprogress; + } + } + if (Options.isMergingSliders()) { + if (Options.isShrinkingSliders() && curveIntervalFrom > 0) { + game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curve.getCurvePoints().length)); + } + game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); + } else { + curve.draw(curveColor, curveIntervalFrom, curveIntervalTo); + } + return curveIntervalTo == 1f; + } + /** * Calculates the slider hit result. * @return the hit result (GameData.HIT_* constants) @@ -557,7 +574,9 @@ public class Slider extends GameObject { // calculate and send slider result hitResult(); - game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); + if (Options.isMergingSliders()) { + game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); + } return true; } diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 2a211beb..8509b637 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -126,7 +126,8 @@ public abstract class Curve { /** * 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 t set the curve interval to [0, t] + * @param t1 interval to draw from + * @param t2 interval to draw to */ public void draw(Color color, float t1, float t2) { if (curve == null) @@ -145,7 +146,7 @@ public abstract class Curve { hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Colors.WHITE_FADE); float a = fallbackSliderColor.a; fallbackSliderColor.a = color.a; - for (int i = 0; i < drawUpTo; i++) + for (int i = drawFrom; i < drawUpTo; i++) hitCircle.drawCentered(curve[i].x, curve[i].y, fallbackSliderColor); fallbackSliderColor.a = a; } @@ -154,7 +155,7 @@ public abstract class Curve { else { if (renderState == null) renderState = new CurveRenderState(hitObject, curve); - renderState.draw(color, borderColor, t1, t2); + renderState.draw(color, borderColor, t1, t2); // TODO } } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index c4275a4a..d44665f1 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -143,6 +143,8 @@ public class CurveRenderState { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } if (firstPointDrawn != drawFrom) { + 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); } else { diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index d18ca304..7c177319 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1455,15 +1455,17 @@ public class Game extends BasicGameState { this.leadInTime += epiImgTime; SoundController.mute(false); - // let's create knorkesliders - List curvepoints = new ArrayList<>(); - for (GameObject gameObject : gameObjects) { - if (gameObject.isSlider()) { - ((Slider) gameObject).baseSliderFrom = curvepoints.size(); - curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); + if (Options.isMergingSliders()) { + // let's create knorkesliders + List curvepoints = new ArrayList<>(); + for (GameObject gameObject : gameObjects) { + if (gameObject.isSlider()) { + ((Slider) gameObject).baseSliderFrom = curvepoints.size(); + curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); + } } + knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } - knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } slidercurveFrom = 0; @@ -1527,7 +1529,9 @@ public class Game extends BasicGameState { * @param trackPosition the track position */ private void drawHitObjects(Graphics g, int trackPosition) { - knorkesliders.draw(Color.white, this.slidercurveFrom, this.slidercurveTo); + if (Options.isMergingSliders()) { + knorkesliders.draw(Color.white, this.slidercurveFrom, this.slidercurveTo); + } // include previous object in follow points int lastObjectIndex = -1; if (objectIndex > 0 && objectIndex < beatmap.objects.length && diff --git a/src/itdelatrisu/opsu/states/OptionsMenu.java b/src/itdelatrisu/opsu/states/OptionsMenu.java index a41cb1a5..6f0cb44b 100644 --- a/src/itdelatrisu/opsu/states/OptionsMenu.java +++ b/src/itdelatrisu/opsu/states/OptionsMenu.java @@ -82,7 +82,9 @@ public class OptionsMenu extends BasicGameState { GameOption.FORCE_DEFAULT_PLAYFIELD, GameOption.IGNORE_BEATMAP_SKINS, GameOption.SNAKING_SLIDERS, + GameOption.SHRINKING_SLIDERS, GameOption.FALLBACK_SLIDERS, + GameOption.MERGING_SLIDERS, GameOption.SHOW_HIT_LIGHTING, GameOption.SHOW_COMBO_BURSTS, GameOption.SHOW_PERFECT_HIT, From 50f475e0f7d6db9f23e8b070ac4d620749d7af57 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 21:12:22 +0100 Subject: [PATCH 07/11] correct shrinking sliders for slider with odd amount of repeats --- src/itdelatrisu/opsu/objects/Slider.java | 14 +++++++++++++- src/itdelatrisu/opsu/objects/curves/Curve.java | 6 ++++++ .../opsu/render/CurveRenderState.java | 16 +++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index c2064bbb..d86ba79e 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -124,6 +124,8 @@ public class Slider extends GameObject { public int baseSliderFrom; + private boolean reversed; + /** * Initializes the Slider data type with images and dimensions. * @param container the game container @@ -377,7 +379,17 @@ public class Slider extends GameObject { float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; float curveIntervalFrom = 0f; if (Options.isShrinkingSliders()) { - float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; + // 1 repeat = no repeats.. + if (repeats % 2 == 0 && curveIntervalTo == 1 && !reversed) { + // fix shrinking sliders for odd repeating sliders + reversed = true; + if (Options.isMergingSliders()) { + + } else { + curve.reverse(); + } + } + float sliderprogress = (trackPosition - getTime() - (sliderTime * (repeats - 1))) / sliderTime; if (sliderprogress > 0) { curveIntervalFrom = sliderprogress; } diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 8509b637..4e23807a 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -159,6 +159,12 @@ public abstract class Curve { } } + public void reverse() { + if (renderState == null) + renderState = new CurveRenderState(hitObject, curve); + renderState.reverse(); + } + /** * Returns the angle of the first control point. */ diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index d44665f1..51872a38 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -66,6 +66,8 @@ public class CurveRenderState { private int lastPointDrawn; private int firstPointDrawn; + private boolean reversed; + /** * Set the width and height of the container that Curves get drawn into. * Should be called before any curves are drawn. @@ -110,6 +112,11 @@ public class CurveRenderState { createVertexBuffer(fbo.getVbo()); //write impossible value to make sure the fbo is cleared lastPointDrawn = -1; + reversed = false; + } + + public void reverse() { + reversed = !reversed; } /** @@ -322,7 +329,14 @@ public class CurveRenderState { if (clearFirst) { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } - for (int i = from * 2; i < to * 2 - 1; ++i) + from = from * 2; + to = to * 2 - 1; + if (reversed) { + int a = from; + from = curve.length * 2 - 1 - to; + to = curve.length * 2 - 1 - a; + } + for (int i = from; i < to; ++i) GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2); GL11.glFlush(); GL20.glDisableVertexAttribArray(staticState.texCoordLoc); From a3af1c71b8fa656009cc32a602d55cbab7ddaaca Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 21:52:15 +0100 Subject: [PATCH 08/11] attemt to fix shrinking sliders with odd amount of repeats with merged slider rendering --- src/itdelatrisu/opsu/objects/Slider.java | 13 ++++++++----- src/itdelatrisu/opsu/objects/curves/Curve.java | 6 ++++-- .../opsu/render/CurveRenderState.java | 17 ++++++++++++++++- src/itdelatrisu/opsu/states/Game.java | 4 ++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index d86ba79e..35514ddd 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -383,9 +383,7 @@ public class Slider extends GameObject { if (repeats % 2 == 0 && curveIntervalTo == 1 && !reversed) { // fix shrinking sliders for odd repeating sliders reversed = true; - if (Options.isMergingSliders()) { - - } else { + if (!Options.isMergingSliders()) { curve.reverse(); } } @@ -396,7 +394,12 @@ public class Slider extends GameObject { } if (Options.isMergingSliders()) { if (Options.isShrinkingSliders() && curveIntervalFrom > 0) { - game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curve.getCurvePoints().length)); + int curvelen = curve.getCurvePoints().length; + if (repeats % 2 == 0) { + game.spliceSliderCurve(baseSliderFrom + (int) ((1f - curveIntervalFrom) * curvelen), baseSliderFrom + curvelen); + } else { + game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curvelen)); + } } game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); } else { @@ -587,7 +590,7 @@ public class Slider extends GameObject { // calculate and send slider result hitResult(); if (Options.isMergingSliders()) { - game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); + game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length + 1); } return true; } diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 4e23807a..d09fc31d 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -160,11 +160,13 @@ public abstract class Curve { } public void reverse() { - if (renderState == null) - renderState = new CurveRenderState(hitObject, curve); renderState.reverse(); } + public void splice(int from, int to) { + renderState.splice(from, to); + } + /** * Returns the angle of the first control point. */ diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 51872a38..21d7199c 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -68,6 +68,9 @@ public class CurveRenderState { private boolean reversed; + private int spliceFrom; + private int spliceTo; + /** * Set the width and height of the container that Curves get drawn into. * Should be called before any curves are drawn. @@ -113,12 +116,20 @@ public class CurveRenderState { //write impossible value to make sure the fbo is cleared lastPointDrawn = -1; reversed = false; + spliceFrom = spliceTo = -1; } public void reverse() { reversed = !reversed; } + public void splice(int from, int to) { + spliceFrom = from * 2; + spliceTo = to * 2; + firstPointDrawn = -1; // force redraw + lastPointDrawn = -1; // force redraw + } + /** * Draw a curve to the screen that's tinted with `color`. The first time * this is called this caches the image result of the curve and on subsequent @@ -336,8 +347,12 @@ public class CurveRenderState { from = curve.length * 2 - 1 - to; to = curve.length * 2 - 1 - a; } - for (int i = from; i < to; ++i) + for (int i = from; i < to; ++i) { + if (spliceFrom <= i && i <= spliceTo) { + continue; + } GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2); + } GL11.glFlush(); GL20.glDisableVertexAttribArray(staticState.texCoordLoc); GL20.glDisableVertexAttribArray(staticState.attribLoc); diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 7c177319..6ea75fd9 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1523,6 +1523,10 @@ public class Game extends BasicGameState { this.slidercurveTo = Math.max(pos, this.slidercurveTo); } + public void spliceSliderCurve(int from, int to) { + this.knorkesliders.splice(from, to); + } + /** * Draws hit objects, hit results, and follow points. * @param g the graphics context From 0eb09d4e0da532986377af895a2203c39d101ca4 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 21:53:10 +0100 Subject: [PATCH 09/11] shrink the slider faster --- src/itdelatrisu/opsu/objects/Slider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 35514ddd..45507480 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -398,7 +398,7 @@ public class Slider extends GameObject { if (repeats % 2 == 0) { game.spliceSliderCurve(baseSliderFrom + (int) ((1f - curveIntervalFrom) * curvelen), baseSliderFrom + curvelen); } else { - game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curvelen)); + game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curvelen) + 1); } } game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); From 8171cfdec69506338e9576c4034cc618fa6f2778 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 22:03:09 +0100 Subject: [PATCH 10/11] also use splice for non-merging sliders instead of reverse --- src/itdelatrisu/opsu/objects/Slider.java | 15 +++++++-------- src/itdelatrisu/opsu/objects/curves/Curve.java | 4 ---- .../opsu/render/CurveRenderState.java | 16 +--------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 45507480..0efdbb85 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -379,14 +379,6 @@ public class Slider extends GameObject { float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; float curveIntervalFrom = 0f; if (Options.isShrinkingSliders()) { - // 1 repeat = no repeats.. - if (repeats % 2 == 0 && curveIntervalTo == 1 && !reversed) { - // fix shrinking sliders for odd repeating sliders - reversed = true; - if (!Options.isMergingSliders()) { - curve.reverse(); - } - } float sliderprogress = (trackPosition - getTime() - (sliderTime * (repeats - 1))) / sliderTime; if (sliderprogress > 0) { curveIntervalFrom = sliderprogress; @@ -403,6 +395,13 @@ public class Slider extends GameObject { } game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); } else { + if (Options.isShrinkingSliders() && curveIntervalFrom > 0) { + int curvelen = curve.getCurvePoints().length; + if (repeats % 2 == 0) { + curve.splice((int) ((1f - curveIntervalFrom) * curvelen), curvelen); + curveIntervalFrom = 0f; + } + } curve.draw(curveColor, curveIntervalFrom, curveIntervalTo); } return curveIntervalTo == 1f; diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index d09fc31d..f357e7e3 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -159,10 +159,6 @@ public abstract class Curve { } } - public void reverse() { - renderState.reverse(); - } - public void splice(int from, int to) { renderState.splice(from, to); } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 21d7199c..35b0e4f7 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -66,8 +66,6 @@ public class CurveRenderState { private int lastPointDrawn; private int firstPointDrawn; - private boolean reversed; - private int spliceFrom; private int spliceTo; @@ -115,14 +113,9 @@ public class CurveRenderState { createVertexBuffer(fbo.getVbo()); //write impossible value to make sure the fbo is cleared lastPointDrawn = -1; - reversed = false; spliceFrom = spliceTo = -1; } - public void reverse() { - reversed = !reversed; - } - public void splice(int from, int to) { spliceFrom = from * 2; spliceTo = to * 2; @@ -340,14 +333,7 @@ public class CurveRenderState { if (clearFirst) { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } - from = from * 2; - to = to * 2 - 1; - if (reversed) { - int a = from; - from = curve.length * 2 - 1 - to; - to = curve.length * 2 - 1 - a; - } - for (int i = from; i < to; ++i) { + for (int i = from * 2; i < to * 2 - 1; ++i) { if (spliceFrom <= i && i <= spliceTo) { continue; } From 766e3657c7a909bcfd5aa51e2db410c44178c819 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 4 Dec 2016 22:16:25 +0100 Subject: [PATCH 11/11] hide sliderticks that the ball already passed --- src/itdelatrisu/opsu/objects/Slider.java | 47 +++++++++++++++++------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 0efdbb85..cb893ea4 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -252,19 +252,8 @@ public class Slider extends GameObject { // ticks if (ticksT != null) { - float tickScale = 0.5f + 0.5f * AnimationEquation.OUT_BACK.calc(decorationsAlpha); - Image tick = GameImage.SLIDER_TICK.getImage().getScaledCopy(tickScale); - for (int i = 0; i < ticksT.length; i++) { - Vec2f c = curve.pointAt(ticksT[i]); - Colors.WHITE_FADE.a = Math.min(curveAlpha, decorationsAlpha); - g.pushTransform(); - if (mirror) { - g.rotate(c.x, c.y, -180f); - } - tick.drawCentered(c.x, c.y, Colors.WHITE_FADE); - g.popTransform(); - Colors.WHITE_FADE.a = alpha; - } + drawSliderTicks(g, trackPosition, curveAlpha, decorationsAlpha, mirror); + Colors.WHITE_FADE.a = alpha; } g.pushTransform(); @@ -375,6 +364,38 @@ public class Slider extends GameObject { color = orig; } + private void drawSliderTicks(Graphics g, int trackPosition, float curveAlpha, float decorationsAlpha, boolean mirror) { + float tickScale = 0.5f + 0.5f * AnimationEquation.OUT_BACK.calc(decorationsAlpha); + Image tick = GameImage.SLIDER_TICK.getImage().getScaledCopy(tickScale); + + // calculate which ticks need to be drawn (don't draw if sliderball crossed it) + int min = 0; + int max = ticksT.length; + if (trackPosition > getTime()) { + for (int i = 0; i < ticksT.length; ) { + if (((trackPosition - getTime()) % sliderTime) / sliderTime < ticksT[i]) { + break; + } + min = ++i; + } + } + if (currentRepeats % 2 == 1) { + max -= min; + min = 0; + } + + for (int i = min; i < max; i++) { + Vec2f c = curve.pointAt(ticksT[i]); + Colors.WHITE_FADE.a = Math.min(curveAlpha, decorationsAlpha); + g.pushTransform(); + if (mirror) { + g.rotate(c.x, c.y, -180f); + } + tick.drawCentered(c.x, c.y, Colors.WHITE_FADE); + g.popTransform(); + } + } + private boolean drawSliderTrack(int trackPosition, float snakingSliderProgress) { float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; float curveIntervalFrom = 0f;