From 5a1972a2bdf384bcc6a6ddaf99f03c2084a5cabe Mon Sep 17 00:00:00 2001 From: Jeffrey Han Date: Wed, 9 Jul 2014 13:36:42 -0400 Subject: [PATCH] Some code cleanup. - Overhauled OsuTimingPoint class: parsing is done in the constructor, and fields are no longer public. - Improved consistency of static/non-static fields in a couple of classes. Signed-off-by: Jeffrey Han --- src/itdelatrisu/opsu/OsuParser.java | 27 +--- src/itdelatrisu/opsu/OsuTimingPoint.java | 143 +++++++++++++++++-- src/itdelatrisu/opsu/SoundController.java | 8 +- src/itdelatrisu/opsu/states/Game.java | 40 +++--- src/itdelatrisu/opsu/states/GameRanking.java | 2 +- src/itdelatrisu/opsu/states/MainMenu.java | 6 +- src/itdelatrisu/opsu/states/Options.java | 10 +- 7 files changed, 172 insertions(+), 64 deletions(-) diff --git a/src/itdelatrisu/opsu/OsuParser.java b/src/itdelatrisu/opsu/OsuParser.java index 791ae43e..b9c9d760 100644 --- a/src/itdelatrisu/opsu/OsuParser.java +++ b/src/itdelatrisu/opsu/OsuParser.java @@ -336,35 +336,20 @@ public class OsuParser { continue; if (line.charAt(0) == '[') break; - tokens = line.split(","); - OsuTimingPoint timingPoint = new OsuTimingPoint(); - try { // newer file versions have many new fields - timingPoint.time = (int) Float.parseFloat(tokens[0]); //rare float - timingPoint.meter = Integer.parseInt(tokens[2]); - timingPoint.sampleType = Byte.parseByte(tokens[3]); - timingPoint.sampleTypeCustom = Byte.parseByte(tokens[4]); - timingPoint.sampleVolume = Integer.parseInt(tokens[5]); - timingPoint.inherited = (Integer.parseInt(tokens[6]) == 1); - timingPoint.kiai = (Integer.parseInt(tokens[7]) == 1); - } catch (ArrayIndexOutOfBoundsException e) { - // TODO: better support for old formats -// Log.error(String.format("Error while parsing TimingPoints, line: '%s'.", line), e); - } + // parse timing point + OsuTimingPoint timingPoint = new OsuTimingPoint(line); - // tokens[1] is either beatLength (positive) or velocity (negative) - float beatLength = Float.parseFloat(tokens[1]); - if (beatLength > 0) { - timingPoint.beatLength = beatLength; - int bpm = Math.round(60000 / beatLength); + // calculate BPM + if (!timingPoint.isInherited()) { + int bpm = Math.round(60000 / timingPoint.getBeatLength()); if (osu.bpmMin == 0) osu.bpmMin = osu.bpmMax = bpm; else if (bpm < osu.bpmMin) osu.bpmMin = bpm; else if (bpm > osu.bpmMax) osu.bpmMax = bpm; - } else - timingPoint.velocity = (int) beatLength; + } osu.timingPoints.add(timingPoint); } diff --git a/src/itdelatrisu/opsu/OsuTimingPoint.java b/src/itdelatrisu/opsu/OsuTimingPoint.java index 98f1d1ff..8020649f 100644 --- a/src/itdelatrisu/opsu/OsuTimingPoint.java +++ b/src/itdelatrisu/opsu/OsuTimingPoint.java @@ -18,22 +18,145 @@ package itdelatrisu.opsu; +import org.newdawn.slick.util.Log; + /** * Data type representing a timing point. */ public class OsuTimingPoint { - public int time; // start time/offset (in ms) - public float beatLength; // (non-inherited) ms per beat - public int velocity = 0; // (inherited) slider multiplier = -100 / value - public int meter; // beats per measure - public byte sampleType; // sound samples (0:none, 1:normal, 2:soft, 3:drum) - public byte sampleTypeCustom; // custom samples (0:default, 1:custom1, 2:custom2) - public int sampleVolume; // volume of samples (0~100) - public boolean inherited; // is this timing point inherited? - public boolean kiai; // is Kiai Mode active? + /** + * Timing point start time/offset (in ms). + */ + private int time = 0; + + /** + * Time per beat (in ms). [NON-INHERITED] + */ + private float beatLength = 0f; + + /** + * Slider multiplier. [INHERITED] + */ + private int velocity = 0; + + /** + * Beats per measure. + */ + private int meter = 4; + + /** + * Sound sample type. + */ + private byte sampleType = 1; + + /** + * Custom sound sample type. + */ + private byte sampleTypeCustom = 0; + + /** + * Volume of samples. [0, 100] + */ + private int sampleVolume = 100; + + /** + * Whether or not this timing point is inherited. + */ + private boolean inherited = false; + + /** + * Whether or not Kiai Mode is active. + */ + private boolean kiai = false; /** * Constructor. + * @param line the line to be parsed */ - public OsuTimingPoint() {} + public OsuTimingPoint(String line) { + // TODO: better support for old formats + String[] tokens = line.split(","); + try { + this.time = (int) Float.parseFloat(tokens[0]); // rare float + this.meter = Integer.parseInt(tokens[2]); + this.sampleType = Byte.parseByte(tokens[3]); + this.sampleTypeCustom = Byte.parseByte(tokens[4]); + this.sampleVolume = Integer.parseInt(tokens[5]); +// this.inherited = (Integer.parseInt(tokens[6]) == 1); + this.kiai = (Integer.parseInt(tokens[7]) == 1); + } catch (ArrayIndexOutOfBoundsException e) { + Log.debug(String.format("Error parsing timing point: '%s'", line)); + } + + // tokens[1] is either beatLength (positive) or velocity (negative) + float beatLength = Float.parseFloat(tokens[1]); + if (beatLength > 0) + this.beatLength = beatLength; + else { + this.velocity = (int) beatLength; + this.inherited = true; + } + } + + /** + * Returns the timing point start time/offset. + * @return the start time (in ms) + */ + public int getTime() { return time; } + + /** + * Returns the beat length. [NON-INHERITED] + * @return the time per beat (in ms) + */ + public float getBeatLength() { return beatLength; } + + /** + * Returns the slider multiplier. [INHERITED] + */ + public float getSliderMultiplier() { return velocity / -100f; } + + /** + * Returns the meter. + * @return the number of beats per measure + */ + public int getMeter() { return meter; } + + /** + * Returns the sample type. + * + */ + public byte getSampleType() { return sampleType; } + + /** + * Returns the custom sample type. + * + */ + public byte getSampleTypeCustom() { return sampleTypeCustom; } + + /** + * Returns the sample volume. + * @return the sample volume [0, 1] + */ + public float getSampleVolume() { return sampleVolume / 100f; } + + /** + * Returns whether or not this timing point is inherited. + * @return the inherited + */ + public boolean isInherited() { return inherited; } + + /** + * Returns whether or not Kiai Time is active. + * @return true if active + */ + public boolean isKiaiTimeActive() { return kiai; } } \ No newline at end of file diff --git a/src/itdelatrisu/opsu/SoundController.java b/src/itdelatrisu/opsu/SoundController.java index 77892e91..d24b6c2a 100644 --- a/src/itdelatrisu/opsu/SoundController.java +++ b/src/itdelatrisu/opsu/SoundController.java @@ -231,11 +231,11 @@ public class SoundController { /** * Sets the sample volume (modifies the global sample volume). - * @param volume the sample volume [0, 100] + * @param volume the sample volume [0, 1] */ - public static void setSampleVolume(int volume) { - if (volume >= 0 && volume <= 100) - sampleVolumeMultiplier = volume / 100f; + public static void setSampleVolume(float volume) { + if (volume >= 0f && volume <= 1f) + sampleVolumeMultiplier = volume; } /** diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index e244bb0a..65e2f51e 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -71,7 +71,7 @@ public class Game extends BasicGameState { /** * The associated OsuFile object. */ - private static OsuFile osu; + private OsuFile osu; /** * The associated GameScore object (holds all score data). @@ -101,7 +101,7 @@ public class Game extends BasicGameState { /** * Delay time, in milliseconds, before song starts. */ - private static int leadInTime; + private int leadInTime; /** * Hit object approach time, in milliseconds. @@ -141,7 +141,7 @@ public class Game extends BasicGameState { /** * Minimum time before start of song, in milliseconds, to process skip-related actions. */ - private final int skipOffsetTime = 2000; + private static final int SKIP_OFFSET = 2000; /** * Current timing point index in timingPoints ArrayList. @@ -308,8 +308,8 @@ public class Game extends BasicGameState { // skip beginning if (objectIndex == 0 && - osu.objects[0].time - skipOffsetTime > 5000 && - trackPosition < osu.objects[0].time - skipOffsetTime) + osu.objects[0].time - SKIP_OFFSET > 5000 && + trackPosition < osu.objects[0].time - SKIP_OFFSET) skipButton.draw(); if (isLeadIn()) @@ -456,13 +456,13 @@ public class Game extends BasicGameState { // timing points if (timingPointIndex < osu.timingPoints.size()) { OsuTimingPoint timingPoint = osu.timingPoints.get(timingPointIndex); - if (trackPosition >= timingPoint.time) { - if (timingPoint.velocity >= 0) - beatLengthBase = beatLength = timingPoint.beatLength; + if (trackPosition >= timingPoint.getTime()) { + if (!timingPoint.isInherited()) + beatLengthBase = beatLength = timingPoint.getBeatLength(); else - beatLength = beatLengthBase * (timingPoint.velocity / -100f); - SoundController.setSampleSet(timingPoint.sampleType); - SoundController.setSampleVolume(timingPoint.sampleVolume); + beatLength = beatLengthBase * timingPoint.getSliderMultiplier(); + SoundController.setSampleSet(timingPoint.getSampleType()); + SoundController.setSampleVolume(timingPoint.getSampleVolume()); timingPointIndex++; } } @@ -644,7 +644,7 @@ public class Game extends BasicGameState { pauseTime = -1; pausedMouseX = -1; pausedMouseY = -1; - if (!Game.isLeadIn()) + if (!isLeadIn()) MusicController.resume(); } return; @@ -751,10 +751,10 @@ public class Game extends BasicGameState { // load the first timingPoint if (!osu.timingPoints.isEmpty()) { OsuTimingPoint timingPoint = osu.timingPoints.get(0); - if (timingPoint.velocity >= 0) { - beatLengthBase = beatLength = timingPoint.beatLength; - SoundController.setSampleSet(timingPoint.sampleType); - SoundController.setSampleVolume(timingPoint.sampleVolume); + if (!timingPoint.isInherited()) { + beatLengthBase = beatLength = timingPoint.getBeatLength(); + SoundController.setSampleSet(timingPoint.getSampleType()); + SoundController.setSampleVolume(timingPoint.getSampleVolume()); timingPointIndex++; } } @@ -777,13 +777,13 @@ public class Game extends BasicGameState { private boolean skipIntro() { int trackPosition = MusicController.getPosition(); if (objectIndex == 0 && - osu.objects[0].time - skipOffsetTime > 4000 && - trackPosition < osu.objects[0].time - skipOffsetTime) { + osu.objects[0].time - SKIP_OFFSET > 4000 && + trackPosition < osu.objects[0].time - SKIP_OFFSET) { if (isLeadIn()) { leadInTime = 0; MusicController.resume(); } - MusicController.setPosition(osu.objects[0].time - skipOffsetTime); + MusicController.setPosition(osu.objects[0].time - SKIP_OFFSET); SoundController.playSound(SoundController.SOUND_MENUHIT); return true; } @@ -931,7 +931,7 @@ public class Game extends BasicGameState { /** * Returns whether or not the track is in the lead-in time state. */ - public static boolean isLeadIn() { return leadInTime > 0; } + public boolean isLeadIn() { return leadInTime > 0; } /** * Returns the object approach time, in milliseconds. diff --git a/src/itdelatrisu/opsu/states/GameRanking.java b/src/itdelatrisu/opsu/states/GameRanking.java index d2a8baba..8c0e6843 100644 --- a/src/itdelatrisu/opsu/states/GameRanking.java +++ b/src/itdelatrisu/opsu/states/GameRanking.java @@ -50,7 +50,7 @@ public class GameRanking extends BasicGameState { /** * Associated GameScore object. */ - private static GameScore score; + private GameScore score; /** * "Retry" and "Exit" buttons. diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index 12eb559b..b677cd57 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -209,9 +209,9 @@ public class MainMenu extends BasicGameState { long time = System.currentTimeMillis() - osuStartTime; g.drawString(String.format("opsu! has been running for %d minutes, %d seconds.", TimeUnit.MILLISECONDS.toMinutes(time), - TimeUnit.MILLISECONDS.toSeconds(time) - - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))), - 25, height - 25 - (lineHeight * 2)); + TimeUnit.MILLISECONDS.toSeconds(time) - + TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))), + 25, height - 25 - (lineHeight * 2)); g.drawString(String.format("The current time is %s.", new SimpleDateFormat("h:mm a").format(new Date())), 25, height - 25 - lineHeight); diff --git a/src/itdelatrisu/opsu/states/Options.java b/src/itdelatrisu/opsu/states/Options.java index 160111ad..9a31b109 100644 --- a/src/itdelatrisu/opsu/states/Options.java +++ b/src/itdelatrisu/opsu/states/Options.java @@ -118,7 +118,7 @@ public class Options extends BasicGameState { /** * Game options. */ - private enum GameOption { + private static enum GameOption { NULL, SCREEN_RESOLUTION, // FULLSCREEN, @@ -168,7 +168,7 @@ public class Options extends BasicGameState { /** * Option tab buttons. */ - private GUIMenuButton[] optionTabs = new GUIMenuButton[TAB_MAX]; + private static GUIMenuButton[] optionTabs = new GUIMenuButton[TAB_MAX]; /** * Current tab. @@ -870,7 +870,7 @@ public class Options extends BasicGameState { drawOption(pos, "Track Checkpoint", (checkpoint == 0) ? "Disabled" : String.format("%02d:%02d", TimeUnit.SECONDS.toMinutes(checkpoint), - checkpoint - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(checkpoint))), + checkpoint - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(checkpoint))), "Press CTRL+L while playing to load a checkpoint, and CTRL+S to set one." ); break; @@ -975,8 +975,8 @@ public class Options extends BasicGameState { public static float getEffectVolume() { return effectVolume / 100f; } /** - * Returns the default sound effect volume. - * @return the sound volume [0, 1] + * Returns the default hit sound volume. + * @return the hit sound volume [0, 1] */ public static float getHitSoundVolume() { return hitSoundVolume / 100f; }