Skip to content

Commit

Permalink
Enhance Practice Mode Bookmarks with simple Region Loop
Browse files Browse the repository at this point in the history
also added ctrl clicking as an alternative
just a tiny secret feature
not really worth anything
  • Loading branch information
poco0317 committed Nov 5, 2019
1 parent aee8eb7 commit 418fea6
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,63 @@ local musicratio = 1
local wodth = capWideScale(get43size(240), 280)
local hidth = 40
local cd
local bookmarkPosition
local loopStartPos
local loopEndPos

local function handleRegionSetting(positionGiven)

-- first time starting a region
if not loopStartPos and not loopEndPos then
loopStartPos = positionGiven
MESSAGEMAN:Broadcast("RegionSet")
return
end

-- reset region to bookmark only if double right click
if positionGiven == loopStartPos or positionGiven == loopEndPos then
loopEndPos = nil
loopStartPos = positionGiven
MESSAGEMAN:Broadcast("RegionSet")
SCREENMAN:GetTopScreen():ResetLoopRegion()
return
end

-- measure the difference of the new pos from each end
local startDiff = math.abs(positionGiven - loopStartPos)
local endDiff = startDiff + 0.1
if loopEndPos then
endDiff = math.abs(positionGiven - loopEndPos)
end

-- use the diff to figure out which end to move

-- if there is no end, then you place the end
if not loopEndPos then
if loopStartPos < positionGiven then
loopEndPos = positionGiven
elseif loopStartPos > positionGiven then
loopEndPos = loopStartPos
loopStartPos = positionGiven
else
-- this should never happen
-- but if it does, reset to bookmark
loopEndPos = nil
loopStartPos = positionGiven
MESSAGEMAN:Broadcast("RegionSet")
SCREENMAN:GetTopScreen():ResetLoopRegion()
return
end
else
-- closer to the start, move the start
if startDiff < endDiff then
loopStartPos = positionGiven
else
loopEndPos = positionGiven
end
end
SCREENMAN:GetTopScreen():SetLoopRegion(loopStartPos * getCurRateValue(), loopEndPos * getCurRateValue())
MESSAGEMAN:Broadcast("RegionSet", {loopLength = loopEndPos-loopStartPos})
end

local function duminput(event)
if event.type == "InputEventType_Release" then
Expand All @@ -950,16 +1006,15 @@ local function duminput(event)
end
elseif event.type == "InputEventType_FirstPress" then
if event.DeviceInput.button == "DeviceButton_backspace" then
if bookmarkPosition ~= nil then
SCREENMAN:GetTopScreen():SetSongPositionAndUnpause(bookmarkPosition, 1, true)
if loopStartPos ~= nil then
SCREENMAN:GetTopScreen():SetSongPositionAndUnpause(loopStartPos, 1, true)
end
elseif event.button == "EffectUp" then
SCREENMAN:GetTopScreen():AddToRate(0.05)
elseif event.button == "EffectDown" then
SCREENMAN:GetTopScreen():AddToRate(-0.05)
elseif event.button == "Coin" then
bookmarkPosition = SCREENMAN:GetTopScreen():GetSongPosition()
cd:GetParent():GetChild("BookmarkPos"):playcommand("Set")
handleRegionSetting(SCREENMAN:GetTopScreen():GetSongPosition())
elseif event.DeviceInput.button == "DeviceButton_mousewheel up" then
if GAMESTATE:IsPaused() then
local pos = SCREENMAN:GetTopScreen():GetSongPosition()
Expand Down Expand Up @@ -1067,13 +1122,17 @@ pm[#pm + 1] =
end,
MouseLeftClickMessageCommand = function(self)
if isOver(self) then
SCREENMAN:GetTopScreen():SetSongPosition(self:GetX() * musicratio, 0, false)
local withCtrl = INPUTFILTER:IsControlPressed()
if withCtrl then
handleRegionSetting(self:GetX() * musicratio)
else
SCREENMAN:GetTopScreen():SetSongPosition(self:GetX() * musicratio, 0, false)
end
end
end,
MouseRightClickMessageCommand = function(self)
if isOver(self) then
bookmarkPosition = self:GetX() * musicratio
self:GetParent():GetChild("BookmarkPos"):queuecommand("Set")
handleRegionSetting(self:GetX() * musicratio)
else
if not (allowedCustomization) then
SCREENMAN:GetTopScreen():TogglePause()
Expand All @@ -1091,7 +1150,24 @@ pm[#pm + 1] =
end,
SetCommand = function(self)
self:visible(true)
self:x(bookmarkPosition / musicratio)
self:zoomto(2, hidth):diffuse(color(".2,.5,1,1")):halign(0.5)
self:x(loopStartPos / musicratio)
end,
RegionSetMessageCommand = function(self, params)
if not params or not params.loopLength then
self:playcommand("Set")
else
self:visible(true)
self:x(loopStartPos / musicratio):halign(0)
self:zoomto(params.loopLength / musicratio, hidth):diffuse(color(".7,.2,.7,0.5"))
end
end,
CurrentRateChangedMessageCommand = function(self)
if not loopEndPos and loopStartPos then
self:playcommand("Set")
elseif loopEndPos and loopStartPos then
self:playcommand("RegionSet", {loopLength = (loopEndPos - loopStartPos)})
end
end
}

Expand Down
100 changes: 85 additions & 15 deletions src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,23 @@ ScreenGameplayPractice::TogglePause()
RageSoundParams p = m_pSoundMusic->GetParams();
p.m_StartSecond = fSeconds - 0.01f;
p.m_fSpeed = rate;
if (fSecondsToStartFadingOutMusic <
GAMESTATE->m_pCurSong->m_fMusicLengthSeconds) {
if (loopStart != loopEnd) {
p.m_fFadeOutSeconds = 3.f;
p.m_LengthSeconds = loopEnd + 3.f - loopStart;
p.StopMode = RageSoundParams::M_LOOP;
} else {
p.m_fFadeOutSeconds = MUSIC_FADE_OUT_SECONDS;
p.m_LengthSeconds = fSecondsToStartFadingOutMusic +
MUSIC_FADE_OUT_SECONDS - p.m_StartSecond;
p.StopMode = RageSoundParams::M_CONTINUE;
}
p.StopMode = RageSoundParams::M_CONTINUE;
p.m_bAccurateSync = true;
// Go
m_pSoundMusic->Play(false, &p);
if (loopStart != loopEnd) {
p.m_StartSecond = loopStart;
m_pSoundMusic->SetParams(p);
}
}

m_pSoundMusic->Pause(newPause);
Expand All @@ -219,9 +226,12 @@ ScreenGameplayPractice::SetSongPosition(float newSongPositionSeconds,
bool unpause)
{
bool isPaused = GAMESTATE->GetPaused();

RageSoundParams p = m_pSoundMusic->GetParams();

// Letting this execute will freeze the music and thats bad
if (loopStart != loopEnd && newSongPositionSeconds > loopEnd)
return;

// If paused, we need to move fast so dont use slow seeking
// but if we want to hard seek, we dont care about speed
p.m_bAccurateSync = !isPaused || hardSeek;
Expand Down Expand Up @@ -272,9 +282,9 @@ ScreenGameplayPractice::AddToRate(float amountAdded)
if (newRate <= 0.25f || newRate > 3.f)
return rate;

bool paused = GAMESTATE->GetPaused();
// bool paused = GAMESTATE->GetPaused();

m_pSoundMusic->Stop();
// m_pSoundMusic->Stop();

RageTimer tm;
const float fSeconds = m_pSoundMusic->GetPositionSeconds(NULL, &tm);
Expand All @@ -284,33 +294,77 @@ ScreenGameplayPractice::AddToRate(float amountAdded)
fSecondsToStartTransitioningOut);

RageSoundParams p;
p.m_StartSecond = fSeconds;
// p.m_StartSecond = fSeconds;
p.m_fSpeed = newRate;
GAMESTATE->m_SongOptions.GetSong().m_fMusicRate = newRate;
GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate = newRate;
GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = newRate;
if (paused)
p.m_Volume = 0.f;
if (fSecondsToStartFadingOutMusic <
GAMESTATE->m_pCurSong->m_fMusicLengthSeconds) {
// if (paused)
// p.m_Volume = 0.f;
if (loopStart != loopEnd) {
p.m_StartSecond = loopStart;
p.m_fFadeOutSeconds = 3.f;
p.m_LengthSeconds = (loopEnd + 3.f - loopStart);
p.StopMode = RageSoundParams::M_LOOP;
} else {
p.m_fFadeOutSeconds = MUSIC_FADE_OUT_SECONDS;
p.m_LengthSeconds = fSecondsToStartFadingOutMusic +
MUSIC_FADE_OUT_SECONDS - p.m_StartSecond;
p.StopMode = RageSoundParams::M_CONTINUE;
}
p.StopMode = RageSoundParams::M_CONTINUE;
p.m_bAccurateSync = true;
// Go
m_pSoundMusic->Play(false, &p);
m_pSoundMusic->SetParams(p);
// m_pSoundMusic->Play(false, &p);
// But only for like 1 frame if we are paused
if (paused)
m_pSoundMusic->Pause(true);
// if (paused)
// m_pSoundMusic->Pause(true);
GAMESTATE->m_Position.m_fMusicSeconds = fSeconds;

MESSAGEMAN->Broadcast(
"CurrentRateChanged"); // Tell the theme we changed the rate
return newRate;
}

void
ScreenGameplayPractice::SetLoopRegion(float start, float end)
{
loopStart = start;
loopEnd = end;

RageSoundParams p = m_pSoundMusic->GetParams();
p.m_StartSecond = start;
p.m_fFadeOutSeconds = MUSIC_FADE_OUT_SECONDS;
p.m_LengthSeconds = end + MUSIC_FADE_OUT_SECONDS - start;
p.StopMode = RageSoundParams::M_LOOP;

m_pSoundMusic->SetParams(p);
}

void
ScreenGameplayPractice::ResetLoopRegion()
{
loopStart = -2000.f;
loopEnd = -2000.f;

RageTimer tm;
const float fSeconds = m_pSoundMusic->GetPositionSeconds(NULL, &tm);

float fSecondsToStartFadingOutMusic, fSecondsToStartTransitioningOut;
GetMusicEndTiming(fSecondsToStartFadingOutMusic,
fSecondsToStartTransitioningOut);

RageSoundParams p = m_pSoundMusic->GetParams();
p.m_StartSecond = GAMESTATE->m_pCurSong->GetFirstSecond() *
GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
p.m_fFadeOutSeconds = MUSIC_FADE_OUT_SECONDS;
p.m_LengthSeconds =
fSecondsToStartFadingOutMusic + MUSIC_FADE_OUT_SECONDS - p.m_StartSecond;
p.StopMode = RageSoundParams::M_CONTINUE;

m_pSoundMusic->SetParams(p);
}

class LunaScreenGameplayPractice : public Luna<ScreenGameplayPractice>
{
public:
Expand Down Expand Up @@ -345,12 +399,28 @@ class LunaScreenGameplayPractice : public Luna<ScreenGameplayPractice>
return 0;
}

static int SetLoopRegion(T* p, lua_State* L)
{
float begin = FArg(1);
float end = FArg(2);
p->SetLoopRegion(begin, end);
return 0;
}

static int ResetLoopRegion(T* p, lua_State* L)
{
p->ResetLoopRegion();
return 0;
}

LunaScreenGameplayPractice()
{
ADD_METHOD(SetSongPosition);
ADD_METHOD(SetSongPositionAndUnpause);
ADD_METHOD(AddToRate);
ADD_METHOD(TogglePause);
ADD_METHOD(SetLoopRegion);
ADD_METHOD(ResetLoopRegion);
}
};

Expand Down
8 changes: 8 additions & 0 deletions src/Etterna/Screen/Gameplay/ScreenGameplayPractice.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,18 @@ class ScreenGameplayPractice : public ScreenGameplay
// Toggle pause
void TogglePause();

// Practice Looper
void SetLoopRegion(float start, float end);
void ResetLoopRegion();

protected:
void SetupNoteDataFromRow(Steps* pSteps,
int minRow = 0,
int maxrow = MAX_NOTE_ROW);

private:
float loopStart = -2000.f;
float loopEnd = -2000.f;
};

#endif

0 comments on commit 418fea6

Please sign in to comment.