Merge pull request #27 from fluddokt/AudioTest

Addition/Edge Addition SampleSet
This commit is contained in:
Jeffrey Han 2015-03-01 13:20:15 -05:00
commit 33e880df77
10 changed files with 138 additions and 50 deletions

View File

@ -1033,14 +1033,17 @@ public class GameData {
* @param y the y coordinate
* @param hitSound the object's hit sound
*/
public void sliderTickResult(int time, int result, float x, float y, byte hitSound) {
public void sliderTickResult(int time, int result, float x, float y, OsuHitObject hitObject, int repeats) {
int hitValue = 0;
switch (result) {
case HIT_SLIDER30:
hitValue = 30;
incrementComboStreak();
changeHealth(1f);
SoundController.playHitSound(hitSound);
SoundController.playHitSound(
hitObject.getEdgeHitSoundType(repeats),
hitObject.getSampleSet(repeats),
hitObject.getAdditionSampleSet(repeats));
break;
case HIT_SLIDER10:
hitValue = 10;
@ -1076,7 +1079,7 @@ public class GameData {
* @param isSpinner whether the hit object was a spinner
*/
public void hitResult(int time, int result, float x, float y, Color color,
boolean end, byte hitSound, boolean isSpinner) {
boolean end, OsuHitObject hitObject, int repeats, boolean isSpinner) {
int hitValue = 0;
boolean perfectHit = false;
switch (result) {
@ -1104,8 +1107,11 @@ public class GameData {
return;
}
if (hitValue > 0) {
SoundController.playHitSound(hitSound);
SoundController.playHitSound(
hitObject.getEdgeHitSoundType(repeats),
hitObject.getSampleSet(repeats),
hitObject.getAdditionSampleSet(repeats));
/**
* [SCORE FORMULA]
* Score = Hit Value + Hit Value * (Combo * Difficulty * Mod) / 25

View File

@ -71,6 +71,9 @@ public class OsuHitObject {
/** Hit sound type (SOUND_* bitmask). */
private byte hitSound;
/** Hit sound addition (sampleSet, AdditionSampleSet, ?, ...). */
private byte[] addition;
/** Slider curve type (SLIDER_* constant). */
private char sliderType;
@ -85,6 +88,12 @@ public class OsuHitObject {
/** Spinner end time (in ms). */
private int endTime;
/** Edge Hit sound type (SOUND_* bitmask). */
private byte[] edgeHitSound;
/** Edge Hit sound addition (sampleSet, AdditionSampleSet). */
private byte[][] edgeAddition;
// additional v10+ parameters not implemented...
// addition -> sampl:add:cust:vol:hitsound
@ -156,8 +165,12 @@ public class OsuHitObject {
// type-specific fields
if ((type & OsuHitObject.TYPE_CIRCLE) > 0) {
/* 'addition' not implemented. */
if (tokens.length > 5) {
String[] additionTokens = tokens[5].split(":");
addition = new byte[additionTokens.length];
for (int j = 0; j < additionTokens.length; j++)
this.addition[j] = Byte.parseByte(additionTokens[j]);
}
} else if ((type & OsuHitObject.TYPE_SLIDER) > 0) {
// slider curve type and coordinates
String[] sliderTokens = tokens[5].split("\\|");
@ -171,8 +184,22 @@ public class OsuHitObject {
}
this.repeat = Integer.parseInt(tokens[6]);
this.pixelLength = Float.parseFloat(tokens[7]);
/* edge fields and 'addition' not implemented. */
if (tokens.length > 8) {
String[] edgeHitSoundTokens = tokens[8].split("\\|");
this.edgeHitSound = new byte[edgeHitSoundTokens.length];
for (int j = 0; j < edgeHitSoundTokens.length; j++) {
edgeHitSound[j] = Byte.parseByte(edgeHitSoundTokens[j]);
}
}
if (tokens.length > 9) {
String[] edgeAdditionTokens = tokens[9].split("\\|");
this.edgeAddition = new byte[edgeAdditionTokens.length][2];
for (int j = 0; j < edgeAdditionTokens.length; j++) {
String[] tedgeAddition = edgeAdditionTokens[j].split(":");
edgeAddition[j][0] = Byte.parseByte(tedgeAddition[0]);
edgeAddition[j][1] = Byte.parseByte(tedgeAddition[1]);
}
}
} else { //if ((type & OsuHitObject.TYPE_SPINNER) > 0) {
// some 'endTime' fields contain a ':' character (?)
int index = tokens[5].indexOf(':');
@ -212,6 +239,16 @@ public class OsuHitObject {
* @return the sound type (SOUND_* bitmask)
*/
public byte getHitSoundType() { return hitSound; }
/**
* Returns the edge hit sound type.
* @return the sound type (SOUND_* bitmask)
*/
public byte getEdgeHitSoundType(int i) {
if(edgeHitSound != null)
return edgeHitSound[i];
else return hitSound;
}
/**
* Returns the slider type.
@ -301,4 +338,26 @@ public class OsuHitObject {
* Returns the number of extra skips on the combo colors.
*/
public int getComboSkip() { return (type >> TYPE_NEWCOMBO); }
/**
* Returns the Sample Set at i.
*/
public byte getSampleSet(int i) {
if (edgeAddition != null)
return edgeAddition[i][0];
if (addition != null)
return addition[0];
return 0;
}
/**
* Returns the Addition Sample Set at i.
*/
public byte getAdditionSampleSet(int i) {
if (edgeAddition != null)
return edgeAddition[i][1];
if (addition != null)
return addition[1];
return 0;
}
}

View File

@ -564,8 +564,8 @@ public class OsuParser {
// set combo info
// - new combo: get next combo index, reset combo number
// - else: maintain combo index, increase combo number
if (((hitObject.isNewCombo() || first) && !hitObject.isSpinner())) {
int skip = 1 + hitObject.getComboSkip();
if (hitObject.isNewCombo() || first) {
int skip = (hitObject.isSpinner()?0:1) + hitObject.getComboSkip();
for (int i = 0; i < skip; i++) {
comboIndex = (comboIndex + 1) % osu.combo.length;
comboNumber = 1;

View File

@ -73,6 +73,9 @@ public enum HitSound implements SoundController.SoundComponent {
/** Current sample set. */
private static SampleSet currentSampleSet;
/** Current default sample set. */
private static SampleSet currentDefaultSampleSet = SampleSet.NORMAL;
/** The file name. */
private String filename;
@ -112,25 +115,38 @@ public enum HitSound implements SoundController.SoundComponent {
}
/**
* Sets the sample set to use when playing hit sounds.
* @param sampleSet the sample set ("None", "Normal", "Soft", "Drum")
* Sets the default sample set to use when playing hit sounds.
* @param sampleSet the sample set ("auto", "Normal", "Soft", "Drum")
*/
public static void setSampleSet(String sampleSet) {
currentSampleSet = null;
public static void setDefaultSampleSet(String sampleSet) {
currentDefaultSampleSet = SampleSet.NORMAL;
for (SampleSet ss : SampleSet.values()) {
if (sampleSet.equalsIgnoreCase(ss.getName())) {
currentSampleSet = ss;
currentDefaultSampleSet = ss;
return;
}
}
}
/**
* Sets the default sample set to use when playing hit sounds.
* @param sampleSet the sample set (0:auto, 1:normal, 2:soft, 3:drum)
*/
public static void setDefaultSampleSet(byte sampleType) {
currentDefaultSampleSet = SampleSet.NORMAL;
for (SampleSet ss : SampleSet.values()) {
if (sampleType == ss.getIndex()) {
currentDefaultSampleSet = ss;
return;
}
}
}
/**
* Sets the sample set to use when playing hit sounds.
* @param sampleType the sample set (0:none, 1:normal, 2:soft, 3:drum)
* @param sampleType the sample set (0:auto, 1:normal, 2:soft, 3:drum)
*/
public static void setSampleSet(byte sampleType) {
currentSampleSet = null;
currentSampleSet = currentDefaultSampleSet;
for (SampleSet ss : SampleSet.values()) {
if (sampleType == ss.getIndex()) {
currentSampleSet = ss;
@ -138,4 +154,6 @@ public enum HitSound implements SoundController.SoundComponent {
}
}
}
}

View File

@ -252,7 +252,7 @@ public class SoundController {
* Plays hit sound(s) using an OsuHitObject bitmask.
* @param hitSound the hit sound (bitmask)
*/
public static void playHitSound(byte hitSound) {
public static void playHitSound(byte hitSound, byte sampleSet, byte additionSampleSet) {
if (hitSound < 0)
return;
@ -261,16 +261,16 @@ public class SoundController {
return;
// play all sounds
if (hitSound == OsuHitObject.SOUND_NORMAL)
playClip(HitSound.NORMAL.getClip(), volume);
else {
if ((hitSound & OsuHitObject.SOUND_WHISTLE) > 0)
playClip(HitSound.WHISTLE.getClip(), volume);
if ((hitSound & OsuHitObject.SOUND_FINISH) > 0)
playClip(HitSound.FINISH.getClip(), volume);
if ((hitSound & OsuHitObject.SOUND_CLAP) > 0)
playClip(HitSound.CLAP.getClip(), volume);
}
HitSound.setSampleSet(sampleSet);
playClip(HitSound.NORMAL.getClip(), volume);
HitSound.setSampleSet(additionSampleSet);
if ((hitSound & OsuHitObject.SOUND_WHISTLE) > 0)
playClip(HitSound.WHISTLE.getClip(), volume);
if ((hitSound & OsuHitObject.SOUND_FINISH) > 0)
playClip(HitSound.FINISH.getClip(), volume);
if ((hitSound & OsuHitObject.SOUND_CLAP) > 0)
playClip(HitSound.CLAP.getClip(), volume);
}
/**

View File

@ -141,7 +141,7 @@ public class Circle implements HitObject {
data.hitResult(
hitObject.getTime(), result,
hitObject.getX(), hitObject.getY(),
color, comboEnd, hitObject.getHitSoundType(), false
color, comboEnd, hitObject, 0, false
);
return true;
}
@ -153,7 +153,6 @@ public class Circle implements HitObject {
public boolean update(boolean overlap, int delta, int mouseX, int mouseY) {
int time = hitObject.getTime();
float x = hitObject.getX(), y = hitObject.getY();
byte hitSound = hitObject.getHitSoundType();
int trackPosition = MusicController.getPosition();
int[] hitResultOffset = game.getHitResultOffsets();
@ -161,17 +160,17 @@ public class Circle implements HitObject {
if (overlap || trackPosition > time + hitResultOffset[GameData.HIT_50]) {
if (isAutoMod) // "auto" mod: catch any missed notes due to lag
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound, false);
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, 0, false);
else // no more points can be scored, so send a miss
data.hitResult(time, GameData.HIT_MISS, x, y, null, comboEnd, hitSound, false);
data.hitResult(time, GameData.HIT_MISS, x, y, null, comboEnd, hitObject, 0, false);
return true;
}
// "auto" mod: send a perfect hit result
else if (isAutoMod) {
if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) {
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound, false);
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, 0, false);
return true;
}
}

View File

@ -253,10 +253,14 @@ public class Slider implements HitObject {
if (currentRepeats % 2 == 0) { // last circle
float[] lastPos = curve.pointAt(1);
data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result,
lastPos[0],lastPos[1], color, comboEnd, hitObject.getHitSoundType(), false);
lastPos[0],lastPos[1], color, comboEnd,
hitObject, currentRepeats+1
, false);
} else { // first circle
data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result,
hitObject.getX(), hitObject.getY(), color, comboEnd, hitObject.getHitSoundType(), false);
hitObject.getX(), hitObject.getY(), color, comboEnd,
hitObject, currentRepeats+1
, false);
}
return result;
@ -286,7 +290,9 @@ public class Slider implements HitObject {
data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime());
sliderClickedInitial = true;
data.sliderTickResult(hitObject.getTime(), result,
hitObject.getX(), hitObject.getY(), hitObject.getHitSoundType());
hitObject.getX(), hitObject.getY(),
hitObject, currentRepeats
);
return true;
}
}
@ -315,7 +321,6 @@ public class Slider implements HitObject {
}
}
byte hitSound = hitObject.getHitSoundType();
int trackPosition = MusicController.getPosition();
int[] hitResultOffset = game.getHitResultOffsets();
int lastIndex = hitObject.getSliderX().length - 1;
@ -330,10 +335,10 @@ public class Slider implements HitObject {
if (isAutoMod) { // "auto" mod: catch any missed notes due to lag
ticksHit++;
data.sliderTickResult(time, GameData.HIT_SLIDER30,
hitObject.getX(), hitObject.getY(), hitSound);
hitObject.getX(), hitObject.getY(), hitObject, currentRepeats);
} else
data.sliderTickResult(time, GameData.HIT_MISS,
hitObject.getX(), hitObject.getY(), hitSound);
hitObject.getX(), hitObject.getY(), hitObject, currentRepeats);
}
// "auto" mod: send a perfect hit result
@ -342,7 +347,7 @@ public class Slider implements HitObject {
ticksHit++;
sliderClickedInitial = true;
data.sliderTickResult(time, GameData.HIT_SLIDER30,
hitObject.getX(), hitObject.getY(), hitSound);
hitObject.getX(), hitObject.getY(), hitObject, currentRepeats);
}
}
}
@ -411,17 +416,18 @@ public class Slider implements HitObject {
ticksHit++;
if (currentRepeats % 2 > 0) // last circle
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER30,
hitObject.getSliderX()[lastIndex], hitObject.getSliderY()[lastIndex], hitSound);
hitObject.getSliderX()[lastIndex], hitObject.getSliderY()[lastIndex],
hitObject, currentRepeats);
else // first circle
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER30,
c[0], c[1], hitSound);
c[0], c[1], hitObject, currentRepeats);
}
// held during new tick
if (isNewTick) {
ticksHit++;
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10,
c[0], c[1], (byte) -1);
c[0], c[1], hitObject, currentRepeats);
}
// held near end of slider
@ -431,9 +437,9 @@ public class Slider implements HitObject {
followCircleActive = false;
if (isNewRepeat)
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, (byte) -1);
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats);
if (isNewTick)
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, (byte) -1);
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats);
}
return false;

View File

@ -164,7 +164,7 @@ public class Spinner implements HitObject {
result = GameData.HIT_MISS;
data.hitResult(hitObject.getEndTime(), result, width / 2, height / 2,
Color.transparent, true, (byte) -1, true);
Color.transparent, true, hitObject, 0, true);
return result;
}

View File

@ -449,7 +449,7 @@ public class Game extends BasicGameState {
beatLengthBase = beatLength = timingPoint.getBeatLength();
else
beatLength = beatLengthBase * timingPoint.getSliderMultiplier();
HitSound.setSampleSet(timingPoint.getSampleType());
HitSound.setDefaultSampleSet(timingPoint.getSampleType());
SoundController.setSampleVolume(timingPoint.getSampleVolume());
timingPointIndex++;
}
@ -728,7 +728,7 @@ public class Game extends BasicGameState {
OsuTimingPoint timingPoint = osu.timingPoints.get(0);
if (!timingPoint.isInherited()) {
beatLengthBase = beatLength = timingPoint.getBeatLength();
HitSound.setSampleSet(timingPoint.getSampleType());
HitSound.setDefaultSampleSet(timingPoint.getSampleType());
SoundController.setSampleVolume(timingPoint.getSampleVolume());
timingPointIndex++;
}

View File

@ -1264,7 +1264,7 @@ public class SongMenu extends BasicGameState {
OsuFile osu = MusicController.getOsuFile();
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
OsuParser.parseHitObjects(osu);
HitSound.setSampleSet(osu.sampleSet);
HitSound.setDefaultSampleSet(osu.sampleSet);
MultiClip.destroyExtraClips();
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.NEW);
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));