diff --git a/src/awlex/ospu/FakeGameObject.java b/src/awlex/ospu/FakeGameObject.java
index cfb701ee..b746b023 100644
--- a/src/awlex/ospu/FakeGameObject.java
+++ b/src/awlex/ospu/FakeGameObject.java
@@ -101,4 +101,9 @@ public class FakeGameObject extends GameObject {
public void setTime(int time) {
this.halfTime = time;
}
+
+ @Override
+ public void updateColor() {
+ }
+
}
\ No newline at end of file
diff --git a/src/itdelatrisu/opsu/Container.java b/src/itdelatrisu/opsu/Container.java
index 0be55d73..e5d6c234 100644
--- a/src/itdelatrisu/opsu/Container.java
+++ b/src/itdelatrisu/opsu/Container.java
@@ -62,6 +62,8 @@ public class Container extends AppGameContainer {
getDelta();
while (running())
gameLoop();
+ } catch(Exception e) {
+ e.printStackTrace();
} finally {
// destroy the game container
close_sub();
diff --git a/src/itdelatrisu/opsu/objects/Circle.java b/src/itdelatrisu/opsu/objects/Circle.java
index 684c644a..44718a38 100644
--- a/src/itdelatrisu/opsu/objects/Circle.java
+++ b/src/itdelatrisu/opsu/objects/Circle.java
@@ -60,6 +60,8 @@ public class Circle extends GameObject {
/** Whether or not the circle result ends the combo streak. */
private boolean comboEnd;
+ private int comboColorIndex;
+
/**
* Initializes the Circle data type with map modifiers, images, and dimensions.
* @param container the game container
@@ -86,9 +88,9 @@ public class Circle extends GameObject {
this.game = game;
this.data = data;
this.comboEnd = comboEnd;
+ this.comboColorIndex = comboColorIndex;
+ updateColor();
updatePosition();
- color = Dancer.colorOverride.getColor(comboColorIndex);
- mirrorColor = Dancer.colorMirrorOverride.getColor(comboColorIndex);
}
public Circle(float x, float y, int time) {
@@ -265,4 +267,10 @@ public class Circle extends GameObject {
return mirrorColor;
}
+ @Override
+ public void updateColor() {
+ color = Dancer.colorOverride.getColor(comboColorIndex);
+ mirrorColor = Dancer.colorMirrorOverride.getColor(comboColorIndex);
+ }
+
}
diff --git a/src/itdelatrisu/opsu/objects/DummyObject.java b/src/itdelatrisu/opsu/objects/DummyObject.java
index ce5adebd..f545d501 100644
--- a/src/itdelatrisu/opsu/objects/DummyObject.java
+++ b/src/itdelatrisu/opsu/objects/DummyObject.java
@@ -100,4 +100,8 @@ public class DummyObject extends GameObject {
return null;
}
+ @Override
+ public void updateColor() {
+ }
+
}
diff --git a/src/itdelatrisu/opsu/objects/GameObject.java b/src/itdelatrisu/opsu/objects/GameObject.java
index 1f9f49dd..b819ac32 100644
--- a/src/itdelatrisu/opsu/objects/GameObject.java
+++ b/src/itdelatrisu/opsu/objects/GameObject.java
@@ -101,4 +101,6 @@ public abstract class GameObject {
public abstract Color getColor();
public abstract Color getMirroredColor();
+ public abstract void updateColor();
+
}
diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java
index 5700713c..b71cb234 100644
--- a/src/itdelatrisu/opsu/objects/Slider.java
+++ b/src/itdelatrisu/opsu/objects/Slider.java
@@ -117,6 +117,8 @@ public class Slider extends GameObject {
public float pixelLength;
+ private int comboColorIndex;
+
/**
* Initializes the Slider data type with images and dimensions.
* @param container the game container
@@ -162,8 +164,8 @@ public class Slider extends GameObject {
this.game = game;
this.data = data;
this.comboEnd = comboEnd;
- color = Dancer.colorOverride.getColor(comboColorIndex);
- mirrorColor = Dancer.colorMirrorOverride.getColor(comboColorIndex);
+ this.comboColorIndex = comboColorIndex;
+ updateColor();
updatePosition();
this.pixelLength = hitObject.getPixelLength();
@@ -710,4 +712,10 @@ public class Slider extends GameObject {
return ticks;
}
+ @Override
+ public void updateColor() {
+ color = Dancer.colorOverride.getColor(comboColorIndex);
+ mirrorColor = Dancer.colorMirrorOverride.getColor(comboColorIndex);
+ }
+
}
diff --git a/src/itdelatrisu/opsu/objects/Spinner.java b/src/itdelatrisu/opsu/objects/Spinner.java
index 251f4e0d..e507e080 100644
--- a/src/itdelatrisu/opsu/objects/Spinner.java
+++ b/src/itdelatrisu/opsu/objects/Spinner.java
@@ -438,4 +438,7 @@ public class Spinner extends GameObject {
return null;
}
+ @Override
+ public void updateColor() {
+ }
}
diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java
index 03b4eb4b..3c8364df 100644
--- a/src/itdelatrisu/opsu/states/Game.java
+++ b/src/itdelatrisu/opsu/states/Game.java
@@ -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.ui.SBOverlay;
/**
* "Game" state.
@@ -271,10 +272,59 @@ public class Game extends BasicGameState {
private final int state;
private final Cursor mirrorCursor;
+ private final SBOverlay sbOverlay;
public Game(int state) {
this.state = state;
mirrorCursor = new Cursor(true);
+ sbOverlay = new SBOverlay(this);
+ }
+
+ public void setObjectIndex(int newObjIndex) {
+ try {
+ /*
+
+ restart = Restart.MANUAL;
+ enter(container, game);
+ checkpointLoaded = true;
+ if (isLeadIn()) {
+ leadInTime = 0;
+ MusicController.resume();
+ }
+ SoundController.playSound(SoundEffect.MENUHIT);
+ UI.sendBarNotification("Checkpoint loaded.");
+
+ // skip to checkpoint
+ MusicController.setPosition(checkpoint);
+ MusicController.setPitch(GameMod.getSpeedMultiplier() * playbackSpeed.getModifier());
+ while (objectIndex < gameObjects.length &&
+ beatmap.objects[objectIndex++].getTime() <= checkpoint)
+ ;
+ objectIndex--;
+ lastReplayTime = beatmap.objects[objectIndex].getTime();
+ } catch (SlickException e) {
+ ErrorHandler.error("Failed to load checkpoint.", e, false);
+ }
+ */
+ restart = Restart.MANUAL;
+ enter(container, game);
+ checkpointLoaded = true;
+ if (isLeadIn()) {
+ leadInTime = 0;
+ MusicController.resume();
+ }
+ int checkpoint = gameObjects[newObjIndex].getTime();
+ // skip to checkpoint
+ MusicController.setPosition(checkpoint);
+ while (objectIndex < gameObjects.length && beatmap.objects[objectIndex].getTime() <= checkpoint) {
+ objectIndex++;
+ }
+ objectIndex--;
+ sbOverlay.updateIndex(objectIndex);
+ lastReplayTime = beatmap.objects[objectIndex].getTime();
+ } catch (SlickException e) {
+ e.printStackTrace();
+ }
}
@Override
@@ -287,6 +337,8 @@ public class Game extends BasicGameState {
int width = container.getWidth();
int height = container.getHeight();
+ sbOverlay.init(container, input, width, height);
+
// create offscreen graphics
offscreen = new Image(width, height);
gOffscreen = offscreen.getGraphics();
@@ -635,6 +687,8 @@ public class Game extends BasicGameState {
else
UI.draw(g);
+ sbOverlay.render(container, game, g);
+
if (!Dancer.hidewatermark) {
Fonts.SMALL.drawString(0.3f, 0.3f, "opsu!dance " + Updater.get().getCurrentVersion() + " by robin_be | https://github.com/yugecin/opsu-dance");
}
@@ -647,6 +701,7 @@ public class Game extends BasicGameState {
Pippi.update(delta);
yugecin.opsudance.spinners.Spinner.update(delta);
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
+ sbOverlay.update(mouseX, mouseY);
skipButton.hoverUpdate(delta, mouseX, mouseY);
if (isReplay || GameMod.AUTO.isActive())
playbackSpeed.getButton().hoverUpdate(delta, mouseX, mouseY);
@@ -910,6 +965,7 @@ public class Game extends BasicGameState {
// update hit object and check completion status
if (gameObjects[objectIndex].update(overlap, delta, mouseX, mouseY, keyPressed, trackPosition)) {
objectIndex++; // done, so increment object index
+ sbOverlay.updateIndex(objectIndex);
if (objectIndex >= mirrorTo) {
Dancer.mirror = false;
}
@@ -924,6 +980,11 @@ public class Game extends BasicGameState {
@Override
public void keyPressed(int key, char c) {
+
+ if (sbOverlay.keyPressed(key, c)) {
+ return;
+ }
+
int trackPosition = MusicController.getPosition();
int mouseX = input.getMouseX();
int mouseY = input.getMouseY();
@@ -1064,8 +1125,16 @@ public class Game extends BasicGameState {
}
}
+ @Override
+ public void mouseDragged(int oldx, int oldy, int newx, int newy) {
+ sbOverlay.mouseDragged(oldx, oldy, newx, newy);
+ }
+
@Override
public void mousePressed(int button, int x, int y) {
+ if (sbOverlay.mousePressed(button, x, y)) {
+ return;
+ }
// watching replay
if (isReplay || GameMod.AUTO.isActive()) {
if (button == Input.MOUSE_MIDDLE_BUTTON)
@@ -1158,6 +1227,10 @@ public class Game extends BasicGameState {
@Override
public void mouseReleased(int button, int x, int y) {
+ if (sbOverlay.mouseReleased(button, x, y)) {
+ return;
+ }
+
if (Options.isMouseDisabled())
return;
@@ -1200,6 +1273,9 @@ public class Game extends BasicGameState {
@Override
public void mouseWheelMoved(int newValue) {
+ if (sbOverlay.mouseWheelMoved(newValue)) {
+ return;
+ }
if (Options.isMouseWheelDisabled() || Options.isMouseDisabled())
return;
@@ -1228,6 +1304,7 @@ public class Game extends BasicGameState {
// grab the mouse (not working for touchscreen)
// container.setMouseGrabbed(true);
+
// restart the game
if (restart != Restart.FALSE) {
// load mods
@@ -1369,6 +1446,13 @@ public class Game extends BasicGameState {
SoundController.mute(false);
}
+
+ sbOverlay.setGameObjects(gameObjects);
+ if (!checkpointLoaded) {
+ sbOverlay.enter();
+ sbOverlay.updateIndex(0);
+ }
+
Pippi.reset();
mirrorFrom = 0;
mirrorTo = gameObjects.length;
@@ -1384,6 +1468,8 @@ public class Game extends BasicGameState {
throws SlickException {
// container.setMouseGrabbed(false);
+ sbOverlay.leave();
+
Cursor.lastObjColor = Color.white;
Cursor.lastMirroredObjColor = Color.white;
diff --git a/src/yugecin/opsudance/ui/OptionsOverlay.java b/src/yugecin/opsudance/ui/OptionsOverlay.java
new file mode 100644
index 00000000..7a2bd82c
--- /dev/null
+++ b/src/yugecin/opsudance/ui/OptionsOverlay.java
@@ -0,0 +1,212 @@
+/*
+ * 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.ui;
+
+import itdelatrisu.opsu.Options;
+import itdelatrisu.opsu.ui.Colors;
+import itdelatrisu.opsu.ui.Fonts;
+import org.newdawn.slick.Color;
+import org.newdawn.slick.GameContainer;
+import org.newdawn.slick.Graphics;
+import org.newdawn.slick.Input;
+import org.newdawn.slick.state.StateBasedGame;
+
+import java.util.Observable;
+import java.util.Observer;
+
+public class OptionsOverlay {
+
+ private int width;
+ private int height;
+
+ private static Options.GameOption[] options = new Options.GameOption[] {
+ Options.GameOption.DANCE_MOVER,
+ Options.GameOption.DANCE_MOVER_DIRECTION,
+ Options.GameOption.DANCE_SLIDER_MOVER_TYPE,
+ Options.GameOption.DANCE_SPINNER,
+ Options.GameOption.DANCE_SPINNER_DELAY,
+ Options.GameOption.DANCE_LAZY_SLIDERS,
+ Options.GameOption.DANCE_CIRCLE_STREAMS,
+ Options.GameOption.DANCE_ONLY_CIRCLE_STACKS,
+ Options.GameOption.DANCE_CIRLCE_IN_SLOW_SLIDERS,
+ Options.GameOption.DANCE_CIRLCE_IN_LAZY_SLIDERS,
+ Options.GameOption.DANCE_MIRROR,
+ Options.GameOption.DANCE_DRAW_APPROACH,
+ Options.GameOption.DANCE_OBJECT_COLOR_OVERRIDE,
+ Options.GameOption.DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED,
+ Options.GameOption.DANCE_RGB_OBJECT_INC,
+ Options.GameOption.DANCE_CURSOR_COLOR_OVERRIDE,
+ Options.GameOption.DANCE_CURSOR_MIRROR_COLOR_OVERRIDE,
+ Options.GameOption.DANCE_CURSOR_ONLY_COLOR_TRAIL,
+ Options.GameOption.DANCE_RGB_CURSOR_INC,
+ Options.GameOption.DANCE_CURSOR_TRAIL_OVERRIDE,
+ Options.GameOption.DANCE_REMOVE_BG,
+ Options.GameOption.DANCE_HIDE_OBJECTS,
+ Options.GameOption.DANCE_HIDE_UI,
+ Options.GameOption.PIPPI_ENABLE,
+ Options.GameOption.PIPPI_ANGLE_INC_MUL,
+ Options.GameOption.PIPPI_ANGLE_INC_MUL_SLIDER,
+ Options.GameOption.PIPPI_SLIDER_FOLLOW_EXPAND,
+ Options.GameOption.PIPPI_PREVENT_WOBBLY_STREAMS,
+ };
+
+ private int textHeight;
+ private Input input;
+ private final ItemList list;
+ private GameContainer container;
+ private Options.GameOption selectedOption;
+ private final SBOverlay overlay;
+
+ public OptionsOverlay(SBOverlay overlay) {
+ this.overlay = overlay;
+ list = new ItemList();
+ }
+
+ public Options.GameOption[] getSavedOptionList() {
+ return options;
+ }
+
+ public void init(GameContainer container, Input input, int width, int height) {
+ list.init(container);
+ this.input = input;
+ this.width = width;
+ this.height = height;
+ this.container = container;
+ textHeight = Fonts.SMALL.getLineHeight();
+ }
+
+ public void render(GameContainer container, StateBasedGame game, Graphics g) {
+ int hoverIdx = getOptionIdxAt(input.getMouseY());
+ float a = Color.black.a;
+ Color.black.a = 0.8f;
+ g.setColor(Color.black);
+ g.fillRect(0, 0, width, height);
+ Color.black.a = a;
+ for (int i = 0; i < options.length; i++) {
+ drawOption(g, options[i], i, selectedOption == null ? hoverIdx == i : selectedOption == options[i]);
+ }
+ if (list.isVisible()) {
+ list.render(container, game, g);
+ }
+ }
+
+ // I know... kill me
+ private void drawOption(Graphics g, Options.GameOption option, int pos, boolean focus) {
+ float y = pos * (textHeight + 5);
+ Color color = (focus) ? Color.cyan : Color.white;
+
+ Fonts.MEDIUM.drawString(width / 6 * 2, y, option.getName(), color);
+ Fonts.MEDIUM.drawString(width / 3 * 2, y, option.getValueString(), color);
+ g.setColor(Colors.WHITE_ALPHA);
+ g.drawLine(0, y + textHeight + 3, width, y + textHeight + 3 + 1);
+ }
+
+ private int getOptionIdxAt(int y) {
+ int index = y / (textHeight + 5);
+ if (index >= options.length) {
+ return -1;
+ }
+ return index;
+ }
+
+ public void update(int mouseX, int mouseY) {
+
+ }
+
+ public boolean mousePressed(int button, int x, int y) {
+ if (list.isVisible()) {
+ list.mousePressed(button, x, y);
+ return true;
+ }
+ int idx = getOptionIdxAt(y);
+ if (idx < options.length) {
+ final Options.GameOption option = options[idx];
+ selectedOption = option;
+ Object[] listItems = option.getListItems();
+ if (listItems == null) {
+ option.click(container);
+ } else {
+ list.setItems(listItems);
+ list.setClickListener(new Observer() {
+ @Override
+ public void update(Observable o, Object arg) {
+ option.clickListItem((int) arg);
+ overlay.saveOption(option);
+ }
+ });
+ list.show();
+ }
+ }
+ return true;
+ }
+
+
+ public void mouseDragged(int oldx, int oldy, int newx, int newy) {
+ if (list.isVisible()) {
+ list.mouseDragged(oldx, oldy, newx, newy);
+ return;
+ }
+
+ int multiplier;
+ if (input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON))
+ multiplier = 4;
+ else if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))
+ multiplier = 1;
+ else
+ return;
+
+ // get direction
+ int diff = newx - oldx;
+ if (diff == 0)
+ return;
+ diff = ((diff > 0) ? 1 : -1) * multiplier;
+
+ // options (drag only)
+ if (selectedOption != null) {
+ selectedOption.drag(container, diff);
+ }
+ }
+
+ public boolean mouseReleased(int button, int x, int y) {
+ if (selectedOption != null) {
+ overlay.saveOption(selectedOption);
+ }
+ selectedOption = null;
+ if (list.isVisible()) {
+ list.mouseReleased(button, x, y);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean mouseWheenMoved(int newValue) {
+ if (list.isVisible()) {
+ list.mouseWheelMoved(newValue);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean keyPressed(int key, char c) {
+ if (list.isVisible()) {
+ list.keyPressed(key, c);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/yugecin/opsudance/ui/SBOverlay.java b/src/yugecin/opsudance/ui/SBOverlay.java
new file mode 100644
index 00000000..63a434ed
--- /dev/null
+++ b/src/yugecin/opsudance/ui/SBOverlay.java
@@ -0,0 +1,237 @@
+/*
+ * 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.ui;
+
+import itdelatrisu.opsu.Options;
+import itdelatrisu.opsu.audio.MusicController;
+import itdelatrisu.opsu.objects.GameObject;
+import itdelatrisu.opsu.states.Game;
+import itdelatrisu.opsu.ui.Fonts;
+import org.newdawn.slick.Color;
+import org.newdawn.slick.GameContainer;
+import org.newdawn.slick.Graphics;
+import org.newdawn.slick.Input;
+import org.newdawn.slick.state.StateBasedGame;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@SuppressWarnings("unchecked")
+public class SBOverlay {
+
+ public static boolean isActive = true;
+
+ private boolean hide;
+ private boolean menu;
+
+ private int width;
+ private int height;
+
+ private int speed;
+ private GameObject[] gameObjects;
+ private HashMap[] optionsMap;
+ private HashMap initialOptions;
+
+ private int index;
+
+ private final Game game;
+ private final OptionsOverlay options;
+
+ public SBOverlay(Game game) {
+ this.game = game;
+ options = new OptionsOverlay(this);
+ initialOptions = new HashMap<>();
+ }
+
+ public void init(GameContainer container, Input input, int width, int height) {
+ this.width = width;
+ this.height = height;
+ speed = 10;
+ gameObjects = new GameObject[0];
+ options.init(container, input, width, height);
+ }
+
+ public void render(GameContainer container, StateBasedGame game, Graphics g) {
+ if (!isActive || hide) {
+ return;
+ }
+ int lh = Fonts.SMALL.getLineHeight();
+ Fonts.SMALL.drawString(10, height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan);
+ Fonts.SMALL.drawString(10, height - 50 - lh, "Menu: N", Color.cyan);
+ Fonts.SMALL.drawString(10, height - 50 - lh * 2, "HIDE: H", Color.cyan);
+ Fonts.SMALL.drawString(10, height - 50 - lh * 3, "obj: J " + index + " K", Color.cyan);
+ if (index < optionsMap.length && optionsMap[index] != null) {
+ int i = 0;
+ for (Object o : optionsMap[index].entrySet()) {
+ Map.Entry option = (Map.Entry) o;
+ Fonts.SMALL.drawString(10, 50 + i * lh, option.getKey().getDisplayName(), Color.cyan);
+ }
+ }
+ if (menu) {
+ options.render(container, game, g);
+ }
+ }
+
+ public void update(int mouseX, int mouseY) {
+ if (!isActive) {
+ return;
+ }
+ if (menu) {
+ options.update(mouseX, mouseY);
+ }
+ }
+
+ public boolean keyPressed(int key, char c) {
+ if (!isActive) {
+ return false;
+ }
+ if (options.keyPressed(key, c)) {
+ return true;
+ }
+ if (key == Input.KEY_C && speed > 0) {
+ speed -= 1;
+ if (speed == 0) {
+ MusicController.pause();
+ } else {
+ MusicController.setPitch(speed / 10f);
+ }
+ } else if (key == Input.KEY_V && speed < 21) {
+ if (speed == 0) {
+ MusicController.resume();
+ }
+ speed += 1;
+ MusicController.setPitch(speed / 10f);
+ } else if (key == Input.KEY_H) {
+ hide = !hide;
+ } else if (key == Input.KEY_N) {
+ menu = !menu;
+ if (menu && speed != 0) {
+ MusicController.pause();
+ } else if (!menu && speed != 0) {
+ MusicController.resume();
+ }
+ } else if (key == Input.KEY_J && index > 0) {
+ index--;
+ setMusicPosition();
+ goBackOneSBIndex();
+ } else if (key == Input.KEY_K && index < gameObjects.length - 1) {
+ index++;
+ setMusicPosition();
+ updateIndex(index);
+ } else if (key == Input.KEY_ESCAPE && menu) {
+ menu = false;
+ if (speed != 0) {
+ MusicController.resume();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void goBackOneSBIndex() {
+ if (optionsMap[index + 1] != null) {
+ // new options on previous index, so to revert then we have to reload them all to this point..
+ final int thisIndex = index;
+ for (int i = 0; i <= thisIndex; i++) {
+ updateIndex(thisIndex);
+ }
+ }
+ }
+
+ private void setMusicPosition() {
+ game.setObjectIndex(index);
+ if (speed != 0) {
+ MusicController.setPitch(speed / 10f);
+ MusicController.resume();
+ } else {
+ MusicController.pause();
+ }
+ }
+
+ public void setGameObjects(GameObject[] gameObjects) {
+ if (this.gameObjects.length != gameObjects.length) {
+ optionsMap = new HashMap[gameObjects.length];
+ }
+ this.gameObjects = gameObjects;
+ }
+
+ public void saveOption(Options.GameOption option) {
+ if (optionsMap[index] == null) {
+ optionsMap[index] = new HashMap<>();
+ }
+ optionsMap[index].put(option, option.write());
+ }
+
+ public boolean mousePressed(int button, int x, int y) {
+ return menu && options.mousePressed(button, x, y);
+ }
+
+ public void mouseDragged(int oldx, int oldy, int newx, int newy) {
+ if (menu) options.mouseDragged(oldx, oldy, newx, newy);
+ }
+
+ public void updateIndex(int index) {
+ this.index = index;
+ if (index >= optionsMap.length) {
+ return;
+ }
+ HashMap options = optionsMap[index];
+ if (options != null) {
+ for (Object o : options.entrySet()) {
+ Map.Entry next = (Map.Entry) o;
+ next.getKey().read(next.getValue());
+ readOption(next.getKey());
+ }
+ }
+ }
+
+ public boolean mouseReleased(int button, int x, int y) {
+ return menu && options.mouseReleased(button, x, y);
+ }
+
+ public boolean mouseWheelMoved(int newValue) {
+ return menu && options.mouseWheenMoved(newValue);
+ }
+
+ public void enter() {
+ // enter, save current settings
+ for (Options.GameOption o : options.getSavedOptionList()) {
+ initialOptions.put(o, o.write());
+ }
+ }
+
+ public void leave() {
+ // leave, revert the settings saved before entering
+ for (Options.GameOption o : options.getSavedOptionList()) {
+ if (initialOptions.containsKey(o)) {
+ o.read(initialOptions.get(o));
+ readOption(o);
+ }
+ }
+ }
+
+ // needed for object color overrides...
+ private void readOption(Options.GameOption o) {
+ if (o == Options.GameOption.DANCE_OBJECT_COLOR_OVERRIDE || o == Options.GameOption.DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED) {
+ for (int i = index; i < gameObjects.length; i++) {
+ gameObjects[i].updateColor();
+ }
+ }
+ }
+
+}