diff --git a/src/itdelatrisu/opsu/options/OptionGroup.java b/src/itdelatrisu/opsu/options/OptionGroup.java index 6fbc897e..07a3e244 100644 --- a/src/itdelatrisu/opsu/options/OptionGroup.java +++ b/src/itdelatrisu/opsu/options/OptionGroup.java @@ -97,6 +97,7 @@ public class OptionGroup { GameOption.FIXED_HP, GameOption.FIXED_AR, GameOption.FIXED_OD, + GameOption.FIXED_SPEED, }), new OptionGroup("SEEKING", new GameOption[] { GameOption.CHECKPOINT, diff --git a/src/itdelatrisu/opsu/options/Options.java b/src/itdelatrisu/opsu/options/Options.java index 2b54b51a..cb38bee9 100644 --- a/src/itdelatrisu/opsu/options/Options.java +++ b/src/itdelatrisu/opsu/options/Options.java @@ -499,7 +499,7 @@ public void read(String s) { @Override public void read(String s) { int i = (int) (Float.parseFloat(s) * 100f); - if (i >= 50 && i <= 200) + if (i >= getMinValue() && i <= getMaxValue()) val = i; } }, @@ -571,7 +571,7 @@ public void setValue(int value) { @Override public void read(String s) { int i = (int) (Float.parseFloat(s) * 10f); - if (i >= 0 && i <= 100) + if (i >= getMinValue() && i <= getMaxValue()) val = i; } }, @@ -585,7 +585,7 @@ public void read(String s) { @Override public void read(String s) { int i = (int) (Float.parseFloat(s) * 10f); - if (i >= 0 && i <= 100) + if (i >= getMinValue() && i <= getMaxValue()) val = i; } }, @@ -599,7 +599,7 @@ public void read(String s) { @Override public void read(String s) { int i = (int) (Float.parseFloat(s) * 10f); - if (i >= 0 && i <= 100) + if (i >= getMinValue() && i <= getMaxValue()) val = i; } }, @@ -613,7 +613,21 @@ public void read(String s) { @Override public void read(String s) { int i = (int) (Float.parseFloat(s) * 10f); - if (i >= 0 && i <= 100) + if (i >= getMinValue() && i <= getMaxValue()) + val = i; + } + }, + FIXED_SPEED ("Fixed speed", "FixedSpeed", "Determines the speed of the music.", 0, 0, 300) { + @Override + public String getValueString() { return (val == 0) ? "Disabled" : String.format("%.2fx", val / 100f); } + + @Override + public String write() { return String.format(Locale.US, "%.2f", val / 100f); } + + @Override + public void read(String s) { + int i = (int) (Float.parseFloat(s) * 100f); + if (i >= getMinValue() && i <= getMaxValue()) val = i; } }, @@ -1165,6 +1179,12 @@ public static void setDisplayMode(Container app) { */ public static float getFixedOD() { return GameOption.FIXED_OD.getIntegerValue() / 10f; } + /** + * Returns the fixed speed override, if any. + * @return the speed value (0, 3], 0f if disabled + */ + public static float getFixedSpeed() { return GameOption.FIXED_SPEED.getIntegerValue() / 100f; } + /** * Returns whether or not to render loading text in the splash screen. * @return true if enabled diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 77a51c31..2b891299 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1194,7 +1194,7 @@ else if (key == Options.getGameKeyRight()) // skip to checkpoint MusicController.setPosition(checkpoint); - MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier()); + MusicController.setPitch(getCurrentPitch()); if (video != null) loadVideo(checkpoint); while (objectIndex < gameObjects.length && @@ -1214,7 +1214,7 @@ else if (key == Options.getGameKeyRight()) break; if (isReplay || GameMod.AUTO.isActive()) { playbackSpeed = playbackSpeed.next(); - MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier()); + MusicController.setPitch(getCurrentPitch()); } break; case Input.KEY_UP: @@ -1257,7 +1257,7 @@ public void mousePressed(int button, int x, int y) { // playback speed button else if (playbackSpeed.getButton().contains(x, y)) { playbackSpeed = playbackSpeed.next(); - MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier()); + MusicController.setPitch(getCurrentPitch()); } // replay seeking @@ -1568,6 +1568,11 @@ else if (hitObject.isSpinner()) if (beatmap.localMusicOffset != 0) UI.getNotificationManager().sendBarNotification(String.format("Using local beatmap offset (%dms)", beatmap.localMusicOffset)); + // using custom difficulty settings? + if (Options.getFixedCS() > 0f || Options.getFixedAR() > 0f || Options.getFixedOD() > 0f || + Options.getFixedHP() > 0f || Options.getFixedSpeed() > 0f) + UI.getNotificationManager().sendNotification("Playing with custom difficulty settings."); + // load video if (beatmap.video != null) { loadVideo((beatmap.videoOffset < 0) ? -beatmap.videoOffset : 0); @@ -1584,7 +1589,7 @@ else if (hitObject.isSpinner()) skipButton.resetHover(); if (isReplay || GameMod.AUTO.isActive()) playbackSpeed.getButton().resetHover(); - MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier()); + MusicController.setPitch(getCurrentPitch()); } @Override @@ -1821,7 +1826,7 @@ private synchronized boolean skipIntro() { MusicController.resume(); } MusicController.setPosition(firstObjectTime - SKIP_OFFSET); - MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier()); + MusicController.setPitch(getCurrentPitch()); replaySkipTime = (isReplay) ? -1 : trackPosition; if (isReplay) { replayX = (int) skipButton.getX(); @@ -2290,6 +2295,12 @@ private boolean hasMoreObjects() { return objectIndex < gameObjects.length || !passedObjects.isEmpty(); } + /** Returns the current pitch. */ + private float getCurrentPitch() { + float base = (Options.getFixedSpeed() > 0f) ? Options.getFixedSpeed() : 1f; + return base * GameMod.getSpeedMultiplier() * playbackSpeed.getModifier(); + } + /** * Returns true if the coordinates are within the music position bar bounds. * @param cx the x coordinate