save offset per song and save it to db (from itdelatrisu/opsu@e023780)
This commit is contained in:
parent
54ce595c7f
commit
5b324bf6ba
|
@ -22,6 +22,7 @@ import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||||
import itdelatrisu.opsu.beatmap.TimingPoint;
|
import itdelatrisu.opsu.beatmap.TimingPoint;
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
|
import yugecin.opsudance.options.Options;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -358,10 +359,14 @@ public class MusicController {
|
||||||
* If no track is loaded, 0 will be returned.
|
* If no track is loaded, 0 will be returned.
|
||||||
*/
|
*/
|
||||||
public static int getPosition() {
|
public static int getPosition() {
|
||||||
|
int offset = OPTION_MUSIC_OFFSET.val;
|
||||||
|
if (lastBeatmap != null)
|
||||||
|
offset += lastBeatmap.localMusicOffset;
|
||||||
|
|
||||||
if (isPlaying())
|
if (isPlaying())
|
||||||
return (int) (player.getPosition() * 1000 + OPTION_MUSIC_OFFSET.val + Game.currentMapMusicOffset);
|
return (int) (player.getPosition() * 1000 + offset);
|
||||||
else if (isPaused())
|
else if (isPaused())
|
||||||
return Math.max((int) (pauseTime * 1000 + OPTION_MUSIC_OFFSET.val + Game.currentMapMusicOffset), 0);
|
return Math.max((int) (pauseTime * 1000 + offset), 0);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,9 @@ public class Beatmap implements Comparable<Beatmap> {
|
||||||
/** The last time this beatmap was played (timestamp). */
|
/** The last time this beatmap was played (timestamp). */
|
||||||
public long lastPlayed = 0;
|
public long lastPlayed = 0;
|
||||||
|
|
||||||
|
/** The local music offset. */
|
||||||
|
public int localMusicOffset = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [General]
|
* [General]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@ package itdelatrisu.opsu.db;
|
||||||
|
|
||||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||||
import itdelatrisu.opsu.beatmap.BeatmapParser;
|
import itdelatrisu.opsu.beatmap.BeatmapParser;
|
||||||
|
import yugecin.opsudance.core.errorhandling.ErrorHandler;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
@ -47,7 +48,7 @@ public class BeatmapDB {
|
||||||
* This value should be changed whenever the database format changes.
|
* This value should be changed whenever the database format changes.
|
||||||
* Add any update queries to the {@link #getUpdateQueries(int)} method.
|
* Add any update queries to the {@link #getUpdateQueries(int)} method.
|
||||||
*/
|
*/
|
||||||
private static final int DATABASE_VERSION = 20161222;
|
private static final int DATABASE_VERSION = 20161225;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of SQL queries to apply, in order, to update from
|
* Returns a list of SQL queries to apply, in order, to update from
|
||||||
|
@ -64,6 +65,10 @@ public class BeatmapDB {
|
||||||
list.add("ALTER TABLE beatmaps ADD COLUMN lastPlayed INTEGER");
|
list.add("ALTER TABLE beatmaps ADD COLUMN lastPlayed INTEGER");
|
||||||
list.add("UPDATE beatmaps SET dateAdded = 0, favorite = 0, playCount = 0, lastPlayed = 0");
|
list.add("UPDATE beatmaps SET dateAdded = 0, favorite = 0, playCount = 0, lastPlayed = 0");
|
||||||
}
|
}
|
||||||
|
if (version < 20161225) {
|
||||||
|
list.add("ALTER TABLE beatmaps ADD COLUMN localOffset INTEGER");
|
||||||
|
list.add("UPDATE beatmaps SET localOffset = 0");
|
||||||
|
}
|
||||||
|
|
||||||
/* add future updates here */
|
/* add future updates here */
|
||||||
|
|
||||||
|
@ -85,7 +90,7 @@ public class BeatmapDB {
|
||||||
/** Query statements. */
|
/** Query statements. */
|
||||||
private static PreparedStatement
|
private static PreparedStatement
|
||||||
insertStmt, selectStmt, deleteMapStmt, deleteGroupStmt,
|
insertStmt, selectStmt, deleteMapStmt, deleteGroupStmt,
|
||||||
setStarsStmt, updatePlayStatsStmt, setFavoriteStmt, updateSizeStmt;
|
setStarsStmt, updatePlayStatsStmt, setFavoriteStmt, setLocalOffsetStmt, updateSizeStmt;
|
||||||
|
|
||||||
/** Current size of beatmap cache table. */
|
/** Current size of beatmap cache table. */
|
||||||
private static int cacheSize = -1;
|
private static int cacheSize = -1;
|
||||||
|
@ -121,7 +126,7 @@ public class BeatmapDB {
|
||||||
"INSERT INTO beatmaps VALUES (" +
|
"INSERT INTO beatmaps VALUES (" +
|
||||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
|
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
|
||||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
|
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
|
||||||
"?, ?, ?, ?, ?, ?" +
|
"?, ?, ?, ?, ?, ?, ?" +
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
selectStmt = connection.prepareStatement("SELECT * FROM beatmaps WHERE dir = ? AND file = ?");
|
selectStmt = connection.prepareStatement("SELECT * FROM beatmaps WHERE dir = ? AND file = ?");
|
||||||
|
@ -130,6 +135,7 @@ public class BeatmapDB {
|
||||||
setStarsStmt = connection.prepareStatement("UPDATE beatmaps SET stars = ? WHERE dir = ? AND file = ?");
|
setStarsStmt = connection.prepareStatement("UPDATE beatmaps SET stars = ? WHERE dir = ? AND file = ?");
|
||||||
updatePlayStatsStmt = connection.prepareStatement("UPDATE beatmaps SET playCount = ?, lastPlayed = ? WHERE dir = ? AND file = ?");
|
updatePlayStatsStmt = connection.prepareStatement("UPDATE beatmaps SET playCount = ?, lastPlayed = ? WHERE dir = ? AND file = ?");
|
||||||
setFavoriteStmt = connection.prepareStatement("UPDATE beatmaps SET favorite = ? WHERE dir = ? AND file = ?");
|
setFavoriteStmt = connection.prepareStatement("UPDATE beatmaps SET favorite = ? WHERE dir = ? AND file = ?");
|
||||||
|
setLocalOffsetStmt = connection.prepareStatement("UPDATE beatmaps SET localOffset = ? WHERE dir = ? AND file = ?");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
explode("Failed to prepare beatmap statements.", e, DEFAULT_OPTIONS);
|
explode("Failed to prepare beatmap statements.", e, DEFAULT_OPTIONS);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +159,7 @@ public class BeatmapDB {
|
||||||
"mode INTEGER, letterboxInBreaks BOOLEAN, widescreenStoryboard BOOLEAN, epilepsyWarning BOOLEAN, " +
|
"mode INTEGER, letterboxInBreaks BOOLEAN, widescreenStoryboard BOOLEAN, epilepsyWarning BOOLEAN, " +
|
||||||
"bg TEXT, sliderBorder TEXT, timingPoints TEXT, breaks TEXT, combo TEXT, " +
|
"bg TEXT, sliderBorder TEXT, timingPoints TEXT, breaks TEXT, combo TEXT, " +
|
||||||
"md5hash TEXT, stars REAL, " +
|
"md5hash TEXT, stars REAL, " +
|
||||||
"dateAdded INTEGER, favorite BOOLEAN, playCount INTEGER, lastPlayed INTEGER" +
|
"dateAdded INTEGER, favorite BOOLEAN, playCount INTEGER, lastPlayed INTEGER, localOffset INTEGER" +
|
||||||
"); " +
|
"); " +
|
||||||
"CREATE TABLE IF NOT EXISTS info (" +
|
"CREATE TABLE IF NOT EXISTS info (" +
|
||||||
"key TEXT NOT NULL UNIQUE, value TEXT" +
|
"key TEXT NOT NULL UNIQUE, value TEXT" +
|
||||||
|
@ -402,6 +408,7 @@ public class BeatmapDB {
|
||||||
stmt.setBoolean(44, beatmap.favorite);
|
stmt.setBoolean(44, beatmap.favorite);
|
||||||
stmt.setInt(45, beatmap.playCount);
|
stmt.setInt(45, beatmap.playCount);
|
||||||
stmt.setLong(46, beatmap.lastPlayed);
|
stmt.setLong(46, beatmap.lastPlayed);
|
||||||
|
stmt.setInt(47, beatmap.localMusicOffset);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -549,6 +556,7 @@ public class BeatmapDB {
|
||||||
beatmap.favorite = rs.getBoolean(44);
|
beatmap.favorite = rs.getBoolean(44);
|
||||||
beatmap.playCount = rs.getInt(45);
|
beatmap.playCount = rs.getInt(45);
|
||||||
beatmap.lastPlayed = rs.getLong(46);
|
beatmap.lastPlayed = rs.getLong(46);
|
||||||
|
beatmap.localMusicOffset = rs.getInt(47);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -694,6 +702,24 @@ public class BeatmapDB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the local music offset for a beatmap in the database.
|
||||||
|
* @param beatmap the beatmap
|
||||||
|
*/
|
||||||
|
public static void updateLocalOffset(Beatmap beatmap) {
|
||||||
|
if (connection == null)
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
setLocalOffsetStmt.setInt(1, beatmap.localMusicOffset);
|
||||||
|
setLocalOffsetStmt.setString(2, beatmap.getFile().getParentFile().getName());
|
||||||
|
setLocalOffsetStmt.setString(3, beatmap.getFile().getName());
|
||||||
|
setLocalOffsetStmt.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
ErrorHandler.explode(String.format("Failed to update local music offset for beatmap '%s' in database.",
|
||||||
|
beatmap.toString()), e, ErrorHandler.DEFAULT_OPTIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connection to the database.
|
* Closes the connection to the database.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -265,8 +265,6 @@ public class Game extends ComplexOpsuState {
|
||||||
/** Music position bar coordinates and dimensions (for replay seeking). */
|
/** Music position bar coordinates and dimensions (for replay seeking). */
|
||||||
private float musicBarX, musicBarY, musicBarWidth, musicBarHeight;
|
private float musicBarX, musicBarY, musicBarWidth, musicBarHeight;
|
||||||
|
|
||||||
public static int currentMapMusicOffset;
|
|
||||||
|
|
||||||
private int mirrorFrom;
|
private int mirrorFrom;
|
||||||
private int mirrorTo;
|
private int mirrorTo;
|
||||||
|
|
||||||
|
@ -386,7 +384,7 @@ public class Game extends ComplexOpsuState {
|
||||||
public void render(Graphics g) {
|
public void render(Graphics g) {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (isLeadIn()) {
|
if (isLeadIn()) {
|
||||||
trackPosition -= leadInTime - currentMapMusicOffset - OPTION_MUSIC_OFFSET.val;
|
trackPosition -= leadInTime - OPTION_MUSIC_OFFSET.val - beatmap.localMusicOffset;
|
||||||
}
|
}
|
||||||
if (pauseTime > -1) // returning from pause screen
|
if (pauseTime > -1) // returning from pause screen
|
||||||
trackPosition = pauseTime;
|
trackPosition = pauseTime;
|
||||||
|
@ -439,7 +437,7 @@ public class Game extends ComplexOpsuState {
|
||||||
if (GameMod.FLASHLIGHT.isActive()) {
|
if (GameMod.FLASHLIGHT.isActive()) {
|
||||||
// render hit objects offscreen
|
// render hit objects offscreen
|
||||||
Graphics.setCurrent(gOffscreen);
|
Graphics.setCurrent(gOffscreen);
|
||||||
int trackPos = (isLeadIn()) ? (leadInTime - OPTION_MUSIC_OFFSET.val) * -1 : trackPosition;
|
int trackPos = (isLeadIn()) ? (leadInTime - OPTION_MUSIC_OFFSET.val - beatmap.localMusicOffset) * -1 : trackPosition;
|
||||||
drawHitObjects(gOffscreen, trackPos);
|
drawHitObjects(gOffscreen, trackPos);
|
||||||
|
|
||||||
// restore original graphics context
|
// restore original graphics context
|
||||||
|
@ -566,8 +564,8 @@ public class Game extends ComplexOpsuState {
|
||||||
Colors.WHITE_FADE.a = oldAlpha;
|
Colors.WHITE_FADE.a = oldAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLeadIn())
|
if (isLeadIn()) // render approach circles during song lead-in
|
||||||
trackPosition = (leadInTime - OPTION_MUSIC_OFFSET.val) * -1; // render approach circles during song lead-in
|
trackPosition = (leadInTime - OPTION_MUSIC_OFFSET.val - beatmap.localMusicOffset) * -1;
|
||||||
|
|
||||||
// countdown
|
// countdown
|
||||||
if (beatmap.countdown > 0) {
|
if (beatmap.countdown > 0) {
|
||||||
|
@ -1231,14 +1229,13 @@ public class Game extends ComplexOpsuState {
|
||||||
}
|
}
|
||||||
OPTION_DANCE_MIRROR.toggle();
|
OPTION_DANCE_MIRROR.toggle();
|
||||||
break;
|
break;
|
||||||
|
case KEY_SUBTRACT:
|
||||||
case KEY_MINUS:
|
case KEY_MINUS:
|
||||||
currentMapMusicOffset += 5;
|
adjustLocalMusicOffset(-5);
|
||||||
barNotifs.send("Current map offset: " + currentMapMusicOffset);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (key == KEY_ADD || c == '+') {
|
if (key == KEY_EQUALS || key == KEY_ADD || c == '+') {
|
||||||
currentMapMusicOffset -= 5;
|
adjustLocalMusicOffset(5);
|
||||||
barNotifs.send("Current map offset: " + currentMapMusicOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1650,6 +1647,10 @@ public class Game extends ComplexOpsuState {
|
||||||
scoreboardVisible = true;
|
scoreboardVisible = true;
|
||||||
currentScoreboardAlpha = 0f;
|
currentScoreboardAlpha = 0f;
|
||||||
|
|
||||||
|
// using local offset?
|
||||||
|
if (beatmap.localMusicOffset != 0)
|
||||||
|
barNotifs.send(String.format("Using local beatmap offset (%dms)", beatmap.localMusicOffset));
|
||||||
|
|
||||||
// needs to play before setting position to resume without lag later
|
// needs to play before setting position to resume without lag later
|
||||||
MusicController.play(false);
|
MusicController.play(false);
|
||||||
MusicController.setPosition(0);
|
MusicController.setPosition(0);
|
||||||
|
@ -1750,6 +1751,18 @@ public class Game extends ComplexOpsuState {
|
||||||
GameMod.loadModState(previousMods);
|
GameMod.loadModState(previousMods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the beatmap's local music offset.
|
||||||
|
* @param sign the sign (multiplier)
|
||||||
|
*/
|
||||||
|
public void adjustLocalMusicOffset(int amount) {
|
||||||
|
int newOffset = beatmap.localMusicOffset + amount;
|
||||||
|
barNotifs.send(String.format("Local beatmap offset set to %dms", newOffset));
|
||||||
|
if (beatmap.localMusicOffset != newOffset) {
|
||||||
|
beatmap.localMusicOffset = newOffset;
|
||||||
|
BeatmapDB.updateLocalOffset(beatmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
public void addMergedSliderPointsToRender(int from, int to) {
|
public void addMergedSliderPointsToRender(int from, int to) {
|
||||||
knorkesliders.addRange(from, to);
|
knorkesliders.addRange(from, to);
|
||||||
}
|
}
|
||||||
|
@ -1908,9 +1921,6 @@ public class Game extends ComplexOpsuState {
|
||||||
* @param beatmap the beatmap to load
|
* @param beatmap the beatmap to load
|
||||||
*/
|
*/
|
||||||
public void loadBeatmap(Beatmap beatmap) {
|
public void loadBeatmap(Beatmap beatmap) {
|
||||||
if (this.beatmap == null || this.beatmap.beatmapID != beatmap.beatmapID) {
|
|
||||||
currentMapMusicOffset = 0;
|
|
||||||
}
|
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
Display.setTitle(String.format("opsu!dance - %s", beatmap.toString()));
|
Display.setTitle(String.format("opsu!dance - %s", beatmap.toString()));
|
||||||
if (beatmap.breaks == null) {
|
if (beatmap.breaks == null) {
|
||||||
|
|
|
@ -117,6 +117,15 @@ public class GamePauseMenu extends BaseOpsuState {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == KEY_SUBTRACT || key == KEY_MINUS) {
|
||||||
|
gameState.adjustLocalMusicOffset(-5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (key == KEY_EQUALS || key == KEY_ADD || c == '+') {
|
||||||
|
gameState.adjustLocalMusicOffset(5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,7 +423,7 @@ public class Options {
|
||||||
|
|
||||||
public static final NumericOption OPTION_EFFECT_VOLUME = new NumericOption("Effects", "VolumeEffect", "Volume of menu and game sounds.", 70, 0, 100);
|
public static final NumericOption OPTION_EFFECT_VOLUME = new NumericOption("Effects", "VolumeEffect", "Volume of menu and game sounds.", 70, 0, 100);
|
||||||
public static final NumericOption OPTION_HITSOUND_VOLUME = new NumericOption("Hit Sounds", "VolumeHitSound", "Volume of hit sounds.", 30, 0, 100);
|
public static final NumericOption OPTION_HITSOUND_VOLUME = new NumericOption("Hit Sounds", "VolumeHitSound", "Volume of hit sounds.", 30, 0, 100);
|
||||||
public static final NumericOption OPTION_MUSIC_OFFSET = new NumericOption("Music Offset", "Offset", "Adjust this value if hit objects are out of sync.", -75, -500, 500) {
|
public static final NumericOption OPTION_MUSIC_OFFSET = new NumericOption("Global Music Offset", "Offset", "Adjust this value if hit objects are out of sync.", -75, -500, 500) {
|
||||||
@Override
|
@Override
|
||||||
public String getValueString () {
|
public String getValueString () {
|
||||||
return String.format("%dms", val);
|
return String.format("%dms", val);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user