Game options overhaul & new options.
- Separated options into "Display", "Music", and "Gameplay" tabs. - New options: VolumeHitSound, DimLevel, PerfectHit - Added options that were previously missing from Game Options screen. - Added sounds to Game Options screen. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
812b83af45
commit
2c2f28b441
|
@ -759,7 +759,10 @@ public class GameScore {
|
||||||
|
|
||||||
if (hitValue > 0) {
|
if (hitValue > 0) {
|
||||||
score += hitValue;
|
score += hitValue;
|
||||||
hitResultList.add(new OsuHitObjectResult(time, result, x, y, null));
|
if (!Options.isPerfectHitBurstEnabled())
|
||||||
|
; // hide perfect hit results
|
||||||
|
else
|
||||||
|
hitResultList.add(new OsuHitObjectResult(time, result, x, y, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,8 +779,10 @@ public class GameScore {
|
||||||
public void hitResult(int time, int result, float x, float y, Color color,
|
public void hitResult(int time, int result, float x, float y, Color color,
|
||||||
boolean end, byte hitSound) {
|
boolean end, byte hitSound) {
|
||||||
int hitValue = 0;
|
int hitValue = 0;
|
||||||
|
boolean perfectHit = false;
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case HIT_300:
|
case HIT_300:
|
||||||
|
perfectHit = true;
|
||||||
hitValue = 300;
|
hitValue = 300;
|
||||||
changeHealth(5f);
|
changeHealth(5f);
|
||||||
objectCount++;
|
objectCount++;
|
||||||
|
@ -852,6 +857,9 @@ public class GameScore {
|
||||||
comboEnd = 0;
|
comboEnd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hitResultList.add(new OsuHitObjectResult(time, result, x, y, color));
|
if (perfectHit && !Options.isPerfectHitBurstEnabled())
|
||||||
|
; // hide perfect hit results
|
||||||
|
else
|
||||||
|
hitResultList.add(new OsuHitObjectResult(time, result, x, y, color));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -228,7 +228,7 @@ public class SoundController {
|
||||||
// set volume
|
// set volume
|
||||||
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
|
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
|
||||||
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
|
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
|
||||||
gainControl.setValue(dB * sampleVolumeMultiplier);
|
gainControl.setValue(dB);
|
||||||
|
|
||||||
// play clip
|
// play clip
|
||||||
clip.setFramePosition(0);
|
clip.setFramePosition(0);
|
||||||
|
@ -255,7 +255,7 @@ public class SoundController {
|
||||||
if (sampleSetIndex < 0 || hitSound < 0)
|
if (sampleSetIndex < 0 || hitSound < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float volume = Options.getEffectVolume();
|
float volume = Options.getHitSoundVolume() * sampleVolumeMultiplier;
|
||||||
if (volume == 0f)
|
if (volume == 0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ public class SoundController {
|
||||||
if (sampleSetIndex < 0 || sound < 0 || sound > HIT_MAX)
|
if (sampleSetIndex < 0 || sound < 0 || sound > HIT_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
playClip(hitSounds[sampleSetIndex][sound], Options.getEffectVolume());
|
playClip(hitSounds[sampleSetIndex][sound],
|
||||||
|
Options.getHitSoundVolume() * sampleVolumeMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class Utils {
|
||||||
*/
|
*/
|
||||||
public static final Color
|
public static final Color
|
||||||
COLOR_BLACK_ALPHA = new Color(0, 0, 0, 0.5f),
|
COLOR_BLACK_ALPHA = new Color(0, 0, 0, 0.5f),
|
||||||
|
COLOR_WHITE_ALPHA = new Color(255, 255, 255, 0.5f),
|
||||||
COLOR_BLUE_DIVIDER = new Color(49, 94, 237),
|
COLOR_BLUE_DIVIDER = new Color(49, 94, 237),
|
||||||
COLOR_BLUE_BACKGROUND = new Color(74, 130, 255),
|
COLOR_BLUE_BACKGROUND = new Color(74, 130, 255),
|
||||||
COLOR_BLUE_BUTTON = new Color(50, 189, 237),
|
COLOR_BLUE_BUTTON = new Color(50, 189, 237),
|
||||||
|
@ -79,6 +80,11 @@ public class Utils {
|
||||||
*/
|
*/
|
||||||
private static GUIMenuButton backButton;
|
private static GUIMenuButton backButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab image (shared by other states).
|
||||||
|
*/
|
||||||
|
private static Image tab;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cursor image and trail.
|
* Cursor image and trail.
|
||||||
*/
|
*/
|
||||||
|
@ -131,7 +137,88 @@ public class Utils {
|
||||||
Log.error("Failed to set the cursor.", e);
|
Log.error("Failed to set the cursor.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load cursor images (TODO: cleanup)
|
loadCursor();
|
||||||
|
|
||||||
|
// create fonts
|
||||||
|
int height = container.getHeight();
|
||||||
|
float fontBase;
|
||||||
|
if (height <= 600)
|
||||||
|
fontBase = 9f;
|
||||||
|
else if (height < 800)
|
||||||
|
fontBase = 10f;
|
||||||
|
else if (height <= 900)
|
||||||
|
fontBase = 12f;
|
||||||
|
else
|
||||||
|
fontBase = 14f;
|
||||||
|
|
||||||
|
Font font = new Font("Lucida Sans Unicode", Font.PLAIN, (int) (fontBase * 4 / 3));
|
||||||
|
FONT_DEFAULT = new TrueTypeFont(font, false);
|
||||||
|
FONT_BOLD = new TrueTypeFont(font.deriveFont(Font.BOLD), false);
|
||||||
|
FONT_XLARGE = new TrueTypeFont(font.deriveFont(fontBase * 4), false);
|
||||||
|
FONT_LARGE = new TrueTypeFont(font.deriveFont(fontBase * 2), false);
|
||||||
|
FONT_MEDIUM = new TrueTypeFont(font.deriveFont(fontBase * 3 / 2), false);
|
||||||
|
FONT_SMALL = new TrueTypeFont(font.deriveFont(fontBase), false);
|
||||||
|
|
||||||
|
// tab image
|
||||||
|
tab = new Image("selection-tab.png");
|
||||||
|
float tabScale = (height * 0.033f) / tab.getHeight();
|
||||||
|
tab = tab.getScaledCopy(tabScale);
|
||||||
|
|
||||||
|
// back button
|
||||||
|
Image back = new Image("menu-back.png");
|
||||||
|
float scale = (height * 0.1f) / back.getHeight();
|
||||||
|
back = back.getScaledCopy(scale);
|
||||||
|
backButton = new GUIMenuButton(back,
|
||||||
|
back.getWidth() / 2f,
|
||||||
|
height - (back.getHeight() / 2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 'selection-tab' image.
|
||||||
|
*/
|
||||||
|
public static Image getTabImage() { return tab; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 'menu-back' GUIMenuButton.
|
||||||
|
*/
|
||||||
|
public static GUIMenuButton getBackButton() { return backButton; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws an image based on its center with a color filter.
|
||||||
|
* @param img the image to draw
|
||||||
|
* @param x the center x coordinate
|
||||||
|
* @param y the center y coordinate
|
||||||
|
* @param color the color filter to apply
|
||||||
|
*/
|
||||||
|
public static void drawCentered(Image img, float x, float y, Color color) {
|
||||||
|
img.draw(x - (img.getWidth() / 2f), y - (img.getHeight() / 2f), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws an animation based on its center.
|
||||||
|
* @param anim the animation to draw
|
||||||
|
* @param x the center x coordinate
|
||||||
|
* @param y the center y coordinate
|
||||||
|
*/
|
||||||
|
public static void drawCentered(Animation anim, float x, float y) {
|
||||||
|
anim.draw(x - (anim.getWidth() / 2f), y - (anim.getHeight() / 2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the cursor images.
|
||||||
|
* @throws SlickException
|
||||||
|
*/
|
||||||
|
public static void loadCursor() throws SlickException {
|
||||||
|
// destroy old cursors, if they exist
|
||||||
|
if (cursor != null)
|
||||||
|
cursor.destroy();
|
||||||
|
if (cursorTrail != null)
|
||||||
|
cursorTrail.destroy();
|
||||||
|
if (cursorMiddle != null)
|
||||||
|
cursorMiddle.destroy();
|
||||||
|
cursor = cursorTrail = cursorMiddle = null;
|
||||||
|
|
||||||
|
// TODO: cleanup
|
||||||
boolean skinCursor = new File(Options.getSkinDir(), "cursor.png").isFile();
|
boolean skinCursor = new File(Options.getSkinDir(), "cursor.png").isFile();
|
||||||
if (Options.isNewCursorEnabled()) {
|
if (Options.isNewCursorEnabled()) {
|
||||||
// load new cursor type
|
// load new cursor type
|
||||||
|
@ -156,60 +243,6 @@ public class Utils {
|
||||||
else
|
else
|
||||||
cursorTrail = new Image("cursortrail2.png");
|
cursorTrail = new Image("cursortrail2.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create fonts
|
|
||||||
int height = container.getHeight();
|
|
||||||
float fontBase;
|
|
||||||
if (height <= 600)
|
|
||||||
fontBase = 9f;
|
|
||||||
else if (height < 800)
|
|
||||||
fontBase = 10f;
|
|
||||||
else if (height <= 900)
|
|
||||||
fontBase = 12f;
|
|
||||||
else
|
|
||||||
fontBase = 14f;
|
|
||||||
|
|
||||||
Font font = new Font("Lucida Sans Unicode", Font.PLAIN, (int) (fontBase * 4 / 3));
|
|
||||||
FONT_DEFAULT = new TrueTypeFont(font, false);
|
|
||||||
FONT_BOLD = new TrueTypeFont(font.deriveFont(Font.BOLD), false);
|
|
||||||
FONT_XLARGE = new TrueTypeFont(font.deriveFont(fontBase * 4), false);
|
|
||||||
FONT_LARGE = new TrueTypeFont(font.deriveFont(fontBase * 2), false);
|
|
||||||
FONT_MEDIUM = new TrueTypeFont(font.deriveFont(fontBase * 3 / 2), false);
|
|
||||||
FONT_SMALL = new TrueTypeFont(font.deriveFont(fontBase), false);
|
|
||||||
|
|
||||||
// back button
|
|
||||||
Image back = new Image("menu-back.png");
|
|
||||||
float scale = (height * 0.1f) / back.getHeight();
|
|
||||||
back = back.getScaledCopy(scale);
|
|
||||||
backButton = new GUIMenuButton(back,
|
|
||||||
back.getWidth() / 2f,
|
|
||||||
height - (back.getHeight() / 2f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the 'back' GUIMenuButton.
|
|
||||||
*/
|
|
||||||
public static GUIMenuButton getBackButton() { return backButton; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draws an image based on its center with a color filter.
|
|
||||||
* @param img the image to draw
|
|
||||||
* @param x the center x coordinate
|
|
||||||
* @param y the center y coordinate
|
|
||||||
* @param color the color filter to apply
|
|
||||||
*/
|
|
||||||
public static void drawCentered(Image img, float x, float y, Color color) {
|
|
||||||
img.draw(x - (img.getWidth() / 2f), y - (img.getHeight() / 2f), color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draws an animation based on its center.
|
|
||||||
* @param anim the animation to draw
|
|
||||||
* @param x the center x coordinate
|
|
||||||
* @param y the center y coordinate
|
|
||||||
*/
|
|
||||||
public static void drawCentered(Animation anim, float x, float y) {
|
|
||||||
anim.draw(x - (anim.getWidth() / 2f), y - (anim.getHeight() / 2f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -262,8 +262,8 @@ public class Game extends BasicGameState {
|
||||||
int height = container.getHeight();
|
int height = container.getHeight();
|
||||||
|
|
||||||
// background
|
// background
|
||||||
if (!osu.drawBG(width, height, 0.7f))
|
g.setBackground(Color.black);
|
||||||
g.setBackground(Color.black);
|
osu.drawBG(width, height, Options.getBackgroundDim());
|
||||||
|
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (pauseTime > -1) // returning from pause screen
|
if (pauseTime > -1) // returning from pause screen
|
||||||
|
|
|
@ -20,6 +20,7 @@ package itdelatrisu.opsu.states;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GUIMenuButton;
|
import itdelatrisu.opsu.GUIMenuButton;
|
||||||
import itdelatrisu.opsu.Opsu;
|
import itdelatrisu.opsu.Opsu;
|
||||||
|
import itdelatrisu.opsu.SoundController;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -109,20 +110,94 @@ public class Options extends BasicGameState {
|
||||||
private static GUIMenuButton[] modButtons;
|
private static GUIMenuButton[] modButtons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Game option constants.
|
* Game options.
|
||||||
|
*/
|
||||||
|
private enum GameOption {
|
||||||
|
NULL,
|
||||||
|
SCREEN_RESOLUTION,
|
||||||
|
// FULLSCREEN,
|
||||||
|
TARGET_FPS,
|
||||||
|
MUSIC_VOLUME,
|
||||||
|
EFFECT_VOLUME,
|
||||||
|
HITSOUND_VOLUME,
|
||||||
|
MUSIC_OFFSET,
|
||||||
|
SCREENSHOT_FORMAT,
|
||||||
|
SHOW_FPS,
|
||||||
|
SHOW_HIT_LIGHTING,
|
||||||
|
SHOW_COMBO_BURSTS,
|
||||||
|
NEW_CURSOR,
|
||||||
|
DYNAMIC_BACKGROUND,
|
||||||
|
SHOW_PERFECT_HIT,
|
||||||
|
BACKGROUND_DIM;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option tab constants.
|
||||||
*/
|
*/
|
||||||
private static final int
|
private static final int
|
||||||
OPTIONS_SCREEN_RESOLUTION = 0,
|
TAB_DISPLAY = 0,
|
||||||
// OPTIONS_FULLSCREEN = ,
|
TAB_MUSIC = 1,
|
||||||
OPTIONS_TARGET_FPS = 1,
|
TAB_GAMEPLAY = 2,
|
||||||
OPTIONS_MUSIC_VOLUME = 2,
|
TAB_MAX = 3; // not a tab
|
||||||
OPTIONS_EFFECT_VOLUME = 3,
|
|
||||||
OPTIONS_MUSIC_OFFSET = 4,
|
/**
|
||||||
OPTIONS_SCREENSHOT_FORMAT = 5,
|
* Option tab names.
|
||||||
OPTIONS_DISPLAY_FPS = 6,
|
*/
|
||||||
OPTIONS_HIT_LIGHTING = 7,
|
private static final String[] TAB_NAMES = {
|
||||||
OPTIONS_COMBO_BURSTS = 8,
|
"Display",
|
||||||
OPTIONS_MAX = 9; // not an option
|
"Music",
|
||||||
|
"Gameplay"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option tab buttons.
|
||||||
|
*/
|
||||||
|
private GUIMenuButton[] optionTabs = new GUIMenuButton[TAB_MAX];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current tab.
|
||||||
|
*/
|
||||||
|
private static int currentTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display options.
|
||||||
|
*/
|
||||||
|
private static final GameOption[] displayOptions = {
|
||||||
|
GameOption.SCREEN_RESOLUTION,
|
||||||
|
// GameOption.FULLSCREEN,
|
||||||
|
GameOption.TARGET_FPS,
|
||||||
|
GameOption.SHOW_FPS,
|
||||||
|
GameOption.SCREENSHOT_FORMAT,
|
||||||
|
GameOption.NEW_CURSOR,
|
||||||
|
GameOption.DYNAMIC_BACKGROUND
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Music options.
|
||||||
|
*/
|
||||||
|
private static final GameOption[] musicOptions = {
|
||||||
|
GameOption.MUSIC_VOLUME,
|
||||||
|
GameOption.EFFECT_VOLUME,
|
||||||
|
GameOption.HITSOUND_VOLUME,
|
||||||
|
GameOption.MUSIC_OFFSET
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gameplay options.
|
||||||
|
*/
|
||||||
|
private static final GameOption[] gameplayOptions = {
|
||||||
|
GameOption.BACKGROUND_DIM,
|
||||||
|
GameOption.SHOW_HIT_LIGHTING,
|
||||||
|
GameOption.SHOW_COMBO_BURSTS,
|
||||||
|
GameOption.SHOW_PERFECT_HIT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max number of options displayed on one screen.
|
||||||
|
*/
|
||||||
|
private static int maxOptionsScreen = Math.max(
|
||||||
|
Math.max(displayOptions.length, musicOptions.length),
|
||||||
|
gameplayOptions.length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Screen resolutions.
|
* Screen resolutions.
|
||||||
|
@ -184,6 +259,11 @@ public class Options extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
private static int effectVolume = 20;
|
private static int effectVolume = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default hit sound volume.
|
||||||
|
*/
|
||||||
|
private static int hitSoundVolume = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset time, in milliseconds, for music position-related elements.
|
* Offset time, in milliseconds, for music position-related elements.
|
||||||
*/
|
*/
|
||||||
|
@ -214,6 +294,16 @@ public class Options extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
private static boolean dynamicBackground = true;
|
private static boolean dynamicBackground = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not to display perfect hit results.
|
||||||
|
*/
|
||||||
|
private static boolean showPerfectHit = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percentage to dim background images during gameplay.
|
||||||
|
*/
|
||||||
|
private static int backgroundDim = 30;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Game option coordinate modifiers (for drawing).
|
* Game option coordinate modifiers (for drawing).
|
||||||
*/
|
*/
|
||||||
|
@ -223,6 +313,7 @@ public class Options extends BasicGameState {
|
||||||
private GameContainer container;
|
private GameContainer container;
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
private Input input;
|
private Input input;
|
||||||
|
private Graphics g;
|
||||||
private int state;
|
private int state;
|
||||||
private boolean init = false;
|
private boolean init = false;
|
||||||
|
|
||||||
|
@ -236,6 +327,7 @@ public class Options extends BasicGameState {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.input = container.getInput();
|
this.input = container.getInput();
|
||||||
|
this.g = container.getGraphics();
|
||||||
|
|
||||||
Utils.init(container, game);
|
Utils.init(container, game);
|
||||||
|
|
||||||
|
@ -243,8 +335,16 @@ public class Options extends BasicGameState {
|
||||||
int height = container.getHeight();
|
int height = container.getHeight();
|
||||||
|
|
||||||
// game option coordinate modifiers
|
// game option coordinate modifiers
|
||||||
textY = 10 + (Utils.FONT_XLARGE.getLineHeight() * 3 / 2);
|
textY = 20 + (Utils.FONT_XLARGE.getLineHeight() * 3 / 2);
|
||||||
offsetY = (int) (((height * 0.8f) - textY) / OPTIONS_MAX);
|
offsetY = (int) (((height * 0.8f) - textY) / maxOptionsScreen);
|
||||||
|
|
||||||
|
// option tabs
|
||||||
|
Image tab = Utils.getTabImage();
|
||||||
|
float tabX = (width / 50) + (tab.getWidth() / 2f);
|
||||||
|
float tabY = 15 + Utils.FONT_XLARGE.getHeight() + (tab.getHeight() / 2f);
|
||||||
|
float tabOffset = tab.getWidth() * 0.85f;
|
||||||
|
for (int i = 0; i < optionTabs.length; i++)
|
||||||
|
optionTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
modsActive = new boolean[MOD_MAX];
|
modsActive = new boolean[MOD_MAX];
|
||||||
|
@ -305,49 +405,38 @@ public class Options extends BasicGameState {
|
||||||
// game options
|
// game options
|
||||||
g.setLineWidth(1f);
|
g.setLineWidth(1f);
|
||||||
g.setFont(Utils.FONT_LARGE);
|
g.setFont(Utils.FONT_LARGE);
|
||||||
this.drawOption(g, OPTIONS_SCREEN_RESOLUTION, "Screen Resolution",
|
switch (currentTab) {
|
||||||
String.format("%dx%d", resolutions[resolutionIndex][0], resolutions[resolutionIndex][1]),
|
case TAB_DISPLAY:
|
||||||
"Restart to apply resolution changes."
|
for (int i = 0; i < displayOptions.length; i++)
|
||||||
);
|
drawOption(displayOptions[i], i);
|
||||||
// this.drawOption(g, OPTIONS_FULLSCREEN, "Fullscreen Mode",
|
break;
|
||||||
// fullscreen ? "Yes" : "No",
|
case TAB_MUSIC:
|
||||||
// "Restart to apply changes."
|
for (int i = 0; i < musicOptions.length; i++)
|
||||||
// );
|
drawOption(musicOptions[i], i);
|
||||||
this.drawOption(g, OPTIONS_TARGET_FPS, "Frame Limiter",
|
break;
|
||||||
String.format("%dfps", getTargetFPS()),
|
case TAB_GAMEPLAY:
|
||||||
"Higher values may cause high CPU usage."
|
for (int i = 0; i < gameplayOptions.length; i++)
|
||||||
);
|
drawOption(gameplayOptions[i], i);
|
||||||
this.drawOption(g, OPTIONS_MUSIC_VOLUME, "Music Volume",
|
break;
|
||||||
String.format("%d%%", musicVolume),
|
}
|
||||||
"Global music volume."
|
|
||||||
);
|
// option tabs
|
||||||
this.drawOption(g, OPTIONS_EFFECT_VOLUME, "Effect Volume",
|
g.setColor(Color.white);
|
||||||
String.format("%d%%", effectVolume),
|
Image tab = optionTabs[0].getImage();
|
||||||
"Sound effect volume."
|
float tabTextY = optionTabs[0].getY() - (tab.getHeight() / 2f);
|
||||||
);
|
for (int i = optionTabs.length - 1; i >= 0; i--) {
|
||||||
this.drawOption(g, OPTIONS_MUSIC_OFFSET, "Music Offset",
|
tab.setAlpha((i == currentTab) ? 1.0f : 0.7f);
|
||||||
String.format("%dms", musicOffset),
|
optionTabs[i].draw();
|
||||||
"Adjust this value if hit objects are out of sync."
|
float tabTextX = optionTabs[i].getX() - (Utils.FONT_MEDIUM.getWidth(TAB_NAMES[i]) / 2);
|
||||||
);
|
Utils.FONT_MEDIUM.drawString(tabTextX, tabTextY, TAB_NAMES[i], Color.white);
|
||||||
this.drawOption(g, OPTIONS_SCREENSHOT_FORMAT, "Screenshot Format",
|
}
|
||||||
screenshotFormat[screenshotFormatIndex].toUpperCase(),
|
g.setLineWidth(2f);
|
||||||
"Press F12 to take a screenshot."
|
float lineY = optionTabs[0].getY() + (tab.getHeight() / 2f);
|
||||||
);
|
g.drawLine(0, lineY, width, lineY);
|
||||||
this.drawOption(g, OPTIONS_DISPLAY_FPS, "Show FPS Counter",
|
g.resetLineWidth();
|
||||||
showFPS ? "Yes" : "No",
|
|
||||||
null
|
|
||||||
);
|
|
||||||
this.drawOption(g, OPTIONS_HIT_LIGHTING, "Show Hit Lighting",
|
|
||||||
showHitLighting ? "Yes" : "No",
|
|
||||||
null
|
|
||||||
);
|
|
||||||
this.drawOption(g, OPTIONS_COMBO_BURSTS, "Show Combo Bursts",
|
|
||||||
showComboBursts ? "Yes" : "No",
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
Utils.FONT_LARGE.drawString(width * 0.02f, height * 0.8f, "Game Mods:", Color.white);
|
Utils.FONT_LARGE.drawString(width / 30, height * 0.8f, "Game Mods:", Color.white);
|
||||||
for (int i = 0; i < modButtons.length; i++)
|
for (int i = 0; i < modButtons.length; i++)
|
||||||
modButtons[i].draw();
|
modButtons[i].draw();
|
||||||
|
|
||||||
|
@ -374,13 +463,26 @@ public class Options extends BasicGameState {
|
||||||
|
|
||||||
// back
|
// back
|
||||||
if (Utils.getBackButton().contains(x, y)) {
|
if (Utils.getBackButton().contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUBACK);
|
||||||
game.enterState(Opsu.STATE_SONGMENU, new EmptyTransition(), new FadeInTransition(Color.black));
|
game.enterState(Opsu.STATE_SONGMENU, new EmptyTransition(), new FadeInTransition(Color.black));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// option tabs
|
||||||
|
for (int i = 0; i < optionTabs.length; i++) {
|
||||||
|
if (optionTabs[i].contains(x, y)) {
|
||||||
|
if (i != currentTab) {
|
||||||
|
currentTab = i;
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUCLICK);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
for (int i = 0; i < modButtons.length; i++) {
|
for (int i = 0; i < modButtons.length; i++) {
|
||||||
if (modButtons[i].contains(x, y)) {
|
if (modButtons[i].contains(x, y)) {
|
||||||
|
boolean prev = modsActive[i];
|
||||||
toggleMod(i);
|
toggleMod(i);
|
||||||
|
|
||||||
// mutually exclusive mods
|
// mutually exclusive mods
|
||||||
|
@ -397,39 +499,52 @@ public class Options extends BasicGameState {
|
||||||
} else if (modsActive[MOD_SUDDEN_DEATH] && modsActive[MOD_NO_FAIL])
|
} else if (modsActive[MOD_SUDDEN_DEATH] && modsActive[MOD_NO_FAIL])
|
||||||
toggleMod((i == MOD_SUDDEN_DEATH) ? MOD_NO_FAIL : MOD_SUDDEN_DEATH);
|
toggleMod((i == MOD_SUDDEN_DEATH) ? MOD_NO_FAIL : MOD_SUDDEN_DEATH);
|
||||||
|
|
||||||
|
if (modsActive[i] != prev)
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUCLICK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// options (click only)
|
// options (click only)
|
||||||
if (isOptionClicked(OPTIONS_SCREEN_RESOLUTION, y)) {
|
switch (getClickedOption(y)) {
|
||||||
|
case SCREEN_RESOLUTION:
|
||||||
resolutionIndex = (resolutionIndex + 1) % resolutions.length;
|
resolutionIndex = (resolutionIndex + 1) % resolutions.length;
|
||||||
return;
|
break;
|
||||||
}
|
// case FULLSCREEN:
|
||||||
// if (isOptionClicked(OPTIONS_FULLSCREEN, y)) {
|
|
||||||
// fullscreen = !fullscreen;
|
// fullscreen = !fullscreen;
|
||||||
// return;
|
// break;
|
||||||
// }
|
case TARGET_FPS:
|
||||||
if (isOptionClicked(OPTIONS_TARGET_FPS, y)) {
|
|
||||||
targetFPSindex = (targetFPSindex + 1) % targetFPS.length;
|
targetFPSindex = (targetFPSindex + 1) % targetFPS.length;
|
||||||
container.setTargetFrameRate(getTargetFPS());
|
container.setTargetFrameRate(getTargetFPS());
|
||||||
return;
|
break;
|
||||||
}
|
case SCREENSHOT_FORMAT:
|
||||||
if (isOptionClicked(OPTIONS_SCREENSHOT_FORMAT, y)) {
|
|
||||||
screenshotFormatIndex = (screenshotFormatIndex + 1) % screenshotFormat.length;
|
screenshotFormatIndex = (screenshotFormatIndex + 1) % screenshotFormat.length;
|
||||||
return;
|
break;
|
||||||
}
|
case SHOW_FPS:
|
||||||
if (isOptionClicked(OPTIONS_DISPLAY_FPS, y)) {
|
|
||||||
showFPS = !showFPS;
|
showFPS = !showFPS;
|
||||||
return;
|
break;
|
||||||
}
|
case SHOW_HIT_LIGHTING:
|
||||||
if (isOptionClicked(OPTIONS_HIT_LIGHTING, y)) {
|
|
||||||
showHitLighting = !showHitLighting;
|
showHitLighting = !showHitLighting;
|
||||||
return;
|
break;
|
||||||
}
|
case SHOW_COMBO_BURSTS:
|
||||||
if (isOptionClicked(OPTIONS_COMBO_BURSTS, y)) {
|
|
||||||
showComboBursts = !showComboBursts;
|
showComboBursts = !showComboBursts;
|
||||||
return;
|
break;
|
||||||
|
case NEW_CURSOR:
|
||||||
|
newCursor = !newCursor;
|
||||||
|
try {
|
||||||
|
Utils.loadCursor();
|
||||||
|
} catch (SlickException e) {
|
||||||
|
Log.error("Failed to load cursor.", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DYNAMIC_BACKGROUND:
|
||||||
|
dynamicBackground = !dynamicBackground;
|
||||||
|
break;
|
||||||
|
case SHOW_PERFECT_HIT:
|
||||||
|
showPerfectHit = !showPerfectHit;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,30 +566,45 @@ public class Options extends BasicGameState {
|
||||||
diff = ((diff > 0) ? 1 : -1) * multiplier;
|
diff = ((diff > 0) ? 1 : -1) * multiplier;
|
||||||
|
|
||||||
// options (drag only)
|
// options (drag only)
|
||||||
if (isOptionClicked(OPTIONS_MUSIC_VOLUME, oldy)) {
|
switch (getClickedOption(oldy)) {
|
||||||
|
case MUSIC_VOLUME:
|
||||||
musicVolume += diff;
|
musicVolume += diff;
|
||||||
if (musicVolume < 0)
|
if (musicVolume < 0)
|
||||||
musicVolume = 0;
|
musicVolume = 0;
|
||||||
else if (musicVolume > 100)
|
else if (musicVolume > 100)
|
||||||
musicVolume = 100;
|
musicVolume = 100;
|
||||||
container.setMusicVolume(getMusicVolume());
|
container.setMusicVolume(getMusicVolume());
|
||||||
return;
|
break;
|
||||||
}
|
case EFFECT_VOLUME:
|
||||||
if (isOptionClicked(OPTIONS_EFFECT_VOLUME, oldy)) {
|
|
||||||
effectVolume += diff;
|
effectVolume += diff;
|
||||||
if (effectVolume < 0)
|
if (effectVolume < 0)
|
||||||
effectVolume = 0;
|
effectVolume = 0;
|
||||||
else if (effectVolume > 100)
|
else if (effectVolume > 100)
|
||||||
effectVolume = 100;
|
effectVolume = 100;
|
||||||
return;
|
break;
|
||||||
}
|
case HITSOUND_VOLUME:
|
||||||
if (isOptionClicked(OPTIONS_MUSIC_OFFSET, oldy)) {
|
hitSoundVolume += diff;
|
||||||
|
if (hitSoundVolume < 0)
|
||||||
|
hitSoundVolume = 0;
|
||||||
|
else if (hitSoundVolume > 100)
|
||||||
|
hitSoundVolume = 100;
|
||||||
|
break;
|
||||||
|
case MUSIC_OFFSET:
|
||||||
musicOffset += diff;
|
musicOffset += diff;
|
||||||
if (musicOffset < -500)
|
if (musicOffset < -500)
|
||||||
musicOffset = -500;
|
musicOffset = -500;
|
||||||
else if (musicOffset > 500)
|
else if (musicOffset > 500)
|
||||||
musicOffset = 500;
|
musicOffset = 500;
|
||||||
return;
|
break;
|
||||||
|
case BACKGROUND_DIM:
|
||||||
|
backgroundDim += diff;
|
||||||
|
if (backgroundDim < 0)
|
||||||
|
backgroundDim = 0;
|
||||||
|
else if (backgroundDim > 100)
|
||||||
|
backgroundDim = 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,43 +612,179 @@ public class Options extends BasicGameState {
|
||||||
public void keyPressed(int key, char c) {
|
public void keyPressed(int key, char c) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case Input.KEY_ESCAPE:
|
case Input.KEY_ESCAPE:
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUBACK);
|
||||||
game.enterState(Opsu.STATE_SONGMENU, new EmptyTransition(), new FadeInTransition(Color.black));
|
game.enterState(Opsu.STATE_SONGMENU, new EmptyTransition(), new FadeInTransition(Color.black));
|
||||||
break;
|
break;
|
||||||
case Input.KEY_F12:
|
case Input.KEY_F12:
|
||||||
Utils.takeScreenShot();
|
Utils.takeScreenShot();
|
||||||
break;
|
break;
|
||||||
|
case Input.KEY_TAB:
|
||||||
|
int i = 1;
|
||||||
|
if (input.isKeyDown(Input.KEY_LSHIFT) || input.isKeyDown(Input.KEY_RSHIFT))
|
||||||
|
i = TAB_MAX - 1;
|
||||||
|
currentTab = (currentTab + i) % TAB_MAX;
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUCLICK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
|
throws SlickException {
|
||||||
|
currentTab = TAB_DISPLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a game option.
|
||||||
|
* @param option the option (OPTION_* constant)
|
||||||
|
* @param pos the position to draw at
|
||||||
|
*/
|
||||||
|
private void drawOption(GameOption option, int pos) {
|
||||||
|
switch (option) {
|
||||||
|
case SCREEN_RESOLUTION:
|
||||||
|
drawOption(pos, "Screen Resolution",
|
||||||
|
String.format("%dx%d", resolutions[resolutionIndex][0], resolutions[resolutionIndex][1]),
|
||||||
|
"Restart to apply resolution changes."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
// case FULLSCREEN:
|
||||||
|
// drawOption(pos, "Fullscreen Mode",
|
||||||
|
// fullscreen ? "Yes" : "No",
|
||||||
|
// "Restart to apply changes."
|
||||||
|
// );
|
||||||
|
// break;
|
||||||
|
case TARGET_FPS:
|
||||||
|
drawOption(pos, "Frame Limiter",
|
||||||
|
String.format("%dfps", getTargetFPS()),
|
||||||
|
"Higher values may cause high CPU usage."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SCREENSHOT_FORMAT:
|
||||||
|
drawOption(pos, "Screenshot Format",
|
||||||
|
screenshotFormat[screenshotFormatIndex].toUpperCase(),
|
||||||
|
"Press F12 to take a screenshot."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHOW_FPS:
|
||||||
|
drawOption(pos, "Show FPS Counter",
|
||||||
|
showFPS ? "Yes" : "No",
|
||||||
|
"Show an FPS counter in the bottom-right hand corner."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case NEW_CURSOR:
|
||||||
|
drawOption(pos, "Enable New Cursor",
|
||||||
|
newCursor ? "Yes" : "No",
|
||||||
|
"Use the new cursor style (may cause higher CPU usage)."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case DYNAMIC_BACKGROUND:
|
||||||
|
drawOption(pos, "Enable Dynamic Backgrounds",
|
||||||
|
dynamicBackground ? "Yes" : "No",
|
||||||
|
"The song background will be used as the main menu background."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MUSIC_VOLUME:
|
||||||
|
drawOption(pos, "Music Volume",
|
||||||
|
String.format("%d%%", musicVolume),
|
||||||
|
"Global music volume."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFFECT_VOLUME:
|
||||||
|
drawOption(pos, "Effect Volume",
|
||||||
|
String.format("%d%%", effectVolume),
|
||||||
|
"Volume of menu and game sounds."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case HITSOUND_VOLUME:
|
||||||
|
drawOption(pos, "Hit Sound Volume",
|
||||||
|
String.format("%d%%", hitSoundVolume),
|
||||||
|
"Volume of hit sounds."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MUSIC_OFFSET:
|
||||||
|
drawOption(pos, "Music Offset",
|
||||||
|
String.format("%dms", musicOffset),
|
||||||
|
"Adjust this value if hit objects are out of sync."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case BACKGROUND_DIM:
|
||||||
|
drawOption(pos, "Background Dim",
|
||||||
|
String.format("%d%%", backgroundDim),
|
||||||
|
"Percentage to dim the background image during gameplay."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHOW_HIT_LIGHTING:
|
||||||
|
drawOption(pos, "Show Hit Lighting",
|
||||||
|
showHitLighting ? "Yes" : "No",
|
||||||
|
"Adds an effect behind hit explosions."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHOW_COMBO_BURSTS:
|
||||||
|
drawOption(pos, "Show Combo Bursts",
|
||||||
|
showComboBursts ? "Yes" : "No",
|
||||||
|
"A character image is displayed at combo milestones."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHOW_PERFECT_HIT:
|
||||||
|
drawOption(pos, "Show Perfect Hits",
|
||||||
|
showPerfectHit ? "Yes" : "No",
|
||||||
|
"Whether to show perfect hit result bursts (300s, slider ticks)."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a game option.
|
* Draws a game option.
|
||||||
* @param g the graphics context
|
* @param pos the element position
|
||||||
* @param pos the element position (OPTIONS_* constants)
|
|
||||||
* @param label the option name
|
* @param label the option name
|
||||||
* @param value the option value
|
* @param value the option value
|
||||||
* @param notes additional notes (optional)
|
* @param notes additional notes (optional)
|
||||||
*/
|
*/
|
||||||
private void drawOption(Graphics g, int pos, String label, String value, String notes) {
|
private void drawOption(int pos, String label, String value, String notes) {
|
||||||
int width = container.getWidth();
|
int width = container.getWidth();
|
||||||
int textHeight = Utils.FONT_LARGE.getHeight();
|
int textHeight = Utils.FONT_LARGE.getHeight();
|
||||||
float y = textY + (pos * offsetY);
|
float y = textY + (pos * offsetY);
|
||||||
|
|
||||||
g.drawString(label, width / 50, y);
|
g.setColor(Color.white);
|
||||||
|
g.drawString(label, width / 30, y);
|
||||||
g.drawString(value, width / 2, y);
|
g.drawString(value, width / 2, y);
|
||||||
g.drawLine(0, y + textHeight, width, y + textHeight);
|
|
||||||
if (notes != null)
|
if (notes != null)
|
||||||
Utils.FONT_SMALL.drawString(width / 50, y + textHeight, notes);
|
Utils.FONT_SMALL.drawString(width / 30, y + textHeight, notes);
|
||||||
|
g.setColor(Utils.COLOR_WHITE_ALPHA);
|
||||||
|
g.drawLine(0, y + textHeight, width, y + textHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not an option was clicked.
|
* Returns the option clicked.
|
||||||
* @param pos the element position (OPTIONS_* constants)
|
* If no option clicked, -1 will be returned.
|
||||||
* @param y the y coordinate of the click
|
* @param y the y coordinate
|
||||||
* @return true if clicked
|
* @return the option (OPTION_* constant)
|
||||||
*/
|
*/
|
||||||
private boolean isOptionClicked(int pos, int y) {
|
private GameOption getClickedOption(int y) {
|
||||||
return (y > textY + (offsetY * pos) - Utils.FONT_LARGE.getHeight() &&
|
GameOption option = GameOption.NULL;
|
||||||
y < textY + (offsetY * pos) + Utils.FONT_LARGE.getHeight());
|
|
||||||
|
if (y < textY || y > textY + (offsetY * maxOptionsScreen))
|
||||||
|
return option;
|
||||||
|
|
||||||
|
int index = (y - textY + Utils.FONT_LARGE.getHeight()) / offsetY;
|
||||||
|
switch (currentTab) {
|
||||||
|
case TAB_DISPLAY:
|
||||||
|
if (index < displayOptions.length)
|
||||||
|
option = displayOptions[index];
|
||||||
|
break;
|
||||||
|
case TAB_MUSIC:
|
||||||
|
if (index < musicOptions.length)
|
||||||
|
option = musicOptions[index];
|
||||||
|
break;
|
||||||
|
case TAB_GAMEPLAY:
|
||||||
|
if (index < gameplayOptions.length)
|
||||||
|
option = gameplayOptions[index];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -563,6 +829,12 @@ public class Options extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
public static float getEffectVolume() { return effectVolume / 100f; }
|
public static float getEffectVolume() { return effectVolume / 100f; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default sound effect volume.
|
||||||
|
* @return the sound volume [0, 1]
|
||||||
|
*/
|
||||||
|
public static float getHitSoundVolume() { return hitSoundVolume / 100f; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the music offset time.
|
* Returns the music offset time.
|
||||||
* @return the offset (in milliseconds)
|
* @return the offset (in milliseconds)
|
||||||
|
@ -623,6 +895,18 @@ public class Options extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
public static boolean isDynamicBackgroundEnabled() { return dynamicBackground; }
|
public static boolean isDynamicBackgroundEnabled() { return dynamicBackground; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not to show perfect hit result bursts.
|
||||||
|
* @return true if enabled
|
||||||
|
*/
|
||||||
|
public static boolean isPerfectHitBurstEnabled() { return showPerfectHit; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the background dim level.
|
||||||
|
* @return the alpha level [0, 1]
|
||||||
|
*/
|
||||||
|
public static float getBackgroundDim() { return (100 - backgroundDim) / 100f; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current beatmap directory.
|
* Returns the current beatmap directory.
|
||||||
* If invalid, this will attempt to search for the directory,
|
* If invalid, this will attempt to search for the directory,
|
||||||
|
@ -687,6 +971,11 @@ public class Options extends BasicGameState {
|
||||||
case "Skin":
|
case "Skin":
|
||||||
skinDir = new File(value);
|
skinDir = new File(value);
|
||||||
break;
|
break;
|
||||||
|
case "Port":
|
||||||
|
i = Integer.parseInt(value);
|
||||||
|
if (i > 0 && i <= 65535)
|
||||||
|
port = i;
|
||||||
|
break;
|
||||||
case "ScreenResolution":
|
case "ScreenResolution":
|
||||||
i = Integer.parseInt(value);
|
i = Integer.parseInt(value);
|
||||||
if (i >= 0 && i < resolutions.length)
|
if (i >= 0 && i < resolutions.length)
|
||||||
|
@ -700,6 +989,20 @@ public class Options extends BasicGameState {
|
||||||
if (i >= 0 && i <= targetFPS.length)
|
if (i >= 0 && i <= targetFPS.length)
|
||||||
targetFPSindex = i;
|
targetFPSindex = i;
|
||||||
break;
|
break;
|
||||||
|
case "ScreenshotFormat":
|
||||||
|
i = Integer.parseInt(value);
|
||||||
|
if (i >= 0 && i < screenshotFormat.length)
|
||||||
|
screenshotFormatIndex = i;
|
||||||
|
break;
|
||||||
|
case "FpsCounter":
|
||||||
|
showFPS = Boolean.parseBoolean(value);
|
||||||
|
break;
|
||||||
|
case "NewCursor":
|
||||||
|
newCursor = Boolean.parseBoolean(value);
|
||||||
|
break;
|
||||||
|
case "DynamicBackground":
|
||||||
|
dynamicBackground = Boolean.parseBoolean(value);
|
||||||
|
break;
|
||||||
case "VolumeMusic":
|
case "VolumeMusic":
|
||||||
i = Integer.parseInt(value);
|
i = Integer.parseInt(value);
|
||||||
if (i >= 0 && i <= 100)
|
if (i >= 0 && i <= 100)
|
||||||
|
@ -710,18 +1013,20 @@ public class Options extends BasicGameState {
|
||||||
if (i >= 0 && i <= 100)
|
if (i >= 0 && i <= 100)
|
||||||
effectVolume = i;
|
effectVolume = i;
|
||||||
break;
|
break;
|
||||||
|
case "VolumeHitSound":
|
||||||
|
i = Integer.parseInt(value);
|
||||||
|
if (i >= 0 && i <= 100)
|
||||||
|
hitSoundVolume = i;
|
||||||
|
break;
|
||||||
case "Offset":
|
case "Offset":
|
||||||
i = Integer.parseInt(value);
|
i = Integer.parseInt(value);
|
||||||
if (i >= -500 && i <= 500)
|
if (i >= -500 && i <= 500)
|
||||||
musicOffset = i;
|
musicOffset = i;
|
||||||
break;
|
break;
|
||||||
case "ScreenshotFormat":
|
case "DimLevel":
|
||||||
i = Integer.parseInt(value);
|
i = Integer.parseInt(value);
|
||||||
if (i >= 0 && i < screenshotFormat.length)
|
if (i >= 0 && i <= 100)
|
||||||
screenshotFormatIndex = i;
|
backgroundDim = i;
|
||||||
break;
|
|
||||||
case "FpsCounter":
|
|
||||||
showFPS = Boolean.parseBoolean(value);
|
|
||||||
break;
|
break;
|
||||||
case "HitLighting":
|
case "HitLighting":
|
||||||
showHitLighting = Boolean.parseBoolean(value);
|
showHitLighting = Boolean.parseBoolean(value);
|
||||||
|
@ -729,18 +1034,8 @@ public class Options extends BasicGameState {
|
||||||
case "ComboBurst":
|
case "ComboBurst":
|
||||||
showComboBursts = Boolean.parseBoolean(value);
|
showComboBursts = Boolean.parseBoolean(value);
|
||||||
break;
|
break;
|
||||||
|
case "PerfectHit":
|
||||||
// custom entries
|
showPerfectHit = Boolean.parseBoolean(value);
|
||||||
case "Port":
|
|
||||||
i = Integer.parseInt(value);
|
|
||||||
if (i > 0 && i <= 65535)
|
|
||||||
port = i;
|
|
||||||
break;
|
|
||||||
case "NewCursor":
|
|
||||||
newCursor = Boolean.parseBoolean(value);
|
|
||||||
break;
|
|
||||||
case "DynamicBackground":
|
|
||||||
dynamicBackground = Boolean.parseBoolean(value);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -773,33 +1068,37 @@ public class Options extends BasicGameState {
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("Skin = %s", getSkinDir().getAbsolutePath()));
|
writer.write(String.format("Skin = %s", getSkinDir().getAbsolutePath()));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
writer.write(String.format("Port = %d", port));
|
||||||
|
writer.newLine();
|
||||||
writer.write(String.format("ScreenResolution = %d", resolutionIndex));
|
writer.write(String.format("ScreenResolution = %d", resolutionIndex));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
// writer.write(String.format("Fullscreen = %b", fullscreen));
|
// writer.write(String.format("Fullscreen = %b", fullscreen));
|
||||||
// writer.newLine();
|
// writer.newLine();
|
||||||
writer.write(String.format("FrameSync = %d", targetFPSindex));
|
writer.write(String.format("FrameSync = %d", targetFPSindex));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
writer.write(String.format("FpsCounter = %b", showFPS));
|
||||||
|
writer.newLine();
|
||||||
|
writer.write(String.format("ScreenshotFormat = %d", screenshotFormatIndex));
|
||||||
|
writer.newLine();
|
||||||
|
writer.write(String.format("NewCursor = %b", newCursor));
|
||||||
|
writer.newLine();
|
||||||
|
writer.write(String.format("DynamicBackground = %b", dynamicBackground));
|
||||||
|
writer.newLine();
|
||||||
writer.write(String.format("VolumeMusic = %d", musicVolume));
|
writer.write(String.format("VolumeMusic = %d", musicVolume));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("VolumeEffect = %d", effectVolume));
|
writer.write(String.format("VolumeEffect = %d", effectVolume));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
writer.write(String.format("VolumeHitSound = %d", hitSoundVolume));
|
||||||
|
writer.newLine();
|
||||||
writer.write(String.format("Offset = %d", musicOffset));
|
writer.write(String.format("Offset = %d", musicOffset));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("ScreenshotFormat = %d", screenshotFormatIndex));
|
writer.write(String.format("DimLevel = %d", backgroundDim));
|
||||||
writer.newLine();
|
|
||||||
writer.write(String.format("FpsCounter = %b", showFPS));
|
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("HitLighting = %b", showHitLighting));
|
writer.write(String.format("HitLighting = %b", showHitLighting));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("ComboBurst = %b", showComboBursts));
|
writer.write(String.format("ComboBurst = %b", showComboBursts));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
writer.write(String.format("PerfectHit = %b", showPerfectHit));
|
||||||
// custom entries
|
|
||||||
writer.write(String.format("Port = %d", port));
|
|
||||||
writer.newLine();
|
|
||||||
writer.write(String.format("NewCursor = %b", newCursor));
|
|
||||||
writer.newLine();
|
|
||||||
writer.write(String.format("DynamicBackground = %b", dynamicBackground));
|
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -156,10 +156,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// sorting tabs
|
// sorting tabs
|
||||||
sortTabs = new GUIMenuButton[OsuGroupList.SORT_MAX];
|
sortTabs = new GUIMenuButton[OsuGroupList.SORT_MAX];
|
||||||
Image tab = new Image("selection-tab.png");
|
Image tab = Utils.getTabImage();
|
||||||
float tabScale = (height * 0.033f) / tab.getHeight();
|
|
||||||
tab = tab.getScaledCopy(tabScale);
|
|
||||||
|
|
||||||
float tabX = buttonX + (tab.getWidth() / 2f);
|
float tabX = buttonX + (tab.getWidth() / 2f);
|
||||||
float tabY = (height * 0.15f) - (tab.getHeight() / 2f) - 2f;
|
float tabY = (height * 0.15f) - (tab.getHeight() / 2f) - 2f;
|
||||||
float tabOffset = (width - buttonX) / sortTabs.length;
|
float tabOffset = (width - buttonX) / sortTabs.length;
|
||||||
|
@ -353,6 +350,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// options
|
// options
|
||||||
if (optionsButton.contains(x, y)) {
|
if (optionsButton.contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundController.SOUND_MENUHIT);
|
||||||
game.enterState(Opsu.STATE_OPTIONS, new EmptyTransition(), new FadeInTransition(Color.black));
|
game.enterState(Opsu.STATE_OPTIONS, new EmptyTransition(), new FadeInTransition(Color.black));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -362,13 +360,16 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// sorting buttons
|
// sorting buttons
|
||||||
for (byte i = 0; i < sortTabs.length; i++) {
|
for (byte i = 0; i < sortTabs.length; i++) {
|
||||||
if (sortTabs[i].contains(x, y) && i != currentSort) {
|
if (sortTabs[i].contains(x, y)) {
|
||||||
currentSort = i;
|
if (i != currentSort) {
|
||||||
OsuGroupNode oldFocusBase = Opsu.groups.getBaseNode(focusNode.index);
|
currentSort = i;
|
||||||
int oldFocusFileIndex = focusNode.osuFileIndex;
|
OsuGroupNode oldFocusBase = Opsu.groups.getBaseNode(focusNode.index);
|
||||||
focusNode = null;
|
int oldFocusFileIndex = focusNode.osuFileIndex;
|
||||||
Opsu.groups.init(i);
|
focusNode = null;
|
||||||
setFocus(oldFocusBase, oldFocusFileIndex + 1, true);
|
Opsu.groups.init(i);
|
||||||
|
setFocus(oldFocusBase, oldFocusFileIndex + 1, true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user