Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make gameplay time completely based on audio time #489

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions res/xml/settings_input.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@

<PreferenceCategory android:title="@string/opt_category_synchronization">

<CheckBoxPreference
android:defaultValue="true"
android:key="syncMusic"
android:summary="@string/opt_syncmusic_summary"
android:title="@string/opt_syncmusic_title" />

<CheckBoxPreference
android:defaultValue="true"
android:key="fixFrameOffset"
Expand Down
10 changes: 0 additions & 10 deletions src/ru/nsu/ccfit/zuev/osu/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public class Config {
enableExtension,
loadAvatar,
stayOnline,
syncMusic,
burstEffects,
hitLighting,
useParticles,
Expand Down Expand Up @@ -181,7 +180,6 @@ public static void loadConfig(final Context context) {
skinTopPath += "/";
}

syncMusic = prefs.getBoolean("syncMusic", syncMusic);
enableExtension = false;// prefs.getBoolean("enableExtension", false);
cachePath = context.getCacheDir().getPath();
burstEffects = prefs.getBoolean("bursts", burstEffects);
Expand Down Expand Up @@ -512,14 +510,6 @@ public static String getOnlineDeviceID() {
return onlineDeviceID;
}

public static boolean isSyncMusic() {
return syncMusic;
}

public static void setSyncMusic(boolean syncMusic) {
Config.syncMusic = syncMusic;
}

public static String getCachePath() {
return cachePath;
}
Expand Down
117 changes: 49 additions & 68 deletions src/ru/nsu/ccfit/zuev/osu/game/GameScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@
import ru.nsu.ccfit.zuev.skins.OsuSkin;
import ru.nsu.ccfit.zuev.skins.BeatmapSkinManager;

public class GameScene implements IUpdateHandler, GameObjectListener,
IOnSceneTouchListener {
public class GameScene implements GameObjectListener, IOnSceneTouchListener {
public static final int CursorCount = 10;
private final Engine engine;
private final Cursor[] cursors = new Cursor[CursorCount];
Expand Down Expand Up @@ -229,13 +228,6 @@ public class GameScene implements IUpdateHandler, GameObjectListener,

// Timing

/**
* The time at which the last frame was rendered with respect to {@link SystemClock#uptimeMillis()}.
* <br>
* If 0, a frame has not been rendered yet.
*/
private long previousFrameTime;

/**
* The start time of the first object in seconds.
*/
Expand Down Expand Up @@ -295,7 +287,7 @@ public class GameScene implements IUpdateHandler, GameObjectListener,

public GameScene(final Engine engine) {
this.engine = engine;
scene = new ExtendedScene();
scene = createMainScene();
bgScene = new ExtendedScene();
fgScene = new ExtendedScene();
mgScene = new ExtendedScene();
Expand Down Expand Up @@ -496,7 +488,6 @@ private boolean loadGame(final BeatmapInfo beatmapInfo, final String rFile, @Nul
GameHelper.setOverallDifficulty(playableBeatmap.getDifficulty().od);
GameHelper.setHealthDrain(playableBeatmap.getDifficulty().hp);
GameHelper.setSpeedMultiplier(modMenu.getSpeed());
scene.setTimeMultiplier(GameHelper.getSpeedMultiplier());

if (scope != null) {
JobKt.ensureActive(scope.getCoroutineContext());
Expand All @@ -510,6 +501,7 @@ private boolean loadGame(final BeatmapInfo beatmapInfo, final String rFile, @Nul
JobKt.ensureActive(scope.getCoroutineContext());
}

totalLength = GlobalManager.getInstance().getSongService().getLength();
objects = new LinkedList<>(playableBeatmap.getHitObjects().objects);
activeObjects = new LinkedList<>();
expiredObjects = new LinkedList<>();
Expand Down Expand Up @@ -671,7 +663,7 @@ public void startGame(BeatmapInfo beatmapInfo, String replayFile, boolean isHUDE
isHUDEditorMode = isHUDEditor;
startedFromHUDEditor = isHUDEditor;

scene = new ExtendedScene();
scene = createMainScene();
if (Config.isEnableStoryboard()) {
if (storyboardSprite == null || storyboardOverlayProxy == null) {
storyboardSprite = new StoryboardSprite(Config.getRES_WIDTH(), Config.getRES_HEIGHT());
Expand Down Expand Up @@ -807,7 +799,6 @@ private void prepareScene() {

comboWas100 = false;
comboWasMissed = false;
previousFrameTime = 0;

hitWindow = playableBeatmap.getHitWindow();
firstObjectStartTime = (float) objects.peek().startTime / 1000;
Expand Down Expand Up @@ -1017,8 +1008,6 @@ public void start() {
engine.getTouchController().applyTouchOptions(touchOptions);

engine.setScene(scene);
scene.registerUpdateHandler(this);

engine.getCamera().setHUD(hud.getParent());

blockAreaFragment = new BlockAreaFragment();
Expand All @@ -1033,37 +1022,14 @@ public RGBColor getComboColor(int num) {
return comboColors.get(num % comboColors.size());
}

@Override
public void onUpdate(final float pSecondsElapsed) {
previousFrameTime = SystemClock.uptimeMillis();

float dt = pSecondsElapsed;
if (GlobalManager.getInstance().getSongService().getStatus() == Status.PLAYING) {
//处理时间差过于庞大的情况
final float realsecPassed = //Config.isSyncMusic() ?
GlobalManager.getInstance().getSongService().getPosition() / 1000.0f;// : realTime;
final float criticalError = Config.isSyncMusic() ? 0.1f : 0.5f;
final float normalError = Config.isSyncMusic() ? dt : 0.05f;

if (elapsedTime - totalOffset - realsecPassed > criticalError) {
return;
}

if (Math.abs(elapsedTime - totalOffset - realsecPassed) > normalError) {
if (elapsedTime - totalOffset > realsecPassed) {
dt /= 2f;
} else {
dt *= 2f;
}
}
elapsedTime += dt;
}
private void update(final float dt) {
elapsedTime += dt;

updateCounterTexts();

if (Multiplayer.isMultiplayer)
{
long mSecElapsed = (long) (pSecondsElapsed * 1000);
long mSecElapsed = (long) (dt / GameHelper.getSpeedMultiplier() * 1000);
realTimeElapsed += mSecElapsed;
statisticDataTimeElapsed += mSecElapsed;

Expand Down Expand Up @@ -1314,16 +1280,6 @@ public void onUpdate(final float pSecondsElapsed) {
video.setAlpha(Math.min(video.getAlpha() + 0.03f, 1.0f));
}

if (elapsedTime >= totalOffset && !musicStarted) {
GlobalManager.getInstance().getSongService().play();
GlobalManager.getInstance().getSongService().setVolume(Config.getBgmVolume());
totalLength = GlobalManager.getInstance().getSongService().getLength();
musicStarted = true;
elapsedTime = totalOffset;

return;
}

boolean shouldBePunished = false;

while (!objects.isEmpty()
Expand Down Expand Up @@ -1425,13 +1381,6 @@ public void onUpdate(final float pSecondsElapsed) {
metronome.update(elapsedTime, activeTimingPoint);
}

//Status playerStatus = music.getStatus();
Status playerStatus = GlobalManager.getInstance().getSongService().getStatus();

if (playerStatus != Status.PLAYING) {
elapsedTime += dt;
}

if (shouldBePunished || (objects.isEmpty() && activeObjects.isEmpty() && leadOut > 2)) {

// Reset the game to continue the HUD editor session.
Expand All @@ -1443,7 +1392,7 @@ public void onUpdate(final float pSecondsElapsed) {
return;
}

scene = new ExtendedScene();
scene = createMainScene();
engine.getCamera().setHUD(null);
BeatmapSkinManager.setSkinEnabled(false);
GameObjectPool.getInstance().purge();
Expand Down Expand Up @@ -1754,7 +1703,7 @@ public void quit() {
camera.setCenterDirect((float) Config.getRES_WIDTH() / 2, (float) Config.getRES_HEIGHT() / 2);
}
}
scene = new ExtendedScene();
scene = createMainScene();
engine.getCamera().setHUD(null);

if (Multiplayer.isMultiplayer)
Expand Down Expand Up @@ -2127,6 +2076,9 @@ public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent event) {
return false;
}

int eventTime = GlobalManager.getInstance().getSongService().getPosition();
float offset = eventTime / 1000f - elapsedTime;

var id = event.getPointerID();
if (id < 0 || id >= CursorCount) {
return false;
Expand All @@ -2144,17 +2096,14 @@ public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent event) {
sprite.setPosition(cursor.mousePos.x, cursor.mousePos.y);
}

var frameOffset = previousFrameTime > 0 ? (event.getMotionEvent().getEventTime() - previousFrameTime) * GameHelper.getSpeedMultiplier() : 0;
var eventTime = (int) (elapsedTime * 1000 + frameOffset);

if (event.isActionDown()) {

if (sprite != null) {
sprite.setShowing(true);
}

cursor.mouseDown = true;
cursor.mouseDownOffsetMS = frameOffset;
cursor.mouseDownOffsetMS = offset;

for (var value : cursors)
value.mouseOldDown = false;
Expand Down Expand Up @@ -2194,8 +2143,7 @@ public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent event) {
}

private void removeAllCursors() {
var frameOffset = previousFrameTime > 0 ? (SystemClock.uptimeMillis() - previousFrameTime) * GameHelper.getSpeedMultiplier() : 0;
var time = (int) (elapsedTime * 1000 + frameOffset);
int time = GlobalManager.getInstance().getSongService().getPosition();

for (int i = 0; i < CursorCount; ++i) {
var cursor = cursors[i];
Expand Down Expand Up @@ -2375,8 +2323,6 @@ public void onUpdate(float pSecondsElapsed) {
float decreasedFrequency = Math.max(101, songService.getFrequency() - 300);
float decreasedSpeed = GameHelper.getSpeedMultiplier() * (1 - (initialFrequency - decreasedFrequency) / initialFrequency);

scene.setTimeMultiplier(decreasedSpeed);

if (video != null) {
// In some devices this can throw an exception, unfortunately there's no
// documentation that explains how to avoid that scenario. Thanks Google.
Expand Down Expand Up @@ -2805,4 +2751,39 @@ private double getStandardPPAt(int objectId) {

return BeatmapDifficultyCalculator.calculateStandardPerformance(timedAttributes.attributes, stat).total;
}

private ExtendedScene createMainScene() {
return new ExtendedScene() {
@Override
protected void onManagedUpdate(float secElapsed) {
float dt = secElapsed;
var songService = GlobalManager.getInstance().getSongService();

if (songService.getStatus() == Status.PLAYING) {
dt = songService.getPosition() / 1000f - (elapsedTime - totalOffset);

// BASS may report the wrong position. When that happens, `dt` will
// be negative. In that case, we should ignore the update.
// See https://github.com/ppy/osu/issues/26879 for more information.
if (dt <= 0) {
return;
}
} else if (!musicStarted) {
// Cap elapsed time at the music start time to prevent objects from progressing too far.
dt = Math.min(elapsedTime + dt, totalOffset) - elapsedTime;

if (elapsedTime >= totalOffset && !musicStarted) {
Execution.updateThread(() -> {
songService.play();
songService.setVolume(Config.getBgmVolume());
musicStarted = true;
});
}
}

update(dt);
super.onManagedUpdate(dt);
}
};
}
}
Loading