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 <itdelatrisu@gmail.com>
This commit is contained in:
parent
50fb71e353
commit
5a1972a2bd
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* <ul>
|
||||
* <li>0: none
|
||||
* <li>1: normal
|
||||
* <li>2: soft
|
||||
* <li>3: drum
|
||||
* </ul>
|
||||
*/
|
||||
public byte getSampleType() { return sampleType; }
|
||||
|
||||
/**
|
||||
* Returns the custom sample type.
|
||||
* <ul>
|
||||
* <li>0: default
|
||||
* <li>1: custom 1
|
||||
* <li>2: custom 2
|
||||
* </ul>
|
||||
*/
|
||||
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; }
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -50,7 +50,7 @@ public class GameRanking extends BasicGameState {
|
|||
/**
|
||||
* Associated GameScore object.
|
||||
*/
|
||||
private static GameScore score;
|
||||
private GameScore score;
|
||||
|
||||
/**
|
||||
* "Retry" and "Exit" buttons.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user