/*
* opsu! - an open-source osu! client
* Copyright (C) 2014 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 .
*/
package itdelatrisu.opsu;
import org.newdawn.slick.util.Log;
/**
* Data type representing a timing point.
*/
public class OsuTimingPoint {
/**
* 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(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.
*
* - 0: none
*
- 1: normal
*
- 2: soft
*
- 3: drum
*
*/
public byte getSampleType() { return sampleType; }
/**
* Returns the custom sample type.
*
* - 0: default
*
- 1: custom 1
*
- 2: custom 2
*
*/
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; }
}