Follow-up to #214: cleanup.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2016-12-19 21:02:01 -05:00
parent 0f936d32cb
commit 90a2f1d2f2
6 changed files with 102 additions and 117 deletions

View File

@ -135,6 +135,12 @@ public class Options {
/** Port binding. */ /** Port binding. */
private static int port = 49250; private static int port = 49250;
/** The theme song string: {@code filename,title,artist,length(ms)} */
private static String themeString = "theme.ogg,On the Bach,Jingle Punks,66000";
/** The theme song timing point string (for computing beats to pulse the logo) . */
private static String themeTimingPoint = "-44,631.578947368421,4,1,0,100,1,0";
/** /**
* Returns whether the XDG flag in the manifest (if any) is set to "true". * Returns whether the XDG flag in the manifest (if any) is set to "true".
* @return true if XDG directories are enabled, false otherwise * @return true if XDG directories are enabled, false otherwise
@ -211,12 +217,6 @@ public class Options {
return (dir.isDirectory()) ? dir : null; return (dir.isDirectory()) ? dir : null;
} }
/**
* The theme song string:
* {@code filename,title,artist,length(ms)}
*/
private static String themeString = "theme.ogg,On the Bach,Jingle Punks,66000";
/** Game options. */ /** Game options. */
public enum GameOption { public enum GameOption {
// internal options (not displayed in-game) // internal options (not displayed in-game)
@ -1342,15 +1342,14 @@ public class Options {
beatmap.audioFilename = new File(tokens[0]); beatmap.audioFilename = new File(tokens[0]);
beatmap.title = tokens[1]; beatmap.title = tokens[1];
beatmap.artist = tokens[2]; beatmap.artist = tokens[2];
// add a timingpoint so the logo can be pulsed in the mainmenu
beatmap.timingPoints = new ArrayList<>(1);
beatmap.timingPoints.add(new TimingPoint("-44,631.578947368421,4,1,0,100,1,0"));
try { try {
beatmap.endTime = Integer.parseInt(tokens[3]); beatmap.endTime = Integer.parseInt(tokens[3]);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
ErrorHandler.error("Theme song length is not a valid integer", e, false); ErrorHandler.error("Theme song length is not a valid integer", e, false);
return null; return null;
} }
beatmap.timingPoints = new ArrayList<>(1);
beatmap.timingPoints.add(new TimingPoint(themeTimingPoint));
return beatmap; return beatmap;
} }

View File

@ -186,18 +186,16 @@ public class MusicController {
/** /**
* Gets the progress of the current beat. * Gets the progress of the current beat.
* @return null if music is paused or no timingpoints are available, or progress as a value in * @return a beat progress value [0,1) where 0 marks the current beat and
* [0, 1], where 0 means a beat just happened and 1 means the next beat is coming right now. * 1 marks the next beat, or {@code null} if no beat information
* is available (e.g. music paused, no timing points)
*/ */
public static Float getBeatProgress() { public static Float getBeatProgress() {
if (!isPlaying() || getBeatmap() == null) {
return null;
}
Beatmap map = getBeatmap(); Beatmap map = getBeatmap();
if (map.timingPoints == null) { if (!isPlaying() || map == null || map.timingPoints == null) {
return null; return null;
} }
int trackposition = getPosition(); int trackPosition = getPosition();
TimingPoint p = null; TimingPoint p = null;
double beatlen = 0d; double beatlen = 0d;
int time = 0; int time = 0;
@ -215,7 +213,7 @@ public class MusicController {
return null; return null;
} }
double beatLength = beatlen * 100d; double beatLength = beatlen * 100d;
return (float) ((((trackposition - time) * 100) % beatLength) / beatLength); return (float) ((((trackPosition - time) * 100) % beatLength) / beatLength);
} }
/** /**

View File

@ -212,45 +212,6 @@ public class BeatmapParser {
return lastNode; return lastNode;
} }
/**
* Parses the timingpoints for a beatmap.
* @param map the map to parse timingpoints for
*/
public static void parseOnlyTimingPoints(Beatmap map) {
if (map == null || map.getFile() == null || !map.getFile().exists()) {
return;
}
if (map.timingPoints == null) {
map.timingPoints = new ArrayList<TimingPoint>();
}
try (
InputStream bis = new BufferedInputStream(new FileInputStream(map.getFile()));
BufferedReader in = new BufferedReader(new InputStreamReader(bis, "UTF-8"));
) {
String line;
boolean found = false;
while((line = in.readLine()) != null) {
line = line.trim();
if(!isValidLine(line)) {
continue;
}
if ("[TimingPoints]".equals(line)) {
found = true;
continue;
}
if (found) {
if (line.startsWith("[")) {
break;
}
parseSectionTimingPoints(map, line);
}
}
map.timingPoints.trimToSize();
} catch (IOException e) {
ErrorHandler.error(String.format("Failed to read file '%s'.", map.getFile().getAbsolutePath()), e, false);
}
}
/** /**
* Parses a beatmap. * Parses a beatmap.
* @param file the file to parse * @param file the file to parse
@ -532,7 +493,7 @@ public class BeatmapParser {
break; break;
try { try {
parseSectionTimingPoints(beatmap, line); parseTimingPoint(beatmap, line);
} catch (Exception e) { } catch (Exception e) {
Log.warn(String.format("Failed to read timing point '%s' for file '%s'.", Log.warn(String.format("Failed to read timing point '%s' for file '%s'.",
line, file.getAbsolutePath()), e); line, file.getAbsolutePath()), e);
@ -650,23 +611,68 @@ public class BeatmapParser {
} }
/** /**
* Parses a timing point in the timingpoints section of a beatmap file * Parses a timing point and adds it to the beatmap.
* @param beatmap the beatmap to add the timingpoint to * @param beatmap the beatmap
* @param line the line with timingpoint to parse * @param line the line containing the unparsed timing point
*/ */
private static void parseSectionTimingPoints(Beatmap beatmap, String line) { private static void parseTimingPoint(Beatmap beatmap, String line) {
// parse timing point
TimingPoint timingPoint = new TimingPoint(line); TimingPoint timingPoint = new TimingPoint(line);
if(!timingPoint.isInherited()) { beatmap.timingPoints.add(timingPoint);
// calculate BPM
if (!timingPoint.isInherited()) {
int bpm = Math.round(60000 / timingPoint.getBeatLength()); int bpm = Math.round(60000 / timingPoint.getBeatLength());
if( beatmap.bpmMin == 0 ) { if (beatmap.bpmMin == 0) {
beatmap.bpmMin = beatmap.bpmMax = bpm; beatmap.bpmMin = beatmap.bpmMax = bpm;
} else if( bpm < beatmap.bpmMin ) { } else if (bpm < beatmap.bpmMin) {
beatmap.bpmMin = bpm; beatmap.bpmMin = bpm;
} else if( bpm > beatmap.bpmMax ) { } else if (bpm > beatmap.bpmMax) {
beatmap.bpmMax = bpm; beatmap.bpmMax = bpm;
} }
} }
beatmap.timingPoints.add(timingPoint); }
/**
* Parses all timing points in a beatmap.
* @param beatmap the beatmap to parse
*/
public static void parseTimingPoints(Beatmap beatmap) {
if (beatmap.timingPoints != null) // already parsed
return;
beatmap.timingPoints = new ArrayList<TimingPoint>();
try (BufferedReader in = new BufferedReader(new FileReader(beatmap.getFile()))) {
String line = in.readLine();
while (line != null) {
line = line.trim();
if (!line.equals("[TimingPoints]"))
line = in.readLine();
else
break;
}
if (line == null) // no timing points
return;
while ((line = in.readLine()) != null) {
line = line.trim();
if (!isValidLine(line))
continue;
if (line.charAt(0) == '[')
break;
try {
parseTimingPoint(beatmap, line);
} catch (Exception e) {
Log.warn(String.format("Failed to read timing point '%s' for file '%s'.",
line, beatmap.getFile().getAbsolutePath()), e);
}
}
beatmap.timingPoints.trimToSize();
} catch (IOException e) {
ErrorHandler.error(String.format("Failed to read file '%s'.", beatmap.getFile().getAbsolutePath()), e, false);
}
} }
/** /**

View File

@ -257,17 +257,15 @@ public class MainMenu extends BasicGameState {
exitButton.draw(); exitButton.draw();
} }
// logo // draw logo (pulsing)
Float position = MusicController.getBeatProgress(); Float position = MusicController.getBeatProgress();
if (position == null) { if (position == null) // default to 60bpm
position = System.currentTimeMillis() % 1000 / 1000f; position = System.currentTimeMillis() % 1000 / 1000f;
}
float scale = 1f + position * 0.05f; float scale = 1f + position * 0.05f;
logo.draw(Color.white, scale); logo.draw(Color.white, scale);
Image ghostLogo = GameImage.MENU_LOGO.getImage().getScaledCopy(logo.getCurrentScale() / scale * 1.05f); float ghostScale = logo.getLastScale() / scale * 1.05f;
float scaleposmodx = ghostLogo.getWidth() / 2; Image ghostLogo = GameImage.MENU_LOGO.getImage().getScaledCopy(ghostScale);
float scaleposmody = ghostLogo.getHeight() / 2; ghostLogo.drawCentered(logo.getX(), logo.getY(), Colors.GHOST_LOGO);
ghostLogo.draw(logo.getX() - scaleposmodx, logo.getY() - scaleposmody, Colors.GHOST_LOGO);
// draw music buttons // draw music buttons
if (MusicController.isPlaying()) if (MusicController.isPlaying())

View File

@ -262,12 +262,9 @@ public class SongMenu extends BasicGameState {
/** Footer pulsing logo button. */ /** Footer pulsing logo button. */
private MenuButton footerLogoButton; private MenuButton footerLogoButton;
/** Size of the footer pulsing logo. */ /** Size of the pulsing logo in the footer. */
private float footerLogoSize; private float footerLogoSize;
/** Whether the cursor hovers over the footer logo. */
private boolean bottomLogoHovered;
/** Time, in milliseconds, for fading the search bar. */ /** Time, in milliseconds, for fading the search bar. */
private int searchTransitionTimer = SEARCH_TRANSITION_TIME; private int searchTransitionTimer = SEARCH_TRANSITION_TIME;
@ -344,7 +341,7 @@ public class SongMenu extends BasicGameState {
Fonts.SMALL.getLineHeight(); Fonts.SMALL.getLineHeight();
footerY = height - GameImage.SELECTION_MODS.getImage().getHeight(); footerY = height - GameImage.SELECTION_MODS.getImage().getHeight();
// logo coordinates // footer logo coordinates
float footerHeight = height - footerY; float footerHeight = height - footerY;
footerLogoSize = footerHeight * 3.25f; footerLogoSize = footerHeight * 3.25f;
Image logo = GameImage.MENU_LOGO.getImage(); Image logo = GameImage.MENU_LOGO.getImage();
@ -516,24 +513,22 @@ public class SongMenu extends BasicGameState {
g.drawLine(0, footerY, width, footerY); g.drawLine(0, footerY, width, footerY);
g.resetLineWidth(); g.resetLineWidth();
// opsu logo in bottom bar // footer logo (pulsing)
Float position = MusicController.getBeatProgress(); Float position = MusicController.getBeatProgress();
if (position == null) { if (position == null) // default to 60bpm
position = System.currentTimeMillis() % 1000 / 1000f; position = System.currentTimeMillis() % 1000 / 1000f;
} if (footerLogoButton.contains(mouseX, mouseY, 0.25f)) {
if (bottomLogoHovered) { // hovering over logo: stop pulsing
footerLogoButton.draw(); footerLogoButton.draw();
} else { } else {
float expand = position * 0.15f; float expand = position * 0.15f;
footerLogoButton.draw(Color.white, 1f - expand); footerLogoButton.draw(Color.white, 1f - expand);
Image ghostLogo = GameImage.MENU_LOGO.getImage(); Image ghostLogo = GameImage.MENU_LOGO.getImage();
ghostLogo = ghostLogo.getScaledCopy((1f + expand) * footerLogoSize / ghostLogo.getWidth()); ghostLogo = ghostLogo.getScaledCopy((1f + expand) * footerLogoSize / ghostLogo.getWidth());
float scaleposmodx = ghostLogo.getWidth() / 2; float oldGhostAlpha = Colors.GHOST_LOGO.a;
float scaleposmody = ghostLogo.getHeight() / 2;
float a = Colors.GHOST_LOGO.a;
Colors.GHOST_LOGO.a *= (1f - position); Colors.GHOST_LOGO.a *= (1f - position);
ghostLogo.draw(footerLogoButton.getX() - scaleposmodx, footerLogoButton.getY() - scaleposmody, Colors.GHOST_LOGO); ghostLogo.drawCentered(footerLogoButton.getX(), footerLogoButton.getY(), Colors.GHOST_LOGO);
Colors.GHOST_LOGO.a = a; Colors.GHOST_LOGO.a = oldGhostAlpha;
} }
// header // header
@ -697,6 +692,7 @@ public class SongMenu extends BasicGameState {
selectRandomButton.hoverUpdate(delta, mouseX, mouseY); selectRandomButton.hoverUpdate(delta, mouseX, mouseY);
selectMapOptionsButton.hoverUpdate(delta, mouseX, mouseY); selectMapOptionsButton.hoverUpdate(delta, mouseX, mouseY);
selectOptionsButton.hoverUpdate(delta, mouseX, mouseY); selectOptionsButton.hoverUpdate(delta, mouseX, mouseY);
footerLogoButton.hoverUpdate(delta, mouseX, mouseY, 0.25f);
// beatmap menu timer // beatmap menu timer
if (beatmapMenuTimer > -1) { if (beatmapMenuTimer > -1) {
@ -791,18 +787,7 @@ public class SongMenu extends BasicGameState {
} }
updateDrawnSongPosition(); updateDrawnSongPosition();
// mouse hover (logo) // mouse hover
if (footerLogoButton.contains(mouseX, mouseY, 0.25f)) {
footerLogoButton.hoverUpdate(delta, true);
bottomLogoHovered = true;
// reset beatmap node hover
hoverIndex = null;
return;
}
footerLogoButton.hoverUpdate(delta, false);
bottomLogoHovered = false;
// mouse hover (beatmap nodes)
BeatmapSetNode node = getNodeAtPosition(mouseX, mouseY); BeatmapSetNode node = getNodeAtPosition(mouseX, mouseY);
if (node != null) { if (node != null) {
if (node == hoverIndex) if (node == hoverIndex)
@ -845,7 +830,7 @@ public class SongMenu extends BasicGameState {
if (isScrollingToFocusNode) if (isScrollingToFocusNode)
return; return;
if (bottomLogoHovered) { if (footerLogoButton.contains(x, y, 0.25f)) {
startGame(); startGame();
return; return;
} }
@ -1445,8 +1430,8 @@ public class SongMenu extends BasicGameState {
focusNode = BeatmapSetList.get().getNode(node, beatmapIndex); focusNode = BeatmapSetList.get().getNode(node, beatmapIndex);
Beatmap beatmap = focusNode.getSelectedBeatmap(); Beatmap beatmap = focusNode.getSelectedBeatmap();
if (beatmap.timingPoints == null) { if (beatmap.timingPoints == null) {
// parse the timingpoints so we can pulse the main menu logo and bottom right logo in songmenu // parse timing points so we can pulse the logo
BeatmapParser.parseOnlyTimingPoints(beatmap); BeatmapParser.parseTimingPoints(beatmap);
} }
MusicController.play(beatmap, false, preview); MusicController.play(beatmap, false, preview);

View File

@ -98,8 +98,8 @@ public class MenuButton {
/** The default max rotation angle of the button. */ /** The default max rotation angle of the button. */
private static final float DEFAULT_ANGLE_MAX = 30f; private static final float DEFAULT_ANGLE_MAX = 30f;
/** The current scale of the drawn button */ /** The last scale at which the button was drawn. */
private float currentScale = 1f; private float lastScale = 1f;
/** /**
* Creates a new button from an Image. * Creates a new button from an Image.
@ -170,9 +170,9 @@ public class MenuButton {
public float getY() { return y; } public float getY() { return y; }
/** /**
* Returns the current scale. * Returns the last scale at which the button was drawn.
*/ */
public float getCurrentScale() { return currentScale; } public float getLastScale() { return lastScale; }
/** /**
* Sets text to draw in the middle of the button. * Sets text to draw in the middle of the button.
@ -208,9 +208,9 @@ public class MenuButton {
public void draw(Color filter) { draw(filter, 1f); } public void draw(Color filter) { draw(filter, 1f); }
/** /**
* Draw the button with a color filter. * Draw the button with a color filter at the given scale.
* @param filter the color to filter with when drawing * @param filter the color to filter with when drawing
* @param scaleOverride the scale to use when drawing, works only for normal images * @param scaleOverride the scale to use when drawing (only works for normal images)
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void draw(Color filter, float scaleOverride) { public void draw(Color filter, float scaleOverride) {
@ -223,14 +223,13 @@ public class MenuButton {
// normal images // normal images
if (imgL == null) { if (imgL == null) {
float scalePosModX = 0; float xScaleOffset = 0f, yScaleOffset = 0f;
float scalePosModY = 0;
if (scaleOverride != 1f) { if (scaleOverride != 1f) {
image = image.getScaledCopy(scaleOverride); image = image.getScaledCopy(scaleOverride);
scalePosModX = image.getWidth() / 2 - xRadius; xScaleOffset = image.getWidth() / 2f - xRadius;
scalePosModY = image.getHeight() / 2 - yRadius; yScaleOffset = image.getHeight() / 2f - yRadius;
} }
currentScale = scaleOverride; lastScale = scaleOverride;
if (hoverEffect == 0) if (hoverEffect == 0)
image.draw(x - xRadius, y - yRadius, filter); image.draw(x - xRadius, y - yRadius, filter);
else { else {
@ -240,16 +239,16 @@ public class MenuButton {
if (scale.getValue() != 1f) { if (scale.getValue() != 1f) {
image = image.getScaledCopy(scale.getValue()); image = image.getScaledCopy(scale.getValue());
image.setAlpha(oldAlpha); image.setAlpha(oldAlpha);
scalePosModX = image.getWidth() / 2 - xRadius; xScaleOffset = image.getWidth() / 2f - xRadius;
scalePosModY = image.getHeight() / 2 - yRadius; yScaleOffset = image.getHeight() / 2f - yRadius;
currentScale *= scale.getValue(); lastScale *= scale.getValue();
} }
} }
if ((hoverEffect & EFFECT_FADE) > 0) if ((hoverEffect & EFFECT_FADE) > 0)
image.setAlpha(alpha.getValue()); image.setAlpha(alpha.getValue());
if ((hoverEffect & EFFECT_ROTATE) > 0) if ((hoverEffect & EFFECT_ROTATE) > 0)
image.setRotation(angle.getValue()); image.setRotation(angle.getValue());
image.draw(x - xRadius - scalePosModX, y - yRadius - scalePosModY, filter); image.draw(x - xRadius - xScaleOffset, y - yRadius - yScaleOffset, filter);
if (image == this.img) { if (image == this.img) {
image.setAlpha(oldAlpha); image.setAlpha(oldAlpha);
image.setRotation(oldAngle); image.setRotation(oldAngle);