Follow-up to #64.
- Removed NEW_SLIDER option, and use the skin "SliderStyle" instead. Uses the new style by default, unless STYLE_PEPPYSLIDER is specified. - Check if OpenGL 3.0 is supported before trying to draw new style sliders. - Fixed compilation warnings; removed unneeded fields and imports. - Filled in some missing Javadocs. - Style changes. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
9c8a8f24c6
commit
b6f208a47d
|
@ -374,16 +374,10 @@ public class GameData {
|
||||||
health = 100f;
|
health = 100f;
|
||||||
healthDisplay = 100f;
|
healthDisplay = 100f;
|
||||||
hitResultCount = new int[HIT_MAX];
|
hitResultCount = new int[HIT_MAX];
|
||||||
if(hitResultList != null)
|
if (hitResultList != null) {
|
||||||
{
|
for (OsuHitObjectResult hitResult : hitResultList) {
|
||||||
Iterator<OsuHitObjectResult> iter =hitResultList.iterator();
|
if (hitResult.curve != null)
|
||||||
while(iter.hasNext())
|
hitResult.curve.discardCache();
|
||||||
{
|
|
||||||
OsuHitObjectResult hitObj = iter.next();
|
|
||||||
if(hitObj != null && hitObj.curve != null)
|
|
||||||
{
|
|
||||||
hitObj.curve.discardCache();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hitResultList = new LinkedBlockingDeque<OsuHitObjectResult>();
|
hitResultList = new LinkedBlockingDeque<OsuHitObjectResult>();
|
||||||
|
@ -953,9 +947,7 @@ public class GameData {
|
||||||
hitResult.alpha = 1 - ((float) (trackPosition - hitResult.time) / HITRESULT_FADE_TIME);
|
hitResult.alpha = 1 - ((float) (trackPosition - hitResult.time) / HITRESULT_FADE_TIME);
|
||||||
} else {
|
} else {
|
||||||
if (hitResult.curve != null)
|
if (hitResult.curve != null)
|
||||||
{
|
|
||||||
hitResult.curve.discardCache();
|
hitResult.curve.discardCache();
|
||||||
}
|
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,6 @@ public class Options {
|
||||||
UI.getCursor().reset();
|
UI.getCursor().reset();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NEW_SLIDER("Enable New Slider", "Use the new Slider style (requires OpenGL 3.0).",false),
|
|
||||||
DYNAMIC_BACKGROUND ("Enable Dynamic Backgrounds", "The song background will be used as the main menu background.", true),
|
DYNAMIC_BACKGROUND ("Enable Dynamic Backgrounds", "The song background will be used as the main menu background.", true),
|
||||||
BACKGROUND_DIM ("Background Dim", "Percentage to dim the background image during gameplay.", 50, 0, 100),
|
BACKGROUND_DIM ("Background Dim", "Percentage to dim the background image during gameplay.", 50, 0, 100),
|
||||||
FORCE_DEFAULT_PLAYFIELD ("Force Default Playfield", "Override the song background with the default playfield background.", false),
|
FORCE_DEFAULT_PLAYFIELD ("Force Default Playfield", "Override the song background with the default playfield background.", false),
|
||||||
|
@ -1072,9 +1071,6 @@ public class Options {
|
||||||
case "NewCursor":
|
case "NewCursor":
|
||||||
GameOption.NEW_CURSOR.setValue(Boolean.parseBoolean(value));
|
GameOption.NEW_CURSOR.setValue(Boolean.parseBoolean(value));
|
||||||
break;
|
break;
|
||||||
case "NewSlider":
|
|
||||||
GameOption.NEW_SLIDER.setValue(Boolean.parseBoolean(value));
|
|
||||||
break;
|
|
||||||
case "DynamicBackground":
|
case "DynamicBackground":
|
||||||
GameOption.DYNAMIC_BACKGROUND.setValue(Boolean.parseBoolean(value));
|
GameOption.DYNAMIC_BACKGROUND.setValue(Boolean.parseBoolean(value));
|
||||||
break;
|
break;
|
||||||
|
@ -1226,8 +1222,6 @@ public class Options {
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("NewCursor = %b", isNewCursorEnabled()));
|
writer.write(String.format("NewCursor = %b", isNewCursorEnabled()));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("NewSlider = %b", GameOption.NEW_SLIDER.getBooleanValue()));
|
|
||||||
writer.newLine();
|
|
||||||
writer.write(String.format("DynamicBackground = %b", isDynamicBackgroundEnabled()));
|
writer.write(String.format("DynamicBackground = %b", isDynamicBackgroundEnabled()));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("LoadVerbose = %b", isLoadVerbose()));
|
writer.write(String.format("LoadVerbose = %b", isLoadVerbose()));
|
||||||
|
|
|
@ -187,9 +187,8 @@ public class Slider implements GameObject {
|
||||||
|
|
||||||
// start circle
|
// start circle
|
||||||
hitCircle.drawCentered(x, y, color);
|
hitCircle.drawCentered(x, y, color);
|
||||||
if (!overlayAboveNumber) {
|
if (!overlayAboveNumber)
|
||||||
hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE);
|
hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE);
|
||||||
}
|
|
||||||
|
|
||||||
// ticks
|
// ticks
|
||||||
if (ticksT != null) {
|
if (ticksT != null) {
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
package itdelatrisu.opsu.objects.curves;
|
package itdelatrisu.opsu.objects.curves;
|
||||||
|
|
||||||
import itdelatrisu.opsu.render.CurveRenderState;
|
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.beatmap.HitObject;
|
import itdelatrisu.opsu.beatmap.HitObject;
|
||||||
import itdelatrisu.opsu.Options;
|
import itdelatrisu.opsu.render.CurveRenderState;
|
||||||
|
import itdelatrisu.opsu.skins.Skin;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GLContext;
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.Image;
|
import org.newdawn.slick.Image;
|
||||||
import org.newdawn.slick.util.Log;
|
import org.newdawn.slick.util.Log;
|
||||||
|
@ -37,8 +39,8 @@ public abstract class Curve {
|
||||||
/** Points generated along the curve should be spaced this far apart. */
|
/** Points generated along the curve should be spaced this far apart. */
|
||||||
protected static float CURVE_POINTS_SEPERATION = 5;
|
protected static float CURVE_POINTS_SEPERATION = 5;
|
||||||
|
|
||||||
/** The width and height of the display container this curve gets drawn into */
|
/** Whether OpenGL 3.0 is supported. */
|
||||||
protected static int containerWidth = 0, containerHeight = 0;
|
private static boolean openGL30 = false;
|
||||||
|
|
||||||
/** The associated HitObject. */
|
/** The associated HitObject. */
|
||||||
protected HitObject hitObject;
|
protected HitObject hitObject;
|
||||||
|
@ -49,7 +51,7 @@ public abstract class Curve {
|
||||||
/** The scaled slider x, y coordinate lists. */
|
/** The scaled slider x, y coordinate lists. */
|
||||||
protected float[] sliderX, sliderY;
|
protected float[] sliderX, sliderY;
|
||||||
|
|
||||||
/** Per-curve render-state used for the new style curve renders*/
|
/** Per-curve render-state used for the new style curve renders. */
|
||||||
private CurveRenderState renderState;
|
private CurveRenderState renderState;
|
||||||
|
|
||||||
/** Points along the curve (set by inherited classes). */
|
/** Points along the curve (set by inherited classes). */
|
||||||
|
@ -70,16 +72,20 @@ public abstract class Curve {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the width and height of the container that Curves get drawn into
|
* Set the width and height of the container that Curves get drawn into.
|
||||||
* Should be called before any curves are drawn.
|
* Should be called before any curves are drawn.
|
||||||
* @param width
|
* @param width the container width
|
||||||
* @param height
|
* @param height the container height
|
||||||
|
* @param circleSize the circle size
|
||||||
*/
|
*/
|
||||||
public static void init(int width, int height, float circleSize)
|
public static void init(int width, int height, float circleSize) {
|
||||||
{
|
openGL30 = GLContext.getCapabilities().OpenGL30;
|
||||||
containerWidth = width;
|
if (openGL30)
|
||||||
containerHeight = height;
|
|
||||||
CurveRenderState.init(width, height, circleSize);
|
CurveRenderState.init(width, height, circleSize);
|
||||||
|
else {
|
||||||
|
if (Options.getSkin().getSliderStyle() != Skin.STYLE_PEPPYSLIDER)
|
||||||
|
Log.warn("New slider style requires OpenGL 3.0, which is not supported.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,23 +100,24 @@ public abstract class Curve {
|
||||||
* @param color the color filter
|
* @param color the color filter
|
||||||
*/
|
*/
|
||||||
public void draw(Color color) {
|
public void draw(Color color) {
|
||||||
if (curve == null) {
|
if (curve == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (Options.GameOption.NEW_SLIDER.getBooleanValue()) {
|
// peppysliders
|
||||||
if (renderState == null) {
|
if (Options.getSkin().getSliderStyle() == Skin.STYLE_PEPPYSLIDER || !openGL30) {
|
||||||
renderState = new CurveRenderState(hitObject);
|
|
||||||
}
|
|
||||||
renderState.draw(color, curve);
|
|
||||||
} else {
|
|
||||||
Image hitCircle = GameImage.HITCIRCLE.getImage();
|
Image hitCircle = GameImage.HITCIRCLE.getImage();
|
||||||
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
|
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
|
||||||
for (int i = 0; i < curve.length; i++) {
|
for (int i = 0; i < curve.length; i++)
|
||||||
hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Utils.COLOR_WHITE_FADE);
|
hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Utils.COLOR_WHITE_FADE);
|
||||||
}
|
for (int i = 0; i < curve.length; i++)
|
||||||
for (int i = 0; i < curve.length; i++) {
|
|
||||||
hitCircle.drawCentered(curve[i].x, curve[i].y, color);
|
hitCircle.drawCentered(curve[i].x, curve[i].y, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mmsliders
|
||||||
|
else {
|
||||||
|
if (renderState == null)
|
||||||
|
renderState = new CurveRenderState(hitObject);
|
||||||
|
renderState.draw(color, curve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +150,9 @@ public abstract class Curve {
|
||||||
return a * (1 - t) + b * t;
|
return a * (1 - t) + b * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards the slider cache (only used for mmsliders).
|
||||||
|
*/
|
||||||
public void discardCache() {
|
public void discardCache() {
|
||||||
if (renderState != null)
|
if (renderState != null)
|
||||||
renderState.discardCache();
|
renderState.discardCache();
|
||||||
|
|
|
@ -18,12 +18,13 @@
|
||||||
package itdelatrisu.opsu.render;
|
package itdelatrisu.opsu.render;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.Options;
|
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.beatmap.HitObject;
|
import itdelatrisu.opsu.beatmap.HitObject;
|
||||||
import itdelatrisu.opsu.objects.curves.Vec2f;
|
import itdelatrisu.opsu.objects.curves.Vec2f;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
|
@ -38,45 +39,46 @@ import org.newdawn.slick.util.Log;
|
||||||
/**
|
/**
|
||||||
* Hold the temporary render state that needs to be restored again after the new
|
* Hold the temporary render state that needs to be restored again after the new
|
||||||
* style curves are drawn.
|
* style curves are drawn.
|
||||||
|
*
|
||||||
|
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||||
*/
|
*/
|
||||||
public class CurveRenderState {
|
public class CurveRenderState {
|
||||||
|
/** The width and height of the display container this curve gets drawn into. */
|
||||||
/** The width and height of the display container this curve gets drawn into */
|
|
||||||
protected static int containerWidth, containerHeight;
|
protected static int containerWidth, containerHeight;
|
||||||
|
|
||||||
/** cached drawn slider, only used if new style sliders are activated */
|
/** Thickness of the curve. */
|
||||||
public Rendertarget fbo;
|
|
||||||
|
|
||||||
/** thickness of the curve */
|
|
||||||
protected static int scale;
|
protected static int scale;
|
||||||
|
|
||||||
/** The HitObject associated with the curve to be drawn */
|
/** Static state that's needed to draw the new style curves. */
|
||||||
HitObject hitObject;
|
|
||||||
|
|
||||||
/** Static state that's needed to draw the new style curves */
|
|
||||||
private static final NewCurveStyleState staticState = new NewCurveStyleState();
|
private static final NewCurveStyleState staticState = new NewCurveStyleState();
|
||||||
|
|
||||||
|
/** Cached drawn slider, only used if new style sliders are activated. */
|
||||||
|
public Rendertarget fbo;
|
||||||
|
|
||||||
|
/** The HitObject associated with the curve to be drawn. */
|
||||||
|
protected HitObject hitObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the width and height of the container that Curves get drawn into
|
* Set the width and height of the container that Curves get drawn into.
|
||||||
* Should be called before any curves are drawn.
|
* Should be called before any curves are drawn.
|
||||||
* @param width
|
* @param width the container width
|
||||||
* @param height
|
* @param height the container height
|
||||||
|
* @param circleSize the circle size
|
||||||
*/
|
*/
|
||||||
public static void init(int width, int height, float circleSize)
|
public static void init(int width, int height, float circleSize) {
|
||||||
{
|
|
||||||
containerWidth = width;
|
containerWidth = width;
|
||||||
containerHeight = height;
|
containerHeight = height;
|
||||||
//equivalent to what happens in Slider.init
|
|
||||||
|
// equivalent to what happens in Slider.init()
|
||||||
scale = (int) (104 - (circleSize * 8));
|
scale = (int) (104 - (circleSize * 8));
|
||||||
scale = (int) (scale * HitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
scale = (int) (scale * HitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||||
//scale = scale * 118 / 128; //for curves exaclty as big as the sliderball
|
//scale = scale * 118 / 128; //for curves exactly as big as the sliderball
|
||||||
FrameBufferCache.init(width, height);
|
FrameBufferCache.init(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an object to hold the render state that's necessary to draw a curve.
|
* Creates an object to hold the render state that's necessary to draw a curve.
|
||||||
* @param hitObject the HitObject that represents this curve, just used as a
|
* @param hitObject the HitObject that represents this curve, just used as a unique ID
|
||||||
* unique ID
|
|
||||||
*/
|
*/
|
||||||
public CurveRenderState(HitObject hitObject) {
|
public CurveRenderState(HitObject hitObject) {
|
||||||
fbo = null;
|
fbo = null;
|
||||||
|
@ -92,13 +94,13 @@ public class CurveRenderState {
|
||||||
*/
|
*/
|
||||||
public void draw(Color color, Vec2f[] curve) {
|
public void draw(Color color, Vec2f[] curve) {
|
||||||
float alpha = color.a;
|
float alpha = color.a;
|
||||||
|
|
||||||
// if this curve hasn't been drawn, draw it and cache the result
|
// if this curve hasn't been drawn, draw it and cache the result
|
||||||
if (fbo == null) {
|
if (fbo == null) {
|
||||||
FrameBufferCache cache = FrameBufferCache.getInstance();
|
FrameBufferCache cache = FrameBufferCache.getInstance();
|
||||||
Rendertarget mapping = cache.get(hitObject);
|
Rendertarget mapping = cache.get(hitObject);
|
||||||
if (mapping == null) {
|
if (mapping == null)
|
||||||
mapping = cache.insert(hitObject);
|
mapping = cache.insert(hitObject);
|
||||||
}
|
|
||||||
fbo = mapping;
|
fbo = mapping;
|
||||||
|
|
||||||
int old_fb = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
|
int old_fb = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
|
||||||
|
@ -134,15 +136,18 @@ public class CurveRenderState {
|
||||||
GL11.glEnd();
|
GL11.glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discard the cache.
|
||||||
|
*/
|
||||||
public void discardCache() {
|
public void discardCache() {
|
||||||
fbo = null;
|
fbo = null;
|
||||||
FrameBufferCache.getInstance().freeMappingFor(hitObject);
|
FrameBufferCache.getInstance().freeMappingFor(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just a structure to hold all the important OpenGL state that needs to be
|
* A structure to hold all the important OpenGL state that needs to be
|
||||||
* changed to draw the curve. This is used to backup and restore the state
|
* changed to draw the curve. This is used to backup and restore the state
|
||||||
* so that the code outside of this (mainly Slick2D) doesn't break
|
* so that the code outside of this (mainly Slick2D) doesn't break.
|
||||||
*/
|
*/
|
||||||
private class RenderState {
|
private class RenderState {
|
||||||
boolean smoothedPoly;
|
boolean smoothedPoly;
|
||||||
|
@ -157,8 +162,7 @@ public class CurveRenderState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backup the current state of the relevant OpenGL state and change it to
|
* Backup the current state of the relevant OpenGL state and change it to
|
||||||
* what's needed to draw the curve
|
* what's needed to draw the curve.
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private RenderState startRender() {
|
private RenderState startRender() {
|
||||||
RenderState state = new RenderState();
|
RenderState state = new RenderState();
|
||||||
|
@ -196,7 +200,7 @@ public class CurveRenderState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore the old OpenGL state that's backed up in {@code state}
|
* Restore the old OpenGL state that's backed up in {@code state}.
|
||||||
* @param state the old state to restore
|
* @param state the old state to restore
|
||||||
*/
|
*/
|
||||||
private void endRender(RenderState state) {
|
private void endRender(RenderState state) {
|
||||||
|
@ -208,22 +212,17 @@ public class CurveRenderState {
|
||||||
GL20.glUseProgram(state.oldProgram);
|
GL20.glUseProgram(state.oldProgram);
|
||||||
GL13.glActiveTexture(state.texUnit);
|
GL13.glActiveTexture(state.texUnit);
|
||||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, state.oldArrayBuffer);
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, state.oldArrayBuffer);
|
||||||
if (!state.depthWriteEnabled) {
|
if (!state.depthWriteEnabled)
|
||||||
GL11.glDepthMask(false);
|
GL11.glDepthMask(false);
|
||||||
}
|
if (!state.depthEnabled)
|
||||||
if (!state.depthEnabled) {
|
|
||||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||||
}
|
if (state.texEnabled)
|
||||||
if (state.texEnabled) {
|
|
||||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||||
}
|
if (state.smoothedPoly)
|
||||||
if (state.smoothedPoly) {
|
|
||||||
GL11.glEnable(GL11.GL_POLYGON_SMOOTH);
|
GL11.glEnable(GL11.GL_POLYGON_SMOOTH);
|
||||||
}
|
if (!state.blendEnabled)
|
||||||
if (!state.blendEnabled) {
|
|
||||||
GL11.glDisable(GL11.GL_BLEND);
|
GL11.glDisable(GL11.GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the actual drawing of the curve into the currently bound framebuffer.
|
* Do the actual drawing of the curve into the currently bound framebuffer.
|
||||||
|
@ -234,7 +233,7 @@ public class CurveRenderState {
|
||||||
staticState.initGradient();
|
staticState.initGradient();
|
||||||
RenderState state = startRender();
|
RenderState state = startRender();
|
||||||
int vtx_buf;
|
int vtx_buf;
|
||||||
//The size is: floatsize * (position + texture coordinates) * (number of cones) * (vertices in a cone)
|
// the size is: floatsize * (position + texture coordinates) * (number of cones) * (vertices in a cone)
|
||||||
FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (2 * curve.length - 1) * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer();
|
FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (2 * curve.length - 1) * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer();
|
||||||
staticState.initShaderProgram();
|
staticState.initShaderProgram();
|
||||||
vtx_buf = GL15.glGenBuffers();
|
vtx_buf = GL15.glGenBuffers();
|
||||||
|
@ -265,9 +264,8 @@ public class CurveRenderState {
|
||||||
//2*4 is for skipping the first 2 floats (u,v)
|
//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.attribLoc, 4, GL11.GL_FLOAT, false, 6 * 4, 2 * 4);
|
||||||
GL20.glVertexAttribPointer(staticState.texCoordLoc, 2, GL11.GL_FLOAT, false, 6 * 4, 0);
|
GL20.glVertexAttribPointer(staticState.texCoordLoc, 2, GL11.GL_FLOAT, false, 6 * 4, 0);
|
||||||
for (int i = 0; i < curve.length*2-1; ++i) {
|
for (int i = 0; i < curve.length * 2 - 1; ++i)
|
||||||
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2);
|
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2);
|
||||||
}
|
|
||||||
GL20.glDisableVertexAttribArray(staticState.texCoordLoc);
|
GL20.glDisableVertexAttribArray(staticState.texCoordLoc);
|
||||||
GL20.glDisableVertexAttribArray(staticState.attribLoc);
|
GL20.glDisableVertexAttribArray(staticState.attribLoc);
|
||||||
GL15.glDeleteBuffers(vtx_buf);
|
GL15.glDeleteBuffers(vtx_buf);
|
||||||
|
@ -277,7 +275,7 @@ public class CurveRenderState {
|
||||||
/**
|
/**
|
||||||
* Fill {@code buff} with the texture coordinates and positions for a cone
|
* Fill {@code buff} with the texture coordinates and positions for a cone
|
||||||
* with {@code DIVIDES} ground corners that has its center at the coordinates
|
* with {@code DIVIDES} ground corners that has its center at the coordinates
|
||||||
* {@code (x1,y1)}
|
* {@code (x1,y1)}.
|
||||||
* @param buff the buffer to be filled
|
* @param buff the buffer to be filled
|
||||||
* @param x1 x-coordinate of the cone
|
* @param x1 x-coordinate of the cone
|
||||||
* @param y1 y-coordinate of the cone
|
* @param y1 y-coordinate of the cone
|
||||||
|
@ -332,44 +330,40 @@ public class CurveRenderState {
|
||||||
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||||
*/
|
*/
|
||||||
private static class NewCurveStyleState {
|
private static class NewCurveStyleState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* used for new style Slider rendering, defines how many vertices the
|
* Used for new style Slider rendering, defines how many vertices the
|
||||||
* base of the cone has that is used to draw the curve
|
* base of the cone has that is used to draw the curve.
|
||||||
*/
|
*/
|
||||||
protected static final int DIVIDES = 30;
|
protected static final int DIVIDES = 30;
|
||||||
|
|
||||||
/** OpenGL shader program ID used to draw and recolor the curve */
|
/** OpenGL shader program ID used to draw and recolor the curve. */
|
||||||
protected int program = 0;
|
protected int program = 0;
|
||||||
|
|
||||||
/** OpenGL shader attribute location of the vertex position attribute */
|
/** OpenGL shader attribute location of the vertex position attribute. */
|
||||||
protected int attribLoc = 0;
|
protected int attribLoc = 0;
|
||||||
|
|
||||||
/** OpenGL shader attribute location of the texture coordinate attribute */
|
/** OpenGL shader attribute location of the texture coordinate attribute. */
|
||||||
protected int texCoordLoc = 0;
|
protected int texCoordLoc = 0;
|
||||||
|
|
||||||
/** OpenGL shader uniform location of the color attribute */
|
/** OpenGL shader uniform location of the color attribute. */
|
||||||
protected int colLoc = 0;
|
protected int colLoc = 0;
|
||||||
|
|
||||||
/** OpenGL shader uniform location of the texture sampler attribute */
|
/** OpenGL shader uniform location of the texture sampler attribute. */
|
||||||
protected int texLoc = 0;
|
protected int texLoc = 0;
|
||||||
|
|
||||||
/** OpenGL texture id for the gradient texture for the curve */
|
/** OpenGL texture id for the gradient texture for the curve. */
|
||||||
protected int gradientTexture = 0;
|
protected int gradientTexture = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the first row of the slider gradient texture and upload it as
|
* Reads the first row of the slider gradient texture and upload it as
|
||||||
* a 1D texture to OpenGL if it hasn't already been done
|
* a 1D texture to OpenGL if it hasn't already been done.
|
||||||
*/
|
*/
|
||||||
public void initGradient()
|
public void initGradient() {
|
||||||
{
|
if (gradientTexture == 0) {
|
||||||
if(gradientTexture == 0)
|
|
||||||
{
|
|
||||||
Image slider = GameImage.SLIDER_GRADIENT.getImage().getScaledCopy(1.0f / GameImage.getUIscale());
|
Image slider = GameImage.SLIDER_GRADIENT.getImage().getScaledCopy(1.0f / GameImage.getUIscale());
|
||||||
staticState.gradientTexture = GL11.glGenTextures();
|
staticState.gradientTexture = GL11.glGenTextures();
|
||||||
ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth() * 4);
|
ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth() * 4);
|
||||||
for(int i=0 ; i< slider.getWidth(); ++i)
|
for (int i = 0; i < slider.getWidth(); ++i) {
|
||||||
{
|
|
||||||
Color col = slider.getColor(i, 0);
|
Color col = slider.getColor(i, 0);
|
||||||
buff.put((byte) (255 * col.r));
|
buff.put((byte) (255 * col.r));
|
||||||
buff.put((byte) (255 * col.g));
|
buff.put((byte) (255 * col.g));
|
||||||
|
@ -407,7 +401,7 @@ public class CurveRenderState {
|
||||||
int res = GL20.glGetShaderi(vtxShdr, GL20.GL_COMPILE_STATUS);
|
int res = GL20.glGetShaderi(vtxShdr, GL20.GL_COMPILE_STATUS);
|
||||||
if (res != GL11.GL_TRUE) {
|
if (res != GL11.GL_TRUE) {
|
||||||
String error = GL20.glGetShaderInfoLog(vtxShdr, 1024);
|
String error = GL20.glGetShaderInfoLog(vtxShdr, 1024);
|
||||||
Log.error("Vertex Shader compilation failed", new Exception(error));
|
Log.error("Vertex Shader compilation failed.", new Exception(error));
|
||||||
}
|
}
|
||||||
GL20.glShaderSource(frgShdr, "#version 330\n"
|
GL20.glShaderSource(frgShdr, "#version 330\n"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
|
@ -429,7 +423,7 @@ public class CurveRenderState {
|
||||||
res = GL20.glGetShaderi(frgShdr, GL20.GL_COMPILE_STATUS);
|
res = GL20.glGetShaderi(frgShdr, GL20.GL_COMPILE_STATUS);
|
||||||
if (res != GL11.GL_TRUE) {
|
if (res != GL11.GL_TRUE) {
|
||||||
String error = GL20.glGetShaderInfoLog(frgShdr, 1024);
|
String error = GL20.glGetShaderInfoLog(frgShdr, 1024);
|
||||||
Log.error("Fragment Shader compilation failed", new Exception(error));
|
Log.error("Fragment Shader compilation failed.", new Exception(error));
|
||||||
}
|
}
|
||||||
GL20.glAttachShader(program, vtxShdr);
|
GL20.glAttachShader(program, vtxShdr);
|
||||||
GL20.glAttachShader(program, frgShdr);
|
GL20.glAttachShader(program, frgShdr);
|
||||||
|
@ -437,7 +431,7 @@ public class CurveRenderState {
|
||||||
res = GL20.glGetProgrami(program, GL20.GL_LINK_STATUS);
|
res = GL20.glGetProgrami(program, GL20.GL_LINK_STATUS);
|
||||||
if (res != GL11.GL_TRUE) {
|
if (res != GL11.GL_TRUE) {
|
||||||
String error = GL20.glGetProgramInfoLog(program, 1024);
|
String error = GL20.glGetProgramInfoLog(program, 1024);
|
||||||
Log.error("Program linking failed", new Exception(error));
|
Log.error("Program linking failed.", new Exception(error));
|
||||||
}
|
}
|
||||||
attribLoc = GL20.glGetAttribLocation(program, "in_position");
|
attribLoc = GL20.glGetAttribLocation(program, "in_position");
|
||||||
texCoordLoc = GL20.glGetAttribLocation(program, "in_tex_coord");
|
texCoordLoc = GL20.glGetAttribLocation(program, "in_tex_coord");
|
||||||
|
|
|
@ -17,57 +17,68 @@
|
||||||
*/
|
*/
|
||||||
package itdelatrisu.opsu.render;
|
package itdelatrisu.opsu.render;
|
||||||
|
|
||||||
import itdelatrisu.opsu.Opsu;
|
|
||||||
import itdelatrisu.opsu.Options;
|
|
||||||
import itdelatrisu.opsu.beatmap.HitObject;
|
import itdelatrisu.opsu.beatmap.HitObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.newdawn.slick.util.Log;
|
import org.newdawn.slick.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is cache for OpenGL FrameBufferObjects. This is currently only used
|
* This is cache for OpenGL FrameBufferObjects. This is currently only used
|
||||||
* to draw curve objects of the new slider style. Does currently not integrate
|
* to draw curve objects of the new slider style. Does currently not integrate
|
||||||
* well and requires some manual OpenGL state manipulation to use it.
|
* well and requires some manual OpenGL state manipulation to use it.
|
||||||
|
*
|
||||||
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||||
*/
|
*/
|
||||||
public class FrameBufferCache {
|
public class FrameBufferCache {
|
||||||
private static final int INITIAL_CACHE_SIZE = 4;
|
/** The initial cache size. */
|
||||||
|
//private static final int INITIAL_CACHE_SIZE = 4;
|
||||||
|
|
||||||
|
/** The single framebuffer cache instance. */
|
||||||
private static FrameBufferCache instance = null;
|
private static FrameBufferCache instance = null;
|
||||||
|
|
||||||
|
/** The mapping from hit objects to framebuffers. */
|
||||||
private Map<HitObject, Rendertarget> cacheMap;
|
private Map<HitObject, Rendertarget> cacheMap;
|
||||||
|
|
||||||
|
/** */
|
||||||
private ArrayList<Rendertarget> cache;
|
private ArrayList<Rendertarget> cache;
|
||||||
public static int width;
|
|
||||||
public static int height;
|
/** Container dimensions. */
|
||||||
|
public static int width, height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the width and height of the framebuffers in this cache.
|
* Set the width and height of the framebuffers in this cache.
|
||||||
* Should be called before anything is inserted into the map.
|
* Should be called before anything is inserted into the map.
|
||||||
* @param width
|
* @param width the container width
|
||||||
* @param height
|
* @param height the container height
|
||||||
*/
|
*/
|
||||||
public static void init(int width, int height)
|
public static void init(int width, int height) {
|
||||||
{
|
|
||||||
FrameBufferCache.width = width;
|
FrameBufferCache.width = width;
|
||||||
FrameBufferCache.height = height;
|
FrameBufferCache.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
private FrameBufferCache() {
|
private FrameBufferCache() {
|
||||||
cache = new ArrayList<>();
|
cache = new ArrayList<Rendertarget>();
|
||||||
cacheMap = new HashMap<>();
|
cacheMap = new HashMap<HitObject, Rendertarget>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there is a framebuffer object mapped to the {@code HitObject obj}
|
* Check if there is a framebuffer object mapped to {@code obj}.
|
||||||
* @param obj
|
* @param obj the hit object
|
||||||
* @return true if there is a framebuffer mapped for this HitObject, else false
|
* @return true if there is a framebuffer mapped for this {@code HitObject}, else false
|
||||||
*/
|
*/
|
||||||
public boolean contains(HitObject obj) {
|
public boolean contains(HitObject obj) {
|
||||||
return cacheMap.containsKey(obj);
|
return cacheMap.containsKey(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@code Rendertarget} mapped to {@code obj}
|
* Get the {@code Rendertarget} mapped to {@code obj}.
|
||||||
* @param obj
|
* @param obj the hit object
|
||||||
* @return the {@code Rendertarget} if there's one mapped to {@code obj}, otherwise null
|
* @return the {@code Rendertarget} if there's one mapped to {@code obj}, otherwise null
|
||||||
*/
|
*/
|
||||||
public Rendertarget get(HitObject obj) {
|
public Rendertarget get(HitObject obj) {
|
||||||
|
@ -75,8 +86,8 @@ public class FrameBufferCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the mapping for {@code obj} to free it up to get used by another {@code HitObject}
|
* Clear the mapping for {@code obj} to free it up to get used by another {@code HitObject}.
|
||||||
* @param obj
|
* @param obj the hit object
|
||||||
* @return true if there was a mapping for {@code obj} and false if there was no mapping for it.
|
* @return true if there was a mapping for {@code obj} and false if there was no mapping for it.
|
||||||
*/
|
*/
|
||||||
public boolean freeMappingFor(HitObject obj) {
|
public boolean freeMappingFor(HitObject obj) {
|
||||||
|
@ -95,7 +106,7 @@ public class FrameBufferCache {
|
||||||
* Create a mapping from {@code obj} to a framebuffer. If there was already
|
* Create a mapping from {@code obj} to a framebuffer. If there was already
|
||||||
* a mapping from {@code obj} this will associate another framebuffer with it
|
* a mapping from {@code obj} this will associate another framebuffer with it
|
||||||
* (thereby freeing up the previously mapped framebuffer).
|
* (thereby freeing up the previously mapped framebuffer).
|
||||||
* @param obj
|
* @param obj the hit object
|
||||||
* @return the {@code Rendertarget} newly mapped to {@code obj}
|
* @return the {@code Rendertarget} newly mapped to {@code obj}
|
||||||
*/
|
*/
|
||||||
public Rendertarget insert(HitObject obj) {
|
public Rendertarget insert(HitObject obj) {
|
||||||
|
@ -108,6 +119,7 @@ public class FrameBufferCache {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no unmapped RTTFramebuffer found, create a new one
|
// no unmapped RTTFramebuffer found, create a new one
|
||||||
buffer = Rendertarget.createRTTFramebuffer(width, height);
|
buffer = Rendertarget.createRTTFramebuffer(width, height);
|
||||||
cache.add(buffer);
|
cache.add(buffer);
|
||||||
|
@ -117,15 +129,14 @@ public class FrameBufferCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There should only ever be one framebuffer cache, this function returns that one framebuffer cache instance.
|
* There should only ever be one framebuffer cache, this function returns
|
||||||
|
* that one framebuffer cache instance.
|
||||||
* If there was no instance created already then this function creates it.
|
* If there was no instance created already then this function creates it.
|
||||||
* @return the instance of FrameBufferCache
|
* @return the instance of FrameBufferCache
|
||||||
*/
|
*/
|
||||||
public static FrameBufferCache getInstance() {
|
public static FrameBufferCache getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null)
|
||||||
instance = new FrameBufferCache();
|
instance = new FrameBufferCache();
|
||||||
}
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,23 +24,26 @@ import org.lwjgl.opengl.GL30;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Represents a rendertarget. For now this maps to an OpenGL FBO via LWJGL.
|
||||||
*
|
*
|
||||||
* Represents a rendertarget. For now this maps to an OpenGL FBO via LWJGL
|
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||||
*/
|
*/
|
||||||
public class Rendertarget {
|
public class Rendertarget {
|
||||||
public final int width;
|
/** The dimensions. */
|
||||||
public final int height;
|
public final int width, height;
|
||||||
|
|
||||||
|
/** The FBO ID. */
|
||||||
private final int fboID;
|
private final int fboID;
|
||||||
|
|
||||||
|
/** The texture ID. */
|
||||||
private final int textureID;
|
private final int textureID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new FBO
|
* Create a new FBO.
|
||||||
*
|
* @param width the width
|
||||||
* @param width
|
* @param height the height
|
||||||
* @param height
|
|
||||||
*/
|
*/
|
||||||
private Rendertarget(int width, int height)
|
private Rendertarget(int width, int height) {
|
||||||
{
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
fboID = GL30.glGenFramebuffers();
|
fboID = GL30.glGenFramebuffers();
|
||||||
|
@ -50,38 +53,41 @@ public class Rendertarget {
|
||||||
/**
|
/**
|
||||||
* Bind this rendertarget as the primary framebuffer.
|
* Bind this rendertarget as the primary framebuffer.
|
||||||
*/
|
*/
|
||||||
public void bind()
|
public void bind() {
|
||||||
{
|
|
||||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, fboID);
|
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, fboID);
|
||||||
}
|
}
|
||||||
|
|
||||||
//use judiciously, try to avoid if possible and consider adding a method to
|
/**
|
||||||
//this class if you find yourself calling this repeatedly
|
* Returns the FBO ID.
|
||||||
public int getID()
|
*/
|
||||||
{
|
// NOTE: use judiciously, try to avoid if possible and consider adding a
|
||||||
|
// method to this class if you find yourself calling this repeatedly.
|
||||||
|
public int getID() {
|
||||||
return fboID;
|
return fboID;
|
||||||
}
|
}
|
||||||
|
|
||||||
//try not to use, could be moved into seperate class
|
/**
|
||||||
public int getTextureID()
|
* Returns the texture ID.
|
||||||
{
|
*/
|
||||||
|
// NOTE: try not to use, could be moved into separate class.
|
||||||
|
public int getTextureID() {
|
||||||
return textureID;
|
return textureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind the default framebuffer
|
* Bind the default framebuffer.
|
||||||
*/
|
*/
|
||||||
public static void unbind()
|
public static void unbind() {
|
||||||
{
|
|
||||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, 0);
|
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Rendertarget with a Texture that it renders the color buffer in
|
* Creates a Rendertarget with a Texture that it renders the color buffer in
|
||||||
* and a renderbuffer that it renders the depth to.
|
* and a renderbuffer that it renders the depth to.
|
||||||
|
* @param width the width
|
||||||
|
* @param height the height
|
||||||
*/
|
*/
|
||||||
public static Rendertarget createRTTFramebuffer(int width, int height)
|
public static Rendertarget createRTTFramebuffer(int width, int height) {
|
||||||
{
|
|
||||||
int old_framebuffer = GL11.glGetInteger(GL30.GL_READ_FRAMEBUFFER_BINDING);
|
int old_framebuffer = GL11.glGetInteger(GL30.GL_READ_FRAMEBUFFER_BINDING);
|
||||||
int old_texture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
|
int old_texture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
|
||||||
Rendertarget buffer = new Rendertarget(width,height);
|
Rendertarget buffer = new Rendertarget(width,height);
|
||||||
|
@ -104,7 +110,6 @@ public class Rendertarget {
|
||||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, old_texture);
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, old_texture);
|
||||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, old_framebuffer);
|
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, old_framebuffer);
|
||||||
|
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ public class Skin {
|
||||||
|
|
||||||
/** Slider styles. */
|
/** Slider styles. */
|
||||||
public static final byte
|
public static final byte
|
||||||
STYLE_PEPPYSLIDER = 1,
|
STYLE_PEPPYSLIDER = 1, // fallback
|
||||||
STYLE_MMSLIDER = 2,
|
STYLE_MMSLIDER = 2, // default (requires OpenGL 3.0)
|
||||||
STYLE_TOONSLIDER = 3,
|
STYLE_TOONSLIDER = 3, // not implemented
|
||||||
STYLE_OPENGLSLIDER = 4;
|
STYLE_OPENGLSLIDER = 4; // not implemented
|
||||||
|
|
||||||
/** The latest skin version. */
|
/** The latest skin version. */
|
||||||
protected static final int LATEST_VERSION = 2;
|
protected static final int LATEST_VERSION = 2;
|
||||||
|
@ -133,7 +133,7 @@ public class Skin {
|
||||||
protected boolean comboBurstRandom = false;
|
protected boolean comboBurstRandom = false;
|
||||||
|
|
||||||
/** The slider style to use (see STYLE_* constants). */
|
/** The slider style to use (see STYLE_* constants). */
|
||||||
protected byte sliderStyle = 2;
|
protected byte sliderStyle = STYLE_MMSLIDER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Colours]
|
* [Colours]
|
||||||
|
|
|
@ -31,8 +31,8 @@ import itdelatrisu.opsu.audio.MusicController;
|
||||||
import itdelatrisu.opsu.audio.SoundController;
|
import itdelatrisu.opsu.audio.SoundController;
|
||||||
import itdelatrisu.opsu.audio.SoundEffect;
|
import itdelatrisu.opsu.audio.SoundEffect;
|
||||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||||
import itdelatrisu.opsu.beatmap.HitObject;
|
|
||||||
import itdelatrisu.opsu.beatmap.BeatmapParser;
|
import itdelatrisu.opsu.beatmap.BeatmapParser;
|
||||||
|
import itdelatrisu.opsu.beatmap.HitObject;
|
||||||
import itdelatrisu.opsu.beatmap.TimingPoint;
|
import itdelatrisu.opsu.beatmap.TimingPoint;
|
||||||
import itdelatrisu.opsu.db.BeatmapDB;
|
import itdelatrisu.opsu.db.BeatmapDB;
|
||||||
import itdelatrisu.opsu.db.ScoreDB;
|
import itdelatrisu.opsu.db.ScoreDB;
|
||||||
|
|
|
@ -59,8 +59,7 @@ public class OptionsMenu extends BasicGameState {
|
||||||
GameOption.SCREENSHOT_FORMAT,
|
GameOption.SCREENSHOT_FORMAT,
|
||||||
GameOption.NEW_CURSOR,
|
GameOption.NEW_CURSOR,
|
||||||
GameOption.DYNAMIC_BACKGROUND,
|
GameOption.DYNAMIC_BACKGROUND,
|
||||||
GameOption.LOAD_VERBOSE,
|
GameOption.LOAD_VERBOSE
|
||||||
GameOption.NEW_SLIDER
|
|
||||||
}),
|
}),
|
||||||
MUSIC ("Music", new GameOption[] {
|
MUSIC ("Music", new GameOption[] {
|
||||||
GameOption.MASTER_VOLUME,
|
GameOption.MASTER_VOLUME,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user