Skip to content

Commit

Permalink
Merge pull request #1051 from graemephi/butter
Browse files Browse the repository at this point in the history
Butter
  • Loading branch information
poco0317 authored Sep 18, 2021
2 parents 6c9036c + 86c8722 commit b07c8aa
Show file tree
Hide file tree
Showing 18 changed files with 281 additions and 307 deletions.
2 changes: 1 addition & 1 deletion src/Etterna/Actor/Base/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ Actor::UpdateInternal(float delta_time)
break;
case CLOCK_TIMER_GLOBAL:
generic_global_timer_update(
static_cast<float>(RageTimer::GetUsecsSinceStart()),
RageTimer::GetTimeSinceStart(),
m_fEffectDelta,
m_fSecsIntoEffect);
break;
Expand Down
59 changes: 10 additions & 49 deletions src/Etterna/Actor/Gameplay/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1932,25 +1932,15 @@ Player::Step(int col,
bool bRelease,
float padStickSeconds)
{
// Do everything that depends on a timer here;
// set your breakpoints somewhere after this block.
std::chrono::duration<float> stepDelta =
std::chrono::steady_clock::now() - tm;
auto stepAgo = stepDelta.count() - padStickSeconds;

const auto fLastBeatUpdate = GAMESTATE->m_Position.m_LastBeatUpdate.Ago();
const auto fPositionSeconds =
GAMESTATE->m_Position.m_fMusicSeconds - stepAgo;
const auto fTimeSinceStep = stepAgo;

// input data
//m_pPlayerStageStats->InputData.emplace_back(!bRelease, col, fPositionSeconds);

auto fSongBeat = GAMESTATE->m_Position.m_fSongBeat;

if (GAMESTATE->m_pCurSteps != nullptr) {
fSongBeat = m_Timing->GetBeatFromElapsedTime(fPositionSeconds);
}
const auto fMusicRate =
GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
const auto fHitUpdateDelta =
(GAMESTATE->m_Position.m_LastBeatUpdate - RageTimer(tm)) - padStickSeconds;
const auto fMusicSeconds =
GAMESTATE->m_Position.m_fMusicSeconds - (fHitUpdateDelta * fMusicRate);
const auto fSongBeat =
GAMESTATE->m_pCurSteps ? m_Timing->GetBeatFromElapsedTime(fMusicSeconds)
: GAMESTATE->m_Position.m_fSongBeat;

const auto iSongRow = row == -1 ? BeatToNoteRow(fSongBeat) : row;

Expand Down Expand Up @@ -2108,41 +2098,12 @@ Player::Step(int col,
if (iRowOfOverlappingNoteOrRow != -1 && col != -1) {
// compute the score for this hit
auto fNoteOffset = 0.F;
// only valid if
auto fMusicSeconds = 0.F;
// we need this later if we are autosyncing
const auto fStepBeat = NoteRowToBeat(iRowOfOverlappingNoteOrRow);
const auto fStepSeconds = m_Timing->WhereUAtBro(fStepBeat);

if (row == -1) {
// We actually stepped on the note this long ago:
// fTimeSinceStep

/* GAMESTATE->m_fMusicSeconds is the music time as of
* GAMESTATE->m_LastBeatUpdate. Figure out what the music time
* is as of now. */
const auto fCurrentMusicSeconds =
GAMESTATE->m_Position.m_fMusicSeconds +
(fLastBeatUpdate *
GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate);

// ... which means it happened at this point in the music:
fMusicSeconds =
fCurrentMusicSeconds -
fTimeSinceStep *
GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;

// The offset from the actual step in seconds:
fNoteOffset = (fStepSeconds - fMusicSeconds) /
GAMESTATE->m_SongOptions.GetCurrent()
.m_fMusicRate; // account for music rate
/*
LOG->Trace("step was %.3f ago, music is off by %f: %f vs %f,
step was %f off",
fTimeSinceStep,
GAMESTATE->m_LastBeatUpdate.Ago()/GAMESTATE->m_SongOptions.m_fMusicRate,
fStepSeconds, fMusicSeconds, fNoteOffset );
*/
fNoteOffset = (fStepSeconds - fMusicSeconds) / fMusicRate;
}

NOTESKIN->SetLastSeenColor(
Expand Down
23 changes: 12 additions & 11 deletions src/Etterna/Screen/Gameplay/ScreenGameplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ ScreenGameplay::StartPlayingSong(float fMinTimeToNotes, float fMinTimeToMusic)

/* Make sure GAMESTATE->m_fMusicSeconds is set up. */
GAMESTATE->m_Position.m_fMusicSeconds = -5000;
UpdateSongPosition(0);
UpdateSongPosition();

ASSERT(GAMESTATE->m_Position.m_fMusicSeconds >
-4000); /* make sure the "fake timer" code doesn't trigger */
Expand Down Expand Up @@ -772,17 +772,18 @@ ScreenGameplay::PlayAnnouncer(const std::string& type,
}

void
ScreenGameplay::UpdateSongPosition(float fDeltaTime)
ScreenGameplay::UpdateSongPosition()
{
if (!m_pSoundMusic->IsPlaying()) {
return;
}

RageTimer tm;
const auto rate = GAMESTATE->m_SongOptions.GetSong().m_fMusicRate;

RageTimer tm = RageZeroTimer;
const auto fSeconds = m_pSoundMusic->GetPositionSeconds(nullptr, &tm);
const auto fAdjust = SOUND->GetFrameTimingAdjustment(fDeltaTime);
GAMESTATE->UpdateSongPosition(
fSeconds + fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm + fAdjust);
fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm);
}

void
Expand Down Expand Up @@ -887,7 +888,7 @@ ScreenGameplay::Update(float fDeltaTime)
return;
}

UpdateSongPosition(fDeltaTime);
UpdateSongPosition();

if (m_bZeroDeltaOnNextUpdate) {
ScreenWithMenuElements::Update(0);
Expand Down Expand Up @@ -1355,7 +1356,7 @@ ScreenGameplay::Input(const InputEventPlus& input) -> bool
if (!input.GameI.IsValid()) {
return false;
}


/* Restart gameplay button moved from theme to allow for rebinding for
* people who dont want to edit lua files :)
*/
Expand All @@ -1365,13 +1366,13 @@ ScreenGameplay::Input(const InputEventPlus& input) -> bool
bHoldingRestart |= input.MenuI == GAME_BUTTON_RESTART;
}
if (bHoldingRestart && (m_DancingState != STATE_OUTRO || AllAreFailing())) {
// delayedback pref will work, or if it's off just go immediately
// delayedback pref will work, or if it's off just go immediately
// but also just let it be instant if you failed
if ((PREFSMAN->m_bDelayedBack &&
INPUTFILTER->GetSecsHeld(input.DeviceI) >= 1.0F) ||
!PREFSMAN->m_bDelayedBack || AllAreFailing())
RestartGameplay();
}
}

// Don't pass on any inputs to Player that aren't a press or a release.
switch (input.type) {
Expand All @@ -1380,8 +1381,8 @@ ScreenGameplay::Input(const InputEventPlus& input) -> bool
break;
default:
return false;
}

}

const auto iCol =
GAMESTATE->GetCurrentStyle(input.pn)->GameInputToColumn(input.GameI);

Expand Down
2 changes: 1 addition & 1 deletion src/Etterna/Screen/Gameplay/ScreenGameplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ScreenGameplay : public ScreenWithMenuElements

void PlayTicks();
// Used to update some pointers
void UpdateSongPosition(float fDeltaTime);
void UpdateSongPosition();
void SongFinished();
virtual void SaveStats();
virtual void StageFinished(bool bBackedOut);
Expand Down
4 changes: 2 additions & 2 deletions src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ ScreenGameplayPractice::Update(const float fDeltaTime)
return;
}

UpdateSongPosition(fDeltaTime);
UpdateSongPosition();

if (m_bZeroDeltaOnNextUpdate) {
ScreenWithMenuElements::Update(0); // NOLINT(bugprone-parent-virtual-call)
Expand Down Expand Up @@ -382,7 +382,7 @@ ScreenGameplayPractice::SetSongPosition(float newSongPositionSeconds,

// Set the final position
SOUND->SetSoundPosition(m_pSoundMusic, newSongPositionSeconds - noteDelay);
UpdateSongPosition(0);
UpdateSongPosition();

// Unpause the music if we want it unpaused
if (unpause && isPaused) {
Expand Down
4 changes: 2 additions & 2 deletions src/Etterna/Screen/Gameplay/ScreenGameplayReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ ScreenGameplayReplay::Update(const float fDeltaTime)
return;
}

UpdateSongPosition(fDeltaTime);
UpdateSongPosition();

if (m_bZeroDeltaOnNextUpdate) {
ScreenWithMenuElements::Update(0); // NOLINT(bugprone-parent-virtual-call)
Expand Down Expand Up @@ -359,7 +359,7 @@ ScreenGameplayReplay::SetRate(const float newRate) -> float

// misc info update
GAMESTATE->m_Position.m_fMusicSeconds = fSeconds;
UpdateSongPosition(0);
UpdateSongPosition();
MESSAGEMAN->Broadcast(
"CurrentRateChanged"); // Tell the theme we changed the rate

Expand Down
2 changes: 1 addition & 1 deletion src/Etterna/Screen/Others/ScreenSelectMusic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1884,7 +1884,7 @@ class LunaScreenSelectMusic : public Luna<ScreenSelectMusic>
score->GetScoreKey().c_str());
p->SetNextScreenName("ScreenEvaluationNormal");
p->StartTransitioningScreen(SM_BeginFadingOut);

// set rate back to what it was before
GAMEMAN->m_bResetModifiers = true;
GAMEMAN->m_fPreviousRate = oldRate;
Expand Down
57 changes: 8 additions & 49 deletions src/Etterna/Singletons/GameSoundManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,44 +523,6 @@ GameSoundManager::~GameSoundManager()
SAFE_DELETE(g_Mutex);
}

float
GameSoundManager::GetFrameTimingAdjustment(float fDeltaTime)
{
/*
* We get one update per frame, and we're updated early, almost immediately
* after vsync, near the beginning of the game loop. However, it's very
* likely that we'll lose the scheduler while waiting for vsync, and some
* other thread will be working. Especially with a low-resolution scheduler
* (Linux 2.4, Win9x), we may not get the scheduler back immediately after
* the vsync; there may be up to a ~10ms delay. This can cause jitter in
* the rendered arrows.
*
* Compensate. If vsync is enabled, and we're maintaining the refresh rate
* consistently, we should have a very precise game loop interval. If we
* have that, but we're off by a small amount (less than the interval),
* adjust the time to line it up. As long as we adjust both the sound time
* and the timestamp, this won't adversely affect input timing. If we're off
* by more than that, we probably had a frame skip, in which case we have
* bigger skip problems, so don't adjust.
*/
static int iLastFPS = 0;
int iThisFPS = DISPLAY->GetFPS();

if (iThisFPS != (*DISPLAY->GetActualVideoModeParams()).rate ||
iThisFPS != iLastFPS) {
iLastFPS = iThisFPS;
return 0;
}

const float fExpectedDelay = 1.0f / iThisFPS;
const float fExtraDelay = fDeltaTime - fExpectedDelay;
if (fabsf(fExtraDelay) >= fExpectedDelay / 2)
return 0;

/* Subtract the extra delay. */
return std::min(-fExtraDelay, 0.F);
}

void
GameSoundManager::Update(float fDeltaTime)
{
Expand Down Expand Up @@ -634,12 +596,11 @@ GameSoundManager::Update(float fDeltaTime)
if (!g_UpdatingTimer)
return;

const float fAdjust = GetFrameTimingAdjustment(fDeltaTime);
const float fRate = g_Playing->m_Music->GetPlaybackRate();
if (!g_Playing->m_Music->IsPlaying()) {
/* There's no song playing. Fake it. */
GAMESTATE->UpdateSongPosition(GAMESTATE->m_Position.m_fMusicSeconds +
fDeltaTime *
g_Playing->m_Music->GetPlaybackRate(),
GAMESTATE->UpdateSongPosition(GAMESTATE->m_Position.m_fMusicSeconds
+ fDeltaTime * fRate,
g_Playing->m_Timing);
return;
}
Expand All @@ -649,15 +610,14 @@ GameSoundManager::Update(float fDeltaTime)
* timing data until we get a non-approximate time, indicating that the
* sound has actually started playing. */
bool m_bApproximate;
RageTimer tm;
RageTimer tm = RageZeroTimer;
const float fSeconds =
g_Playing->m_Music->GetPositionSeconds(&m_bApproximate, &tm);

// Check for song timing skips.
if (PREFSMAN->m_bLogSkips && !g_Playing->m_bTimingDelayed) {
const float fExpectedTimePassed =
(tm - GAMESTATE->m_Position.m_LastBeatUpdate) *
g_Playing->m_Music->GetPlaybackRate();
(tm - GAMESTATE->m_Position.m_LastBeatUpdate) * fRate;
const float fSoundTimePassed =
fSeconds - GAMESTATE->m_Position.m_fMusicSeconds;
const float fDiff = fExpectedTimePassed - fSoundTimePassed;
Expand Down Expand Up @@ -686,12 +646,11 @@ GameSoundManager::Update(float fDeltaTime)
if (g_Playing->m_bTimingDelayed) {
/* We're still waiting for the new sound to start playing, so keep using
* the old timing data and fake the time. */
GAMESTATE->UpdateSongPosition(GAMESTATE->m_Position.m_fMusicSeconds +
fDeltaTime,
GAMESTATE->UpdateSongPosition(GAMESTATE->m_Position.m_fMusicSeconds
+ fDeltaTime * fRate,
g_Playing->m_Timing);
} else {
GAMESTATE->UpdateSongPosition(
fSeconds + fAdjust, g_Playing->m_Timing, tm + fAdjust);
GAMESTATE->UpdateSongPosition(fSeconds, g_Playing->m_Timing);
}

// Send crossed messages
Expand Down
1 change: 0 additions & 1 deletion src/Etterna/Singletons/GameSoundManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class GameSoundManager : MessageSubscriber
void PlayOnceFromAnnouncer(const std::string& sFolderName);

void HandleSongTimer(bool on = true);
auto GetFrameTimingAdjustment(float fDeltaTime) -> float;

static auto GetPlayerBalance(PlayerNumber pn) -> float;
void WithRageSoundPlaying(std::function<void(RageSound*)> f);
Expand Down
22 changes: 0 additions & 22 deletions src/Etterna/Singletons/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,26 +758,6 @@ GameState::UpdateSongPosition(float fPositionSeconds,
const TimingData& timing,
const RageTimer& timestamp)
{
/* It's not uncommon to get a lot of duplicated positions from the sound
* driver, like so: 13.120953,13.130975,13.130975,13.130975,13.140998,...
* This causes visual stuttering of the arrows. To compensate, keep a
* RageTimer since the last change and multiply the delta by the current
* rate when applied. */
if (fPositionSeconds == m_LastPositionSeconds && !m_paused) {
// LOG->Info("Time unchanged, adding: %+f",
// m_LastPositionTimer.Ago()*m_SongOptions.GetSong().m_fMusicRate
//);
fPositionSeconds +=
m_LastPositionTimer.Ago() * m_SongOptions.GetSong().m_fMusicRate;
} else {
// LOG->Info("Time difference: %+f",
// m_LastPositionTimer.Ago() - (fPositionSeconds -
// m_LastPositionSeconds)
//);
m_LastPositionTimer.Touch();
m_LastPositionSeconds = fPositionSeconds;
}

if (m_pCurSteps) {
m_Position.UpdateSongPosition(
fPositionSeconds, *m_pCurSteps->GetTimingData(), timestamp);
Expand All @@ -791,8 +771,6 @@ GameState::UpdateSongPosition(float fPositionSeconds,
GAMESTATE->m_Position.m_fSongBeatVisible,
fPositionSeconds,
GAMESTATE->m_Position.m_fSongBeatNoOffset);
// LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f,
// m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze );
}

float
Expand Down
Loading

0 comments on commit b07c8aa

Please sign in to comment.