refactor options
This commit is contained in:
304
src/yugecin/opsudance/options/Configuration.java
Normal file
304
src/yugecin/opsudance/options/Configuration.java
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import com.sun.jna.platform.win32.Advapi32Util;
|
||||
import com.sun.jna.platform.win32.Win32Exception;
|
||||
import com.sun.jna.platform.win32.WinReg;
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.audio.SoundController;
|
||||
import itdelatrisu.opsu.audio.SoundEffect;
|
||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||
import itdelatrisu.opsu.beatmap.TimingPoint;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import yugecin.opsudance.core.errorhandling.ErrorHandler;
|
||||
import yugecin.opsudance.core.events.EventBus;
|
||||
import yugecin.opsudance.core.inject.Inject;
|
||||
import yugecin.opsudance.events.BubbleNotificationEvent;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static yugecin.opsudance.options.Options.*;
|
||||
|
||||
public class Configuration {
|
||||
|
||||
public final boolean USE_XDG;
|
||||
public final File CONFIG_DIR;
|
||||
public final File DATA_DIR;
|
||||
public final File CACHE_DIR;
|
||||
public final File BEATMAP_DIR;
|
||||
public final File SKIN_ROOT_DIR;
|
||||
public final File BEATMAP_DB;
|
||||
public final File SCORE_DB;
|
||||
public final File NATIVE_DIR;
|
||||
public final File TEMP_DIR;
|
||||
|
||||
public final File LOG_FILE;
|
||||
public final File OPTIONS_FILE;
|
||||
|
||||
public final String FONT_NAME;
|
||||
public final String VERSION_FILE;
|
||||
public final URI REPOSITORY_URI;
|
||||
public final URI DANCE_REPOSITORY_URI;
|
||||
public final String ISSUES_URL;
|
||||
public final String VERSION_REMOTE;
|
||||
|
||||
public final File osuInstallationDirectory;
|
||||
|
||||
public final Beatmap themeBeatmap;
|
||||
|
||||
public File beatmapDir;
|
||||
public File oszDir;
|
||||
public File screenshotDir;
|
||||
public File replayDir;
|
||||
public File replayImportDir;
|
||||
public File skinRootDir;
|
||||
|
||||
@Inject
|
||||
public Configuration() {
|
||||
USE_XDG = areXDGDirectoriesEnabled();
|
||||
|
||||
CONFIG_DIR = getXDGBaseDir("XDG_CONFIG_HOME", ".config");
|
||||
DATA_DIR = getXDGBaseDir("XDG_DATA_HOME", ".local/share");
|
||||
CACHE_DIR = getXDGBaseDir("XDG_CACHE_HOME", ".cache");
|
||||
|
||||
BEATMAP_DIR = new File(DATA_DIR, "Songs/");
|
||||
SKIN_ROOT_DIR = new File(DATA_DIR, "Skins/");
|
||||
BEATMAP_DB = new File(DATA_DIR, ".opsu.db");
|
||||
SCORE_DB = new File(DATA_DIR, ".opsu_scores.db");
|
||||
NATIVE_DIR = new File(CACHE_DIR, "Natives/");
|
||||
TEMP_DIR = new File(CACHE_DIR, "Temp/");
|
||||
|
||||
LOG_FILE = new File(CONFIG_DIR, ".opsu.log");
|
||||
OPTIONS_FILE = new File(CONFIG_DIR, ".opsu.cfg");
|
||||
|
||||
FONT_NAME = "DroidSansFallback.ttf";
|
||||
VERSION_FILE = "version";
|
||||
REPOSITORY_URI = URI.create("https://github.com/itdelatrisu/opsu");
|
||||
DANCE_REPOSITORY_URI = URI.create("https://github.com/yugecin/opsu-dance");
|
||||
ISSUES_URL = "https://github.com/yugecin/opsu-dance/issues/new?title=%s&body=%s";
|
||||
VERSION_REMOTE = "https://raw.githubusercontent.com/yugecin/opsu-dance/master/version";
|
||||
|
||||
osuInstallationDirectory = loadOsuInstallationDirectory();
|
||||
|
||||
themeBeatmap = createThemeBeatmap();
|
||||
}
|
||||
|
||||
private Beatmap createThemeBeatmap() {
|
||||
try {
|
||||
String[] tokens = {"theme.mp3", "Rainbows", "Kevin MacLeod", "219350"};
|
||||
Beatmap beatmap = new Beatmap(null);
|
||||
beatmap.audioFilename = new File(tokens[0]);
|
||||
beatmap.title = tokens[1];
|
||||
beatmap.artist = tokens[2];
|
||||
beatmap.endTime = Integer.parseInt(tokens[3]);
|
||||
beatmap.timingPoints = new ArrayList<>(1);
|
||||
beatmap.timingPoints.add(new TimingPoint("1080,545.454545454545,4,1,0,100,0,0"));
|
||||
return beatmap;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private File loadOsuInstallationDirectory() {
|
||||
if (!System.getProperty("os.name").startsWith("Win")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final WinReg.HKEY rootKey = WinReg.HKEY_CLASSES_ROOT;
|
||||
final String regKey = "osu\\DefaultIcon";
|
||||
final String regValue = null; // default value
|
||||
final String regPathPattern = "\"(.+)\\\\[^\\/]+\\.exe\"";
|
||||
|
||||
String value;
|
||||
try {
|
||||
value = Advapi32Util.registryGetStringValue(rootKey, regKey, regValue);
|
||||
} catch (Win32Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
Pattern pattern = Pattern.compile(regPathPattern);
|
||||
Matcher m = pattern.matcher(value);
|
||||
if (!m.find()) {
|
||||
return null;
|
||||
}
|
||||
File dir = new File(m.group(1));
|
||||
if (dir.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void loadDirectories() {
|
||||
replayImportDir = loadDirectory(replayImportDir, new File(DATA_DIR, "ReplayImport"), "replay import");
|
||||
oszDir = loadDirectory(oszDir, new File(DATA_DIR, "SongPacks"), "song packs");
|
||||
screenshotDir = loadDirectory(screenshotDir, new File(DATA_DIR, "Screenshots"), "screenshots");
|
||||
replayDir = loadDirectory(replayDir, new File(DATA_DIR, "Replays"), "replays");
|
||||
beatmapDir = loadOsuDirectory(beatmapDir, BEATMAP_DIR, "beatmap");
|
||||
skinRootDir = loadOsuDirectory(skinRootDir, SKIN_ROOT_DIR, "skin root");
|
||||
}
|
||||
|
||||
private File loadDirectory(File dir, File defaultDir, String kind) {
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
if (!defaultDir.isDirectory() && !defaultDir.mkdir()) {
|
||||
String msg = String.format("Failed to create %s directory at '%s'.", kind, defaultDir.getAbsolutePath());
|
||||
EventBus.post(new BubbleNotificationEvent(msg, BubbleNotificationEvent.COMMONCOLOR_RED));
|
||||
}
|
||||
return defaultDir;
|
||||
}
|
||||
|
||||
private File loadOsuDirectory(File dir, File defaultDir, String kind) {
|
||||
if (dir != null && dir.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
|
||||
if (osuInstallationDirectory != null) {
|
||||
dir = new File(osuInstallationDirectory, defaultDir.getName());
|
||||
if (dir.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
return loadDirectory(dir, defaultDir, kind);
|
||||
}
|
||||
|
||||
private boolean areXDGDirectoriesEnabled() {
|
||||
JarFile jarFile = Utils.getJarFile();
|
||||
if (jarFile == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Manifest manifest = jarFile.getManifest();
|
||||
if (manifest == null) {
|
||||
return false;
|
||||
}
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
String value = attributes.getValue("Use-XDG");
|
||||
return (value != null && value.equalsIgnoreCase("true"));
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory based on the XDG base directory specification for
|
||||
* Unix-like operating systems, only if the "XDG" flag is enabled.
|
||||
* @param env the environment variable to check (XDG_*_*)
|
||||
* @param fallback the fallback directory relative to ~home
|
||||
* @return the XDG base directory, or the working directory if unavailable
|
||||
*/
|
||||
private File getXDGBaseDir(String env, String fallback) {
|
||||
File workingdir;
|
||||
if (Utils.isJarRunning()) {
|
||||
workingdir = Utils.getRunningDirectory().getParentFile();
|
||||
} else {
|
||||
workingdir = Paths.get(".").toAbsolutePath().normalize().toFile();
|
||||
}
|
||||
|
||||
if (!USE_XDG) {
|
||||
return workingdir;
|
||||
}
|
||||
|
||||
String OS = System.getProperty("os.name").toLowerCase();
|
||||
if (OS.indexOf("nix") == -1 && OS.indexOf("nux") == -1 && OS.indexOf("aix") == -1){
|
||||
return workingdir;
|
||||
}
|
||||
|
||||
String rootPath = System.getenv(env);
|
||||
if (rootPath == null) {
|
||||
String home = System.getProperty("user.home");
|
||||
if (home == null) {
|
||||
return new File("./");
|
||||
}
|
||||
rootPath = String.format("%s/%s", home, fallback);
|
||||
}
|
||||
File dir = new File(rootPath, "opsu");
|
||||
if (!dir.isDirectory() && !dir.mkdir()) {
|
||||
ErrorHandler.error(String.format("Failed to create configuration folder at '%s/opsu'.", rootPath), new Exception("empty")).preventReport().show();
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author http://wiki.lwjgl.org/index.php?title=Taking_Screen_Shots
|
||||
*/
|
||||
public void takeScreenShot() {
|
||||
// TODO: get a decent place for this
|
||||
// create the screenshot directory
|
||||
if (!screenshotDir.isDirectory() && !screenshotDir.mkdir()) {
|
||||
EventBus.post(new BubbleNotificationEvent(String.format("Failed to create screenshot directory at '%s'.", screenshotDir.getAbsolutePath()), BubbleNotificationEvent.COMMONCOLOR_RED));
|
||||
return;
|
||||
}
|
||||
|
||||
// create file name
|
||||
SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||
final String fileName = String.format("screenshot_%s.%s", date.format(new Date()), OPTION_SCREENSHOT_FORMAT.getValueString().toLowerCase());
|
||||
final File file = new File(screenshotDir, fileName);
|
||||
|
||||
SoundController.playSound(SoundEffect.SHUTTER);
|
||||
|
||||
// copy the screen to file
|
||||
final int width = Display.getWidth();
|
||||
final int height = Display.getHeight();
|
||||
final int bpp = 3; // assuming a 32-bit display with a byte each for red, green, blue, and alpha
|
||||
final ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
|
||||
GL11.glReadBuffer(GL11.GL_FRONT);
|
||||
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
|
||||
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int i = (x + (width * y)) * bpp;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
}
|
||||
ImageIO.write(image, OPTION_SCREENSHOT_FORMAT.getValueString().toLowerCase(), file);
|
||||
EventBus.post(new BubbleNotificationEvent("Created " + fileName, BubbleNotificationEvent.COMMONCOLOR_PURPLE));
|
||||
} catch (Exception e) {
|
||||
ErrorHandler.error("Failed to take a screenshot.", e).show();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
}
|
||||
40
src/yugecin/opsudance/options/GenericOption.java
Normal file
40
src/yugecin/opsudance/options/GenericOption.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
public abstract class GenericOption extends Option {
|
||||
|
||||
public int intval;
|
||||
public String strval;
|
||||
public boolean boolval;
|
||||
|
||||
public GenericOption(String name, String configurationName, String description, int intval, String strval, boolean boolval) {
|
||||
super(name, configurationName, description);
|
||||
this.intval = intval;
|
||||
this.strval = strval;
|
||||
this.boolval = boolval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String getValueString();
|
||||
@Override
|
||||
public abstract void read(String s);
|
||||
@Override
|
||||
public abstract String write();
|
||||
|
||||
}
|
||||
33
src/yugecin/opsudance/options/ListOption.java
Normal file
33
src/yugecin/opsudance/options/ListOption.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
public abstract class ListOption extends Option {
|
||||
|
||||
public ListOption(String name, String configurationName, String description) {
|
||||
super(name, configurationName, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String write();
|
||||
@Override
|
||||
public abstract void read(String s);
|
||||
public abstract Object[] getListItems();
|
||||
public abstract void clickListItem(int index);
|
||||
|
||||
}
|
||||
60
src/yugecin/opsudance/options/NumericOption.java
Normal file
60
src/yugecin/opsudance/options/NumericOption.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import yugecin.opsudance.core.events.EventBus;
|
||||
import yugecin.opsudance.events.BubbleNotificationEvent;
|
||||
|
||||
public class NumericOption extends Option {
|
||||
|
||||
public final int min;
|
||||
public final int max;
|
||||
public int val;
|
||||
|
||||
public NumericOption(String name, String configurationName, String description, int val, int min, int max) {
|
||||
super(name, configurationName, description);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public void setValue(int val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueString() {
|
||||
return String.format("%d%%", val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write() {
|
||||
return Integer.toString(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
try {
|
||||
val = Utils.clamp(Integer.parseInt(s), min, max);
|
||||
} catch (Exception ignored) {
|
||||
EventBus.post(new BubbleNotificationEvent("Failed to parse " + configurationName + " option", BubbleNotificationEvent.COMMONCOLOR_RED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
102
src/yugecin/opsudance/options/Option.java
Normal file
102
src/yugecin/opsudance/options/Option.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import yugecin.opsudance.core.DisplayContainer;
|
||||
import yugecin.opsudance.core.inject.InstanceContainer;
|
||||
|
||||
public class Option {
|
||||
|
||||
// keep a reference to the instancecontainer so that not every option instance needs to be injected
|
||||
protected static InstanceContainer instanceContainer;
|
||||
// caching some commonly used classes
|
||||
protected static Configuration config;
|
||||
protected static DisplayContainer displayContainer;
|
||||
public static void setInstanceContainer(InstanceContainer instanceContainer) {
|
||||
Option.instanceContainer = instanceContainer;
|
||||
Option.config = instanceContainer.provide(Configuration.class);
|
||||
Option.displayContainer = instanceContainer.provide(DisplayContainer.class);
|
||||
}
|
||||
|
||||
public final String name;
|
||||
public final String configurationName;
|
||||
public final String description;
|
||||
|
||||
/**
|
||||
* If this option should not be shown in the optionsmenu because it does
|
||||
* not match the search string.
|
||||
*/
|
||||
private boolean filtered;
|
||||
|
||||
/**
|
||||
* Constructor for internal options (not displayed in-game).
|
||||
*/
|
||||
public Option(String configurationName) {
|
||||
this(null, configurationName, null);
|
||||
}
|
||||
|
||||
public Option(String name, String configurationName, String description) {
|
||||
this.name = name;
|
||||
this.configurationName = configurationName;
|
||||
this.description = description;
|
||||
OptionsService.registerOption(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* should the option be shown
|
||||
* @return true if the option should be shown
|
||||
*/
|
||||
public boolean showCondition() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getValueString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String write() {
|
||||
return getValueString();
|
||||
}
|
||||
|
||||
public void read(String s) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the filtered flag for this option based on the given searchString.
|
||||
* @param searchString the searched string or null to reset the filtered flag
|
||||
* @return true if this option does need to be filtered
|
||||
*/
|
||||
public boolean filter(String searchString) {
|
||||
if (searchString == null || searchString.length() == 0) {
|
||||
filtered = false;
|
||||
return false;
|
||||
}
|
||||
filtered = !name.toLowerCase().contains(searchString) && !description.toLowerCase().contains(searchString);
|
||||
return filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this option should be filtered (= not shown) because it does not
|
||||
* match the search string.
|
||||
* @return true if the option shouldn't be shown.
|
||||
*/
|
||||
public boolean isFiltered() {
|
||||
return filtered;
|
||||
}
|
||||
|
||||
}
|
||||
239
src/yugecin/opsudance/options/OptionGroups.java
Normal file
239
src/yugecin/opsudance/options/OptionGroups.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! 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! 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!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import static yugecin.opsudance.options.Options.*;
|
||||
|
||||
public class OptionGroups {
|
||||
|
||||
public static final OptionTab[] normalOptions = new OptionTab[] {
|
||||
new OptionTab("GENERAL", null),
|
||||
new OptionTab("GENERAL", new Option[]{
|
||||
OPTION_DISABLE_UPDATER,
|
||||
OPTION_ENABLE_WATCH_SERVICE
|
||||
}),
|
||||
new OptionTab("LANGUAGE", new Option[]{
|
||||
OPTION_SHOW_UNICODE,
|
||||
}),
|
||||
new OptionTab("GRAPHICS", null),
|
||||
new OptionTab("RENDERER", new Option[] {
|
||||
OPTION_SCREEN_RESOLUTION,
|
||||
OPTION_ALLOW_LARGER_RESOLUTIONS,
|
||||
OPTION_FULLSCREEN,
|
||||
OPTION_TARGET_UPS,
|
||||
OPTION_TARGET_FPS,
|
||||
OPTION_SHOW_FPS,
|
||||
OPTION_USE_FPS_DELTAS,
|
||||
OPTION_SCREENSHOT_FORMAT,
|
||||
}),
|
||||
new OptionTab("SLIDER OPTIONS", new Option[]{
|
||||
OPTION_SNAKING_SLIDERS,
|
||||
OPTION_FALLBACK_SLIDERS,
|
||||
OPTION_SHRINKING_SLIDERS,
|
||||
OPTION_MERGING_SLIDERS,
|
||||
//OPTION_MERGING_SLIDERS_MIRROR_POOL,
|
||||
OPTION_DRAW_SLIDER_ENDCIRCLES,
|
||||
}),
|
||||
new OptionTab("DANCING HITCIRCLES", new Option[] {
|
||||
OPTION_DANCING_CIRCLES,
|
||||
OPTION_DANCING_CIRCLES_MULTIPLIER,
|
||||
}),
|
||||
new OptionTab("SKIN", null),
|
||||
new OptionTab("SKIN", new Option[]{
|
||||
OPTION_SKIN,
|
||||
OPTION_IGNORE_BEATMAP_SKINS,
|
||||
OPTION_DYNAMIC_BACKGROUND,
|
||||
OPTION_LOAD_HD_IMAGES,
|
||||
OPTION_LOAD_VERBOSE,
|
||||
OPTION_COLOR_MAIN_MENU_LOGO,
|
||||
}),
|
||||
new OptionTab("CURSOR", new Option[]{
|
||||
OPTION_CURSOR_SIZE,
|
||||
OPTION_NEW_CURSOR,
|
||||
OPTION_DISABLE_CURSOR
|
||||
// TODO use combo colour as tint for slider ball option
|
||||
}),
|
||||
new OptionTab("AUDIO", null),
|
||||
new OptionTab("VOLUME", new Option[]{
|
||||
OPTION_MASTER_VOLUME,
|
||||
OPTION_MUSIC_VOLUME,
|
||||
OPTION_EFFECT_VOLUME,
|
||||
OPTION_HITSOUND_VOLUME,
|
||||
OPTION_SAMPLE_VOLUME_OVERRIDE,
|
||||
}),
|
||||
new OptionTab("MISC", new Option[] {
|
||||
OPTION_MUSIC_OFFSET,
|
||||
OPTION_DISABLE_SOUNDS,
|
||||
OPTION_ENABLE_THEME_SONG
|
||||
}),
|
||||
new OptionTab("GAMEPLAY", null),
|
||||
new OptionTab("GENERAL", new Option[] {
|
||||
OPTION_BACKGROUND_DIM,
|
||||
OPTION_FORCE_DEFAULT_PLAYFIELD,
|
||||
OPTION_SHOW_HIT_LIGHTING,
|
||||
OPTION_SHOW_HIT_ANIMATIONS,
|
||||
OPTION_SHOW_COMBO_BURSTS,
|
||||
OPTION_SHOW_PERFECT_HIT,
|
||||
OPTION_SHOW_FOLLOW_POINTS,
|
||||
OPTION_SHOW_HIT_ERROR_BAR,
|
||||
OPTION_MAP_START_DELAY,
|
||||
OPTION_MAP_END_DELAY,
|
||||
OPTION_EPILEPSY_WARNING,
|
||||
}),
|
||||
new OptionTab("INPUT", null),
|
||||
new OptionTab("KEY MAPPING", new Option[]{
|
||||
OPTION_KEY_LEFT,
|
||||
OPTION_KEY_RIGHT,
|
||||
}),
|
||||
new OptionTab("MOUSE", new Option[] {
|
||||
OPTION_DISABLE_MOUSE_WHEEL,
|
||||
OPTION_DISABLE_MOUSE_BUTTONS,
|
||||
}),
|
||||
new OptionTab("CUSTOM", null),
|
||||
new OptionTab("DIFFICULTY", new Option[]{
|
||||
OPTION_FIXED_CS,
|
||||
OPTION_FIXED_HP,
|
||||
OPTION_FIXED_AR,
|
||||
OPTION_FIXED_OD,
|
||||
}),
|
||||
new OptionTab("MISC", new Option[] {
|
||||
OPTION_CHECKPOINT,
|
||||
OPTION_REPLAY_SEEKING,
|
||||
}),
|
||||
new OptionTab("DANCE", null),
|
||||
new OptionTab("MOVER", new Option[]{
|
||||
OPTION_DANCE_MOVER,
|
||||
OPTION_DANCE_EXGON_DELAY,
|
||||
OPTION_DANCE_QUAD_BEZ_AGGRESSIVENESS,
|
||||
OPTION_DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR,
|
||||
OPTION_DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS,
|
||||
OPTION_DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR,
|
||||
OPTION_DANCE_MOVER_DIRECTION,
|
||||
OPTION_DANCE_SLIDER_MOVER_TYPE,
|
||||
}),
|
||||
new OptionTab("SPINNER", new Option[]{
|
||||
OPTION_DANCE_SPINNER,
|
||||
OPTION_DANCE_SPINNER_DELAY,
|
||||
}),
|
||||
new OptionTab("SLIDER OPTIONS", new Option[]{
|
||||
OPTION_DANCE_LAZY_SLIDERS,
|
||||
OPTION_DANCE_CIRLCE_IN_SLOW_SLIDERS,
|
||||
OPTION_DANCE_CIRLCE_IN_LAZY_SLIDERS,
|
||||
}),
|
||||
new OptionTab("CIRCLE MOVEMENTS", new Option[]{
|
||||
OPTION_DANCE_CIRCLE_STREAMS,
|
||||
OPTION_DANCE_ONLY_CIRCLE_STACKS,
|
||||
}),
|
||||
new OptionTab("MIRROR", new Option[] {
|
||||
OPTION_DANCE_MIRROR,
|
||||
}),
|
||||
new OptionTab("ADVANCED DISPLAY", null),
|
||||
new OptionTab("OBJECTS", new Option[]{
|
||||
OPTION_DANCE_DRAW_APPROACH,
|
||||
OPTION_DANCE_OBJECT_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED,
|
||||
OPTION_DANCE_RGB_OBJECT_INC,
|
||||
OPTION_DANCE_HIDE_OBJECTS,
|
||||
}),
|
||||
new OptionTab("CURSOR", new Option[]{
|
||||
OPTION_DANCE_CURSOR_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_CURSOR_MIRROR_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_CURSOR_ONLY_COLOR_TRAIL,
|
||||
OPTION_DANCE_RGB_CURSOR_INC,
|
||||
OPTION_DANCE_CURSOR_TRAIL_OVERRIDE,
|
||||
}),
|
||||
new OptionTab("MISC", new Option[] {
|
||||
OPTION_DANCE_HIDE_UI,
|
||||
OPTION_DANCE_REMOVE_BG,
|
||||
OPTION_DANCE_ENABLE_SB,
|
||||
}),
|
||||
new OptionTab ("PIPPI", null),
|
||||
new OptionTab ("GENERAL", new Option[]{
|
||||
OPTION_PIPPI_ENABLE,
|
||||
OPTION_PIPPI_RADIUS_PERCENT,
|
||||
}),
|
||||
new OptionTab ("ANGLE MULTIPLIERS", new Option[]{
|
||||
OPTION_PIPPI_ANGLE_INC_MUL,
|
||||
OPTION_PIPPI_ANGLE_INC_MUL_SLIDER,
|
||||
}),
|
||||
new OptionTab ("MISC", new Option[] {
|
||||
OPTION_PIPPI_SLIDER_FOLLOW_EXPAND,
|
||||
OPTION_PIPPI_PREVENT_WOBBLY_STREAMS,
|
||||
})
|
||||
};
|
||||
|
||||
public static final OptionTab[] storyboardOptions = new OptionTab[] {
|
||||
new OptionTab("Gameplay", new Option[] {
|
||||
OPTION_BACKGROUND_DIM,
|
||||
OPTION_DANCE_REMOVE_BG,
|
||||
OPTION_SNAKING_SLIDERS,
|
||||
OPTION_SHRINKING_SLIDERS,
|
||||
OPTION_SHOW_HIT_LIGHTING,
|
||||
OPTION_SHOW_HIT_ANIMATIONS,
|
||||
OPTION_SHOW_COMBO_BURSTS,
|
||||
OPTION_SHOW_PERFECT_HIT,
|
||||
OPTION_SHOW_FOLLOW_POINTS,
|
||||
}),
|
||||
new OptionTab("Input", new Option[] {
|
||||
OPTION_CURSOR_SIZE,
|
||||
OPTION_NEW_CURSOR,
|
||||
OPTION_DISABLE_CURSOR
|
||||
}),
|
||||
new OptionTab("Dance", new Option[] {
|
||||
OPTION_DANCE_MOVER,
|
||||
OPTION_DANCE_EXGON_DELAY,
|
||||
OPTION_DANCE_QUAD_BEZ_AGGRESSIVENESS,
|
||||
OPTION_DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR,
|
||||
OPTION_DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS,
|
||||
OPTION_DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR,
|
||||
OPTION_DANCE_MOVER_DIRECTION,
|
||||
OPTION_DANCE_SLIDER_MOVER_TYPE,
|
||||
OPTION_DANCE_SPINNER,
|
||||
OPTION_DANCE_SPINNER_DELAY,
|
||||
OPTION_DANCE_LAZY_SLIDERS,
|
||||
OPTION_DANCE_CIRCLE_STREAMS,
|
||||
OPTION_DANCE_ONLY_CIRCLE_STACKS,
|
||||
OPTION_DANCE_CIRLCE_IN_SLOW_SLIDERS,
|
||||
OPTION_DANCE_CIRLCE_IN_LAZY_SLIDERS,
|
||||
OPTION_DANCE_MIRROR,
|
||||
}),
|
||||
new OptionTab("Dance display", new Option[] {
|
||||
OPTION_DANCE_DRAW_APPROACH,
|
||||
OPTION_DANCE_OBJECT_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED,
|
||||
OPTION_DANCE_RGB_OBJECT_INC,
|
||||
OPTION_DANCE_CURSOR_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_CURSOR_MIRROR_COLOR_OVERRIDE,
|
||||
OPTION_DANCE_CURSOR_ONLY_COLOR_TRAIL,
|
||||
OPTION_DANCE_RGB_CURSOR_INC,
|
||||
OPTION_DANCE_CURSOR_TRAIL_OVERRIDE,
|
||||
OPTION_DANCE_HIDE_OBJECTS,
|
||||
OPTION_DANCE_HIDE_UI,
|
||||
}),
|
||||
new OptionTab ("Pippi", new Option[] {
|
||||
OPTION_PIPPI_ENABLE,
|
||||
OPTION_PIPPI_RADIUS_PERCENT,
|
||||
OPTION_PIPPI_ANGLE_INC_MUL,
|
||||
OPTION_PIPPI_ANGLE_INC_MUL_SLIDER,
|
||||
OPTION_PIPPI_SLIDER_FOLLOW_EXPAND,
|
||||
OPTION_PIPPI_PREVENT_WOBBLY_STREAMS,
|
||||
})
|
||||
};
|
||||
|
||||
}
|
||||
31
src/yugecin/opsudance/options/OptionTab.java
Normal file
31
src/yugecin/opsudance/options/OptionTab.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
public class OptionTab {
|
||||
|
||||
public final String name;
|
||||
public final Option[] options;
|
||||
public boolean filtered;
|
||||
|
||||
public OptionTab(String name, Option[] options) {
|
||||
this.name = name;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
}
|
||||
978
src/yugecin/opsudance/options/Options.java
Normal file
978
src/yugecin/opsudance/options/Options.java
Normal file
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import awlex.ospu.polymover.factory.PolyMoverFactory;
|
||||
import itdelatrisu.opsu.GameImage;
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.states.Game;
|
||||
import itdelatrisu.opsu.ui.Fonts;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.newdawn.slick.Input;
|
||||
import org.newdawn.slick.SlickException;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
import org.newdawn.slick.util.Log;
|
||||
import yugecin.opsudance.*;
|
||||
import yugecin.opsudance.core.events.EventBus;
|
||||
import yugecin.opsudance.core.events.EventListener;
|
||||
import yugecin.opsudance.events.BarNotificationEvent;
|
||||
import yugecin.opsudance.events.ResolutionOrSkinChangedEvent;
|
||||
import yugecin.opsudance.movers.factories.ExgonMoverFactory;
|
||||
import yugecin.opsudance.movers.factories.QuadraticBezierMoverFactory;
|
||||
import yugecin.opsudance.movers.slidermovers.DefaultSliderMoverController;
|
||||
import yugecin.opsudance.skinning.SkinService;
|
||||
import yugecin.opsudance.utils.CachedVariable;
|
||||
import yugecin.opsudance.utils.CachedVariable.Getter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author itdelatrisu (https://github.com/itdelatrisu) most functions are copied from itdelatrisu.opsu.Options.java
|
||||
*/
|
||||
public class Options {
|
||||
|
||||
// TODO remove this?
|
||||
public static int width;
|
||||
public static int height;
|
||||
|
||||
static {
|
||||
EventBus.subscribe(ResolutionOrSkinChangedEvent.class, new EventListener<ResolutionOrSkinChangedEvent>() {
|
||||
@Override
|
||||
public void onEvent(ResolutionOrSkinChangedEvent event) {
|
||||
if (event.width > 0) {
|
||||
width = event.width;
|
||||
height = event.height;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// internal options (not displayed in-game)
|
||||
public static final Option OPTION_BEATMAP_DIRECTORY = new Option("BeatmapDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.BEATMAP_DIR.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.beatmapDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Option OPTION_OSZ_DIRECTORY = new Option("OSZDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.oszDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.oszDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Option OPTION_SCREENSHOT_DIRECTORY = new Option("ScreenshotDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.screenshotDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.screenshotDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Option OPTION_REPLAY_DIRECTORY = new Option("ReplayDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.replayDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.replayDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Option OPTION_REPLAY_IMPORT_DIRECTORY = new Option("ReplayImportDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.replayImportDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.replayImportDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Option OPTION_SKIN_DIRECTORY = new Option("SkinDirectory") {
|
||||
@Override
|
||||
public String write() {
|
||||
return config.skinRootDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
config.skinRootDir = new File(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_PORT = new NumericOption("-", "Port", "-", 49250, 1024, 65535) {
|
||||
@Override
|
||||
public void read (String s){
|
||||
super.read(s);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_NOSINGLEINSTANCE = new ToggleOption("-", "NoSingleInstance", "-", false);
|
||||
|
||||
// in-game options
|
||||
public static final Option OPTION_SCREEN_RESOLUTION = new ListOption("Screen Resolution", "ScreenResolution", "Change the size of the game.") {
|
||||
private final String[] resolutions = {
|
||||
null,
|
||||
"800x600",
|
||||
"1024x600",
|
||||
"1024x768",
|
||||
"1280x720",
|
||||
"1280x800",
|
||||
"1280x960",
|
||||
"1280x1024",
|
||||
"1366x768",
|
||||
"1440x900",
|
||||
"1600x900",
|
||||
"1600x1200",
|
||||
"1680x1050",
|
||||
"1920x1080",
|
||||
"1920x1200",
|
||||
"2560x1440",
|
||||
"2560x1600",
|
||||
"3840x2160"
|
||||
};
|
||||
|
||||
private int idx;
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return resolutions[idx]; // do not change (see DisplayContainer#setup)
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
idx = index;
|
||||
displayContainer.updateDisplayMode(resolutions[idx]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
resolutions[0] = displayContainer.nativeDisplayMode.getWidth() + "x" + displayContainer.nativeDisplayMode.getHeight();
|
||||
try {
|
||||
idx = Integer.parseInt(s);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
idx = Utils.clamp(idx, 0, resolutions.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.valueOf(idx);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_ALLOW_LARGER_RESOLUTIONS = new ToggleOption("Allow large resolutions", "AllowLargeRes", "Allow resolutions larger than the native resolution", false);
|
||||
public static final ToggleOption OPTION_FULLSCREEN = new ToggleOption("Fullscreen Mode", "Fullscreen", "Restart to apply changes.", false);
|
||||
public static final ListOption OPTION_SKIN = new ListOption("Skin", "Skin", "Change how the game looks.") {
|
||||
private CachedVariable<SkinService> skinService = new CachedVariable<>(new Getter<SkinService>() {
|
||||
@Override
|
||||
public SkinService get() {
|
||||
return instanceContainer.provide(SkinService.class);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return skinService.get().usedSkinName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return skinService.get().availableSkinDirectories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
skinService.get().usedSkinName = skinService.get().availableSkinDirectories[index];
|
||||
skinService.get().reloadSkin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
skinService.get().usedSkinName = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write() {
|
||||
return skinService.get().usedSkinName;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_TARGET_UPS = new NumericOption("target UPS", "targetUPS", "Higher values result in less input lag and smoother cursor trail, but may cause high CPU usage.", 480, 20, 1000) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%dups", val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue ( int value){
|
||||
super.setValue(value);
|
||||
displayContainer.setUPS(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final int[] targetFPS = {60, 120, 240, 1000};
|
||||
public static int targetFPSIndex = 0;
|
||||
|
||||
public static final ListOption OPTION_TARGET_FPS = new ListOption("FPS limit", "FPSlimit", "Higher values may cause high CPU usage. A value higher than the UPS has no effect.") {
|
||||
private CachedVariable<String[]> $_getListItems = new CachedVariable<>(new Getter<String[]>() {
|
||||
@Override
|
||||
public String[] get() {
|
||||
String[] list = new String[targetFPS.length];
|
||||
for (int i = 0; i < targetFPS.length; i++) {
|
||||
list[i] = String.format("%dfps", targetFPS[i]);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return $_getListItems.get()[targetFPSIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return $_getListItems.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
targetFPSIndex = index;
|
||||
displayContainer.setFPS(targetFPS[targetFPSIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return Integer.toString(targetFPS[targetFPSIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = Integer.parseInt(s);
|
||||
for (int j = 0; j < targetFPS.length; j++) {
|
||||
if (i == targetFPS[j]) {
|
||||
targetFPSIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_SHOW_FPS = new ToggleOption("Show FPS Counters", "FpsCounter", "Show FPS and UPS counters in the bottom-right hand corner.", true);
|
||||
public static final ToggleOption OPTION_USE_FPS_DELTAS = new ToggleOption("Use deltas for FPS counters", "FpsCounterDeltas", "Show time between updates instead of updates per second.", false) {
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return OPTION_SHOW_FPS.state;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_SHOW_UNICODE = new ToggleOption("Prefer Non-English Metadata", "ShowUnicode", "Where available, song titles will be shown in their native language.", false) {
|
||||
@Override
|
||||
public void toggle () {
|
||||
super.toggle();
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Fonts.LARGE.loadGlyphs();
|
||||
Fonts.MEDIUM.loadGlyphs();
|
||||
Fonts.DEFAULT.loadGlyphs();
|
||||
} catch (SlickException e) {
|
||||
Log.warn("Failed to load glyphs.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_SCREENSHOT_FORMAT = new ListOption("Screenshot Format", "ScreenshotFormat", "Press F12 to take a screenshot.") {
|
||||
private String[] formats = { "PNG", "JPG", "BMP" };
|
||||
private int index = 0;
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return formats[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return formats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return Integer.toString(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = Integer.parseInt(s);
|
||||
if (0 <= i && i < formats.length) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_CURSOR_SIZE = new NumericOption("Size", "CursorSize", "Change the cursor scale.", 100, 50, 200) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%.2fx", val / 100f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.format("%.2f", val / 100f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = (int) (Float.parseFloat(s.replace(',', '.')) * 100f);
|
||||
if (i >= 50 && i <= 200)
|
||||
val = i;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_NEW_CURSOR = new ToggleOption("Enable New Cursor", "NewCursor", "Use the new cursor style (may cause higher CPU usage).", true);
|
||||
public static final ToggleOption OPTION_DYNAMIC_BACKGROUND = new ToggleOption("Enable Dynamic Backgrounds", "DynamicBackground", "The song background will be used as the main menu background.", true);
|
||||
public static final ToggleOption OPTION_LOAD_VERBOSE = new ToggleOption("Show Detailed Loading Progress", "LoadVerbose", "Display more specific loading information in the splash screen.", false);
|
||||
public static final ToggleOption OPTION_COLOR_MAIN_MENU_LOGO = new ToggleOption("Use cursor color as main menu logo tint", "ColorMainMenuLogo", "Colorful main menu logo", false);
|
||||
public static final NumericOption OPTION_MASTER_VOLUME = new NumericOption("Master", "VolumeUniversal", "Global volume level.", 35, 0, 100) {
|
||||
@Override
|
||||
public void setValue(int value){
|
||||
super.setValue(value);
|
||||
// changing mastervolume, so music volume should change too
|
||||
OPTION_MUSIC_VOLUME.setValue(OPTION_MUSIC_VOLUME.val);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_MUSIC_VOLUME = new NumericOption("Music", "VolumeMusic", "Volume of music.", 80, 0, 100) {
|
||||
@Override
|
||||
public void setValue(int value){
|
||||
super.setValue(value);
|
||||
SoundStore.get().setMusicVolume(OPTION_MASTER_VOLUME.val * OPTION_MUSIC_VOLUME.val / 10000f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_SAMPLE_VOLUME_OVERRIDE = new NumericOption("Sample override", "BMSampleOverride", "Override beatmap hitsound volume", 100, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
if (val == 0) {
|
||||
return "Disabled";
|
||||
}
|
||||
return super.getValueString();
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_EFFECT_VOLUME = new NumericOption("Effects", "VolumeEffect", "Volume of menu and game sounds.", 70, 0, 100);
|
||||
public static final NumericOption OPTION_HITSOUND_VOLUME = new NumericOption("Hit Sounds", "VolumeHitSound", "Volume of hit sounds.", 30, 0, 100);
|
||||
public static final NumericOption OPTION_MUSIC_OFFSET = new NumericOption("Music Offset", "Offset", "Adjust this value if hit objects are out of sync.", -75, -500, 500) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%dms", val);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DISABLE_SOUNDS = new ToggleOption("Disable All Sound Effects", "DisableSound", "May resolve Linux sound driver issues. Requires a restart.", (System.getProperty("os.name").toLowerCase().contains("linux")));
|
||||
public static final GenericOption OPTION_KEY_LEFT = new GenericOption("Left Game Key", "keyOsuLeft", "Select this option to input a key.", Input.KEY_Z, null, false) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Keyboard.getKeyName(intval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return Keyboard.getKeyName(intval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s){
|
||||
intval = Keyboard.getKeyIndex(s);
|
||||
if (intval == Keyboard.KEY_NONE) {
|
||||
intval = Input.KEY_Y;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final GenericOption OPTION_KEY_RIGHT = new GenericOption("Right Game Key", "keyOsuRight", "Select this option to input a key.", Input.KEY_X, null, false) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Keyboard.getKeyName(intval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return Keyboard.getKeyName(intval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s){
|
||||
intval = Keyboard.getKeyIndex(s);
|
||||
if (intval == Keyboard.KEY_NONE) {
|
||||
intval = Input.KEY_X;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_BACKGROUND_DIM = new NumericOption("Background Dim", "DimLevel", "Percentage to dim the background image during gameplay.", 50, 0, 100);
|
||||
public static final ToggleOption OPTION_DISABLE_MOUSE_WHEEL = new ToggleOption("Disable mouse wheel in play mode", "MouseDisableWheel", "During play, you can use the mouse wheel to adjust the volume and pause the game. This will disable that functionality.", false);
|
||||
public static final ToggleOption OPTION_DISABLE_MOUSE_BUTTONS = new ToggleOption("Disable mouse buttons in play mode", "MouseDisableButtons", "This option will disable all mouse buttons. Specifically for people who use their keyboard to click.", false) {
|
||||
@Override
|
||||
public void toggle() {
|
||||
EventBus.post(new BarNotificationEvent(state ? "Mouse buttons are disabled." : "Mouse buttons are enabled."));
|
||||
}
|
||||
};
|
||||
public static final ToggleOption OPTION_DISABLE_CURSOR = new ToggleOption("Disable Cursor", "DisableCursor", "Hide the cursor sprite.", false);
|
||||
public static final ToggleOption OPTION_DANCE_REMOVE_BG = new ToggleOption("Use black background instead of image", "RemoveBG", "Hello darkness my old friend", true);
|
||||
public static final ToggleOption OPTION_FORCE_DEFAULT_PLAYFIELD = new ToggleOption("Force Default Playfield", "ForceDefaultPlayfield", "Override the song background with the default playfield background.", false);
|
||||
public static final ToggleOption OPTION_IGNORE_BEATMAP_SKINS = new ToggleOption("Ignore All Beatmap Skins", "IgnoreBeatmapSkins", "Never use skin element overrides provided by beatmaps.", false);
|
||||
public static final ToggleOption OPTION_SNAKING_SLIDERS = new ToggleOption("Snaking sliders", "SnakingSliders", "Sliders gradually snake out from their starting point.", true);
|
||||
public static final ToggleOption OPTION_SHRINKING_SLIDERS = new ToggleOption("Shrinking sliders", "ShrinkingSliders", "Sliders shrinks when sliderball passes (aka knorkesliders)", true);
|
||||
public static final ToggleOption OPTION_FALLBACK_SLIDERS = new ToggleOption("Fallback sliders", "FallbackSliders", "Enable this if sliders won't render", false);
|
||||
public static final ToggleOption OPTION_MERGING_SLIDERS = new ToggleOption("Merging sliders", "MergingSliders", "Merge sliders (aka knorkesliders)", true) {
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return !OPTION_FALLBACK_SLIDERS.state;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_MERGING_SLIDERS_MIRROR_POOL = new NumericOption("Merging sliders mirror pool", "MergingSliderMirrorPool", "Amount of mirrors to calculate for merging sliders (impacts performance)", 2, 1, 5) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return OPTION_MERGING_SLIDERS.showCondition() && OPTION_MERGING_SLIDERS.state;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DRAW_SLIDER_ENDCIRCLES = new ToggleOption("Draw endcircles", "DrawSliderEndCircles", "Old slider style", false);
|
||||
public static final ToggleOption OPTION_DANCING_CIRCLES = new ToggleOption("Enable", "DancingHitcircles", "Make hitcircles dance to the beat", false);
|
||||
public static final NumericOption OPTION_DANCING_CIRCLES_MULTIPLIER = new NumericOption("Multiplier", "DancingHitcirclesMP", "Multiplier to expand the hitcircles when dancing to the beat", 50, 1, 200) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%.1f%%", val / 10f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_SHOW_HIT_LIGHTING = new ToggleOption("Show Hit Lighting", "HitLighting", "Adds an effect behind hit explosions.", true);
|
||||
public static final ToggleOption OPTION_SHOW_HIT_ANIMATIONS = new ToggleOption("Show Hit Animations", "HitAnimations", "Fade out circles and curves.", true);
|
||||
public static final ToggleOption OPTION_SHOW_REVERSEARROW_ANIMATIONS = new ToggleOption("Show reverse arrow animations", "ReverseArrowAnimations", "Fade out reverse arrows after passing.", true);
|
||||
public static final ToggleOption OPTION_SHOW_COMBO_BURSTS = new ToggleOption("Show Combo Bursts", "ComboBurst", "A character image is displayed at combo milestones.", true);
|
||||
public static final ToggleOption OPTION_SHOW_PERFECT_HIT = new ToggleOption("Show Perfect Hits", "PerfectHit", "Whether to show perfect hit result bursts (300s, slider ticks).", true);
|
||||
public static final ToggleOption OPTION_SHOW_FOLLOW_POINTS = new ToggleOption("Show Follow Points", "FollowPoints", "Whether to show follow points between hit objects.", true);
|
||||
public static final ToggleOption OPTION_SHOW_HIT_ERROR_BAR = new ToggleOption("Show Hit Error Bar", "ScoreMeter", "Shows precisely how accurate you were with each hit.", false);
|
||||
public static final NumericOption OPTION_MAP_START_DELAY = new NumericOption("Map start delay", "StartDelay", "Have a fix amount of time to prepare your play/record", 20, 1, 50) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val * 100) + "ms";
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_MAP_END_DELAY = new NumericOption("Map end delay", "EndDelay", "Have a fix amount of time at the and of the map for a smooth finish", 50, 1, 150) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val * 100) + "ms";
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_EPILEPSY_WARNING = new NumericOption("Epilepsy warning image", "EpiWarn", "Show a little warning for flashing colours in the beginning", 0, 0, 20) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
if (val == 0) {
|
||||
return "Disabled";
|
||||
}
|
||||
return (val * 100) + "ms";
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_LOAD_HD_IMAGES = new ToggleOption("Load HD Images", "LoadHDImages", String.format("Loads HD (%s) images when available. Increases memory usage and loading times.", GameImage.HD_SUFFIX), true);
|
||||
public static final NumericOption OPTION_FIXED_CS = new NumericOption("Fixed CS", "FixedCS", "Determines the size of circles and sliders.", 0, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val == 0) ? "Disabled" : String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = (int) (Float.parseFloat(s.replace(',', '.')) * 10f);
|
||||
if (i >= 0 && i <= 100)
|
||||
val = i;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_FIXED_HP = new NumericOption("Fixed HP", "FixedHP", "Determines the rate at which health decreases.", 0, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val == 0) ? "Disabled" : String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = (int) (Float.parseFloat(s.replace(',', '.')) * 10f);
|
||||
if (i >= 0 && i <= 100)
|
||||
val = i;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_FIXED_AR = new NumericOption("Fixed AR", "FixedAR", "Determines how long hit circles stay on the screen.", 0, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val == 0) ? "Disabled" : String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = (int) (Float.parseFloat(s.replace(',', '.')) * 10f);
|
||||
if (i >= 0 && i <= 100)
|
||||
val = i;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_FIXED_OD = new NumericOption("Fixed OD", "FixedOD", "Determines the time window for hit results.", 0, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val == 0) ? "Disabled" : String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.format("%.1f", val / 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = (int) (Float.parseFloat(s.replace(',', '.')) * 10f);
|
||||
if (i >= 0 && i <= 100)
|
||||
val = i;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_CHECKPOINT = new NumericOption("Track Checkpoint", "Checkpoint", "Press Ctrl+L while playing to load a checkpoint, and Ctrl+S to set one.", 0, 0, 3599) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return (val == 0) ? "Disabled" : String.format("%02d:%02d",
|
||||
TimeUnit.SECONDS.toMinutes(val),
|
||||
val - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(val)));
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_ENABLE_THEME_SONG = new ToggleOption("Enable Theme Song", "MenuMusic", "Whether to play the theme song upon starting opsu!", true);
|
||||
public static final ToggleOption OPTION_REPLAY_SEEKING = new ToggleOption("Replay Seeking", "ReplaySeeking", "Enable a seeking bar on the left side of the screen during replays.", false);
|
||||
public static final ToggleOption OPTION_DISABLE_UPDATER = new ToggleOption("Disable Automatic Updates", "DisableUpdater", "Disable automatic checking for updates upon starting opsu!.", false);
|
||||
public static final ToggleOption OPTION_ENABLE_WATCH_SERVICE = new ToggleOption("Enable Watch Service", "WatchService", "Watch the beatmap directory for changes. Requires a restart.", false);
|
||||
public static final ListOption OPTION_DANCE_MOVER = new ListOption("Algorithm", "Mover", "Algorithm that decides how to move from note to note" ) {
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return Dancer.moverFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
if (Game.isInGame && Dancer.moverFactories[index] instanceof PolyMoverFactory) {
|
||||
// TODO remove this when #79 is fixed
|
||||
EventBus.post(new BarNotificationEvent("This mover is disabled in the storyboard right now"));
|
||||
return;
|
||||
}
|
||||
Dancer.instance.setMoverFactoryIndex(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.moverFactories[Dancer.instance.getMoverFactoryIndex()].toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.valueOf(Dancer.instance.getMoverFactoryIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
int i = Integer.parseInt(s);
|
||||
Dancer.instance.setMoverFactoryIndex(i);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_EXGON_DELAY = new NumericOption("ExGon delay", "ExGonDelay", "Delay between moves for the ExGon mover", 25, 2, 750) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return Dancer.moverFactories[Dancer.instance.getMoverFactoryIndex()] instanceof ExgonMoverFactory;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_QUAD_BEZ_AGGRESSIVENESS = new NumericOption("Bezier aggressiveness", "QuadBezAgr", "AKA initial D factor", 50, 0, 200) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return Dancer.moverFactories[Dancer.instance.getMoverFactoryIndex()] instanceof QuadraticBezierMoverFactory;
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR = new NumericOption("Exit aggressiveness", "CubBezSliderExitAgr", "AKA initial D factor for sliderexits", 4, 1, 6) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return OPTION_DANCE_QUAD_BEZ_AGGRESSIVENESS.showCondition()
|
||||
&& Dancer.sliderMoverController instanceof DefaultSliderMoverController;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS = new ToggleOption("Use cubic bezier before sliders", "QuadBezCubicSliders", "Slider entry looks better using this", true) {
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return OPTION_DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR.showCondition();
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR = new NumericOption("Entry aggressiveness", "CubBezSliderEntryAgr", "AKA initial D factor for sliderentries", 4, 1, 6) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCondition () {
|
||||
return OPTION_DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS.showCondition()
|
||||
&& OPTION_DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS.state;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_MOVER_DIRECTION = new ListOption("Direction", "MoverDirection", "The direction the mover goes" ) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.moverDirection.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return MoverDirection.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.moverDirection = MoverDirection.values()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return "" + Dancer.moverDirection.nr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.moverDirection = MoverDirection.values()[Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_SLIDER_MOVER_TYPE = new ListOption("Slider mover", "SliderMover", "How to move in sliders") {
|
||||
private int val;
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.sliderMoverController.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return Dancer.sliderMovers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
val = index;
|
||||
Dancer.sliderMoverController = Dancer.sliderMovers[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.sliderMoverController = Dancer.sliderMovers[val = Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_SPINNER = new ListOption("Algorithm", "Spinner", "Spinner style") {
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return Dancer.spinners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.instance.setSpinnerIndex(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.spinners[Dancer.instance.getSpinnerIndex()].toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return Dancer.instance.getSpinnerIndex() + "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.instance.setSpinnerIndex(Integer.parseInt(s));
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_SPINNER_DELAY = new NumericOption("Delay", "SpinnerDelay", "Fiddle with this if spinner goes too fast.", 3, 0, 20) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%dms", val);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DANCE_LAZY_SLIDERS = new ToggleOption("Lazy sliders", "LazySliders", "Don't do short sliders", false);
|
||||
public static final ToggleOption OPTION_DANCE_ONLY_CIRCLE_STACKS = new ToggleOption("Only circle stacks", "CircleStacks", "Only do circle movement on stacks", false);
|
||||
public static final ToggleOption OPTION_DANCE_CIRCLE_STREAMS = new ToggleOption("Circle streams", "CircleStreams", "Make circles while streaming", false);
|
||||
public static final ToggleOption OPTION_DANCE_MIRROR = new ToggleOption("Mirror collage", "MirrorCollage", "Hypnotizing stuff. Toggle this ingame by pressing the M key.", false);
|
||||
public static final ToggleOption OPTION_DANCE_DRAW_APPROACH = new ToggleOption("Draw approach circles", "DrawApproach", "Can get a bit busy when using mirror collage", true);
|
||||
public static final ListOption OPTION_DANCE_OBJECT_COLOR_OVERRIDE = new ListOption("Color", "ObjColorOverride", "Override object colors") {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.colorOverride.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return ObjectColorOverrides.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.colorOverride = ObjectColorOverrides.values()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return "" + Dancer.colorOverride.nr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.colorOverride = ObjectColorOverrides.values()[Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED = new ListOption("Mirror color", "ObjColorMirroredOverride", "Override collage object colors") {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.colorMirrorOverride.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return ObjectColorOverrides.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.colorMirrorOverride = ObjectColorOverrides.values()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return "" + Dancer.colorMirrorOverride.nr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.colorMirrorOverride = ObjectColorOverrides.values()[Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_RGB_OBJECT_INC = new NumericOption("RGB increment", "RGBInc", "Amount of hue to shift, used for rainbow object override", 70, -1800, 1800) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%.1f°", val / 10f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_CURSOR_COLOR_OVERRIDE = new ListOption("Color", "CursorColorOverride", "Override cursor color") {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.cursorColorOverride.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return CursorColorOverrides.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.cursorColorOverride = CursorColorOverrides.values()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return "" + Dancer.cursorColorOverride.nr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.cursorColorOverride = CursorColorOverrides.values()[Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final ListOption OPTION_DANCE_CURSOR_MIRROR_COLOR_OVERRIDE = new ListOption("Mirror color", "CursorMirrorColorOverride", "Override mirror cursor color") {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return Dancer.cursorColorMirrorOverride.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getListItems () {
|
||||
return CursorColorOverrides.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickListItem(int index){
|
||||
Dancer.cursorColorMirrorOverride = CursorColorOverrides.values()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write () {
|
||||
return "" + Dancer.cursorColorMirrorOverride.nr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read (String s){
|
||||
Dancer.cursorColorMirrorOverride = CursorColorOverrides.values()[Integer.parseInt(s)];
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DANCE_CURSOR_ONLY_COLOR_TRAIL = new ToggleOption("Only color cursor trail", "OnlyColorTrail", "Don't color the cursor, only the trail", false);
|
||||
public static final NumericOption OPTION_DANCE_RGB_CURSOR_INC = new NumericOption("RGB cursor increment", "RGBCursorInc", "Amount of hue to shift, used for rainbow cursor override", 100, -2000, 2000) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("%.2f°", val / 1000f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_DANCE_CURSOR_TRAIL_OVERRIDE = new NumericOption("Trail length", "CursorTrailOverride", "Override cursor trail length", 20, 20, 600) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
if (val == 20) {
|
||||
return "Disabled";
|
||||
}
|
||||
return "" + val;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_DANCE_HIDE_OBJECTS = new ToggleOption("Don't draw objects", "HideObj", "If you only want to see cursors :)", false);
|
||||
public static final ToggleOption OPTION_DANCE_CIRLCE_IN_SLOW_SLIDERS = new ToggleOption("Do circles in slow sliders", "CircleInSlider", "Circle around sliderball in lazy & slow sliders", false);
|
||||
public static final ToggleOption OPTION_DANCE_CIRLCE_IN_LAZY_SLIDERS = new ToggleOption("Do circles in lazy sliders", "CircleInLazySlider", "Circle in hitcircle in lazy sliders", false);
|
||||
public static final ToggleOption OPTION_DANCE_HIDE_UI = new ToggleOption("Hide all UI", "HideUI", ".", true);
|
||||
public static final ToggleOption OPTION_DANCE_ENABLE_SB = new ToggleOption("Enable storyboard editor", "EnableStoryBoard", "Dance storyboard", false);
|
||||
public static final ToggleOption OPTION_PIPPI_ENABLE = new ToggleOption("Enable", "Pippi", "Move in circles like dancing pippi (osu! april fools joke 2016)", false);
|
||||
public static final NumericOption OPTION_PIPPI_RADIUS_PERCENT = new NumericOption("Radius", "PippiRad", "Radius of pippi, percentage of circle radius", 100, 0, 100) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return val + "%";
|
||||
}
|
||||
@Override
|
||||
public void setValue ( int value){
|
||||
super.setValue(value);
|
||||
Pippi.setRadiusPercent(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_PIPPI_ANGLE_INC_MUL = new NumericOption("Normal", "PippiAngIncMul", "How fast pippi's angle increments", 10, -200, 200) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("x%.1f", val / 10f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final NumericOption OPTION_PIPPI_ANGLE_INC_MUL_SLIDER = new NumericOption("In slider", "PippiAngIncMulSlider", "Same as above, but in sliders", 50, -200, 200) {
|
||||
@Override
|
||||
public String getValueString () {
|
||||
return String.format("x%.1f", val / 10f);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ToggleOption OPTION_PIPPI_SLIDER_FOLLOW_EXPAND = new ToggleOption("Followcircle expand", "PippiFollowExpand", "Increase radius in followcircles", false);
|
||||
public static final ToggleOption OPTION_PIPPI_PREVENT_WOBBLY_STREAMS = new ToggleOption("Prevent wobbly streams", "PippiPreventWobblyStreams", "Force linear mover while doing streams to prevent wobbly pippi", true);
|
||||
|
||||
}
|
||||
118
src/yugecin/opsudance/options/OptionsService.java
Normal file
118
src/yugecin/opsudance/options/OptionsService.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
import org.newdawn.slick.util.Log;
|
||||
import yugecin.opsudance.core.events.EventBus;
|
||||
import yugecin.opsudance.core.inject.Inject;
|
||||
import yugecin.opsudance.core.inject.InstanceContainer;
|
||||
import yugecin.opsudance.events.BubbleNotificationEvent;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author itdelatrisu (https://github.com/itdelatrisu) most functions are copied from itdelatrisu.opsu.Options.java
|
||||
*/
|
||||
public class OptionsService {
|
||||
|
||||
@Inject
|
||||
private Configuration config;
|
||||
|
||||
public static final HashMap<String, Option> optionMap = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public OptionsService(InstanceContainer instanceContainer) {
|
||||
Option.setInstanceContainer(instanceContainer);
|
||||
}
|
||||
|
||||
public static void registerOption(Option option) {
|
||||
optionMap.put(option.configurationName, option);
|
||||
}
|
||||
|
||||
public void loadOptions() {
|
||||
// if no config file, use default settings
|
||||
if (!config.OPTIONS_FILE.isFile()) {
|
||||
saveOptions();
|
||||
return;
|
||||
}
|
||||
|
||||
// read file
|
||||
try (BufferedReader in = new BufferedReader(new FileReader(config.OPTIONS_FILE))) {
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (line.length() < 2 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
int index = line.indexOf('=');
|
||||
if (index == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// read option
|
||||
String name = line.substring(0, index).trim();
|
||||
Option option = optionMap.get(name);
|
||||
if (option != null) {
|
||||
try {
|
||||
String value = line.substring(index + 1).trim();
|
||||
option.read(value);
|
||||
} catch (Exception e) {
|
||||
Log.warn(String.format("Format error in options file for line: '%s'.", line), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String err = String.format("Failed to read option file '%s'.", config.OPTIONS_FILE.getAbsolutePath());
|
||||
Log.error(err, e);
|
||||
EventBus.post(new BubbleNotificationEvent(err, BubbleNotificationEvent.COMMONCOLOR_RED));
|
||||
}
|
||||
config.loadDirectories();
|
||||
}
|
||||
|
||||
public void saveOptions() {
|
||||
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(config.OPTIONS_FILE), "utf-8"))) {
|
||||
// header
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
|
||||
String date = dateFormat.format(new Date());
|
||||
writer.write("# opsu! configuration");
|
||||
writer.newLine();
|
||||
writer.write("# last updated on ");
|
||||
writer.write(date);
|
||||
writer.newLine();
|
||||
writer.newLine();
|
||||
|
||||
// options
|
||||
for (Option option : optionMap.values()) {
|
||||
writer.write(option.configurationName);
|
||||
writer.write(" = ");
|
||||
writer.write(option.write());
|
||||
writer.newLine();
|
||||
}
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
String err = String.format("Failed to write to file '%s'.", config.OPTIONS_FILE.getAbsolutePath());
|
||||
Log.error(err, e);
|
||||
EventBus.post(new BubbleNotificationEvent(err, BubbleNotificationEvent.COMMONCOLOR_RED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
43
src/yugecin/opsudance/options/ToggleOption.java
Normal file
43
src/yugecin/opsudance/options/ToggleOption.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.options;
|
||||
|
||||
public class ToggleOption extends Option {
|
||||
|
||||
public boolean state;
|
||||
|
||||
public ToggleOption(String name, String configurationName, String description, boolean state) {
|
||||
super(name, configurationName, description);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
this.state = !this.state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write() {
|
||||
return Boolean.toString(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String s) {
|
||||
state = Boolean.parseBoolean(s);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user