mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
enhance editor toolbar sounds
This commit is contained in:
parent
48a92f1eac
commit
ca517f27b8
|
@ -618,7 +618,7 @@ void CSound::UnloadSample(int SampleID)
|
|||
m_aSamples[SampleID].m_pData = nullptr;
|
||||
}
|
||||
|
||||
float CSound::GetSampleDuration(int SampleID)
|
||||
float CSound::GetSampleTotalTime(int SampleID)
|
||||
{
|
||||
if(SampleID == -1 || SampleID >= NUM_SAMPLES)
|
||||
return 0.0f;
|
||||
|
@ -626,6 +626,50 @@ float CSound::GetSampleDuration(int SampleID)
|
|||
return (m_aSamples[SampleID].m_NumFrames / m_aSamples[SampleID].m_Rate);
|
||||
}
|
||||
|
||||
float CSound::GetSampleCurrentTime(int SampleID)
|
||||
{
|
||||
if(SampleID == -1 || SampleID >= NUM_SAMPLES)
|
||||
return 0.0f;
|
||||
|
||||
CSample *pSample = &m_aSamples[SampleID];
|
||||
if(IsPlaying(SampleID))
|
||||
{
|
||||
for(auto &Voice : m_aVoices)
|
||||
{
|
||||
if(Voice.m_pSample == pSample)
|
||||
{
|
||||
return (Voice.m_Tick / pSample->m_Rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pSample->m_PausedAt / pSample->m_Rate);
|
||||
}
|
||||
}
|
||||
|
||||
void CSound::SetSampleCurrentTime(int SampleID, float Time)
|
||||
{
|
||||
if(SampleID == -1 || SampleID >= NUM_SAMPLES)
|
||||
return;
|
||||
|
||||
CSample *pSample = &m_aSamples[SampleID];
|
||||
if(IsPlaying(SampleID))
|
||||
{
|
||||
for(auto &Voice : m_aVoices)
|
||||
{
|
||||
if(Voice.m_pSample == pSample)
|
||||
{
|
||||
Voice.m_Tick = pSample->m_NumFrames * Time;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pSample->m_PausedAt = pSample->m_NumFrames * Time;
|
||||
}
|
||||
}
|
||||
|
||||
void CSound::SetChannel(int ChannelID, float Vol, float Pan)
|
||||
{
|
||||
m_aChannels[ChannelID].m_Vol = (int)(Vol * 255.0f);
|
||||
|
@ -772,9 +816,18 @@ ISound::CVoiceHandle CSound::Play(int ChannelID, int SampleID, int Flags, float
|
|||
m_aVoices[VoiceID].m_pSample = &m_aSamples[SampleID];
|
||||
m_aVoices[VoiceID].m_pChannel = &m_aChannels[ChannelID];
|
||||
if(Flags & FLAG_LOOP)
|
||||
{
|
||||
m_aVoices[VoiceID].m_Tick = m_aSamples[SampleID].m_PausedAt;
|
||||
}
|
||||
else if(Flags & FLAG_PREVIEW)
|
||||
{
|
||||
m_aVoices[VoiceID].m_Tick = m_aSamples[SampleID].m_PausedAt;
|
||||
m_aSamples[SampleID].m_PausedAt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_aVoices[VoiceID].m_Tick = 0;
|
||||
}
|
||||
m_aVoices[VoiceID].m_Vol = 255;
|
||||
m_aVoices[VoiceID].m_Flags = Flags;
|
||||
m_aVoices[VoiceID].m_X = (int)x;
|
||||
|
@ -799,6 +852,21 @@ ISound::CVoiceHandle CSound::Play(int ChannelID, int SampleID, int Flags)
|
|||
return Play(ChannelID, SampleID, Flags, 0, 0);
|
||||
}
|
||||
|
||||
void CSound::Pause(int SampleID)
|
||||
{
|
||||
// TODO: a nice fade out
|
||||
std::unique_lock<std::mutex> Lock(m_SoundLock);
|
||||
CSample *pSample = &m_aSamples[SampleID];
|
||||
for(auto &Voice : m_aVoices)
|
||||
{
|
||||
if(Voice.m_pSample == pSample)
|
||||
{
|
||||
Voice.m_pSample->m_PausedAt = Voice.m_Tick;
|
||||
Voice.m_pSample = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSound::Stop(int SampleID)
|
||||
{
|
||||
// TODO: a nice fade out
|
||||
|
|
|
@ -96,7 +96,9 @@ public:
|
|||
int LoadWVFromMem(const void *pData, unsigned DataSize, bool FromEditor) override;
|
||||
void UnloadSample(int SampleID) override;
|
||||
|
||||
float GetSampleDuration(int SampleID) override; // in s
|
||||
float GetSampleTotalTime(int SampleID) override; // in s
|
||||
float GetSampleCurrentTime(int SampleID) override; // in s
|
||||
void SetSampleCurrentTime(int SampleID, float Time) override;
|
||||
|
||||
void SetChannel(int ChannelID, float Vol, float Pan) override;
|
||||
void SetListenerPos(float x, float y) override;
|
||||
|
@ -112,6 +114,7 @@ public:
|
|||
CVoiceHandle Play(int ChannelID, int SampleID, int Flags, float x, float y);
|
||||
CVoiceHandle PlayAt(int ChannelID, int SampleID, int Flags, float x, float y) override;
|
||||
CVoiceHandle Play(int ChannelID, int SampleID, int Flags) override;
|
||||
void Pause(int SampleID) override;
|
||||
void Stop(int SampleID) override;
|
||||
void StopAll() override;
|
||||
void StopVoice(CVoiceHandle Voice) override;
|
||||
|
|
|
@ -15,7 +15,8 @@ public:
|
|||
FLAG_LOOP = 1 << 0,
|
||||
FLAG_POS = 1 << 1,
|
||||
FLAG_NO_PANNING = 1 << 2,
|
||||
FLAG_ALL = FLAG_LOOP | FLAG_POS | FLAG_NO_PANNING,
|
||||
FLAG_PREVIEW = 1 << 3,
|
||||
FLAG_ALL = FLAG_LOOP | FLAG_POS | FLAG_NO_PANNING | FLAG_PREVIEW,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -68,7 +69,9 @@ public:
|
|||
virtual int LoadWVFromMem(const void *pData, unsigned DataSize, bool FromEditor = false) = 0;
|
||||
virtual void UnloadSample(int SampleID) = 0;
|
||||
|
||||
virtual float GetSampleDuration(int SampleID) = 0; // in s
|
||||
virtual float GetSampleTotalTime(int SampleID) = 0; // in s
|
||||
virtual float GetSampleCurrentTime(int SampleID) = 0; // in s
|
||||
virtual void SetSampleCurrentTime(int SampleID, float Time) = 0;
|
||||
|
||||
virtual void SetChannel(int ChannelID, float Volume, float Panning) = 0;
|
||||
virtual void SetListenerPos(float x, float y) = 0;
|
||||
|
@ -83,6 +86,7 @@ public:
|
|||
|
||||
virtual CVoiceHandle PlayAt(int ChannelID, int SampleID, int Flags, float x, float y) = 0;
|
||||
virtual CVoiceHandle Play(int ChannelID, int SampleID, int Flags) = 0;
|
||||
virtual void Pause(int SampleID) = 0;
|
||||
virtual void Stop(int SampleID) = 0;
|
||||
virtual void StopAll() = 0;
|
||||
virtual void StopVoice(CVoiceHandle Voice) = 0;
|
||||
|
|
|
@ -1257,35 +1257,106 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
|
||||
void CEditor::DoToolbarSounds(CUIRect ToolBar)
|
||||
{
|
||||
CUIRect ToolBarTop, ToolBarBottom, Button;
|
||||
CUIRect ToolBarTop, ToolBarBottom, Button, SeekBar;
|
||||
ToolBar.HSplitMid(&ToolBarTop, &ToolBarBottom, 5.0f);
|
||||
|
||||
if(m_SelectedSound >= 0 && (size_t)m_SelectedSound < m_Map.m_vpSounds.size())
|
||||
{
|
||||
const std::shared_ptr<CEditorSound> pSelectedSound = m_Map.m_vpSounds[m_SelectedSound];
|
||||
|
||||
// play/stop button
|
||||
// play/pause button
|
||||
{
|
||||
ToolBarBottom.VSplitLeft(ToolBarBottom.h, &Button, &ToolBarBottom);
|
||||
static int s_PlayStopButton;
|
||||
if(DoButton_FontIcon(&s_PlayStopButton, Sound()->IsPlaying(pSelectedSound->m_SoundID) ? FONT_ICON_STOP : FONT_ICON_PLAY, 0, &Button, 0, "Play/stop audio preview", IGraphics::CORNER_ALL) ||
|
||||
static int s_PlayPauseButton;
|
||||
if(DoButton_FontIcon(&s_PlayPauseButton, Sound()->IsPlaying(pSelectedSound->m_SoundID) ? FONT_ICON_PAUSE : FONT_ICON_PLAY, 0, &Button, 0, "Play/pause audio preview", IGraphics::CORNER_ALL) ||
|
||||
(m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_SPACE)))
|
||||
{
|
||||
if(Sound()->IsPlaying(pSelectedSound->m_SoundID))
|
||||
Sound()->Stop(pSelectedSound->m_SoundID);
|
||||
Sound()->Pause(pSelectedSound->m_SoundID);
|
||||
else
|
||||
Sound()->Play(CSounds::CHN_GUI, pSelectedSound->m_SoundID, 0);
|
||||
Sound()->Play(CSounds::CHN_GUI, pSelectedSound->m_SoundID, ISound::FLAG_PREVIEW);
|
||||
}
|
||||
}
|
||||
// stop button
|
||||
{
|
||||
ToolBarBottom.VSplitLeft(2.0f, nullptr, &ToolBarBottom);
|
||||
ToolBarBottom.VSplitLeft(ToolBarBottom.h, &Button, &ToolBarBottom);
|
||||
static int s_StopButton;
|
||||
if(DoButton_FontIcon(&s_StopButton, FONT_ICON_STOP, 0, &Button, 0, "Stop audio preview", IGraphics::CORNER_ALL))
|
||||
{
|
||||
Sound()->Stop(pSelectedSound->m_SoundID);
|
||||
}
|
||||
}
|
||||
// do seekbar
|
||||
{
|
||||
ToolBarBottom.VSplitLeft(5.0f, nullptr, &ToolBarBottom);
|
||||
ToolBarBottom.VSplitLeft(200.0f, &SeekBar, &ToolBarBottom);
|
||||
const float Rounding = 5.0f;
|
||||
|
||||
static int s_SeekBarID = 0;
|
||||
void *pId = &s_SeekBarID;
|
||||
|
||||
char aBuffer[64];
|
||||
float CurrentTime = Sound()->GetSampleCurrentTime(pSelectedSound->m_SoundID);
|
||||
float TotalTime = Sound()->GetSampleTotalTime(pSelectedSound->m_SoundID);
|
||||
|
||||
// draw seek bar
|
||||
SeekBar.Draw(ColorRGBA(0, 0, 0, 0.5f), IGraphics::CORNER_ALL, Rounding);
|
||||
|
||||
// draw filled bar
|
||||
float Amount = CurrentTime / TotalTime;
|
||||
CUIRect FilledBar = SeekBar;
|
||||
FilledBar.w = 2 * Rounding + (FilledBar.w - 2 * Rounding) * Amount;
|
||||
FilledBar.Draw(ColorRGBA(1, 1, 1, 0.5f), IGraphics::CORNER_ALL, Rounding);
|
||||
|
||||
// draw time
|
||||
char aCurrentTime[32];
|
||||
str_time_float(CurrentTime, TIME_HOURS, aCurrentTime, sizeof(aCurrentTime));
|
||||
char aTotalTime[32];
|
||||
str_time_float(TotalTime, TIME_HOURS, aTotalTime, sizeof(aTotalTime));
|
||||
str_format(aBuffer, sizeof(aBuffer), "%s / %s", aCurrentTime, aTotalTime);
|
||||
UI()->DoLabel(&SeekBar, aBuffer, SeekBar.h * 0.70f, TEXTALIGN_MC);
|
||||
|
||||
// do the logic
|
||||
const bool Inside = UI()->MouseInside(&SeekBar);
|
||||
|
||||
if(UI()->CheckActiveItem(pId))
|
||||
{
|
||||
if(!UI()->MouseButton(0))
|
||||
UI()->SetActiveItem(nullptr);
|
||||
else
|
||||
{
|
||||
static float s_PrevAmount = 0.0f;
|
||||
float AmountSeek = clamp((UI()->MouseX() - SeekBar.x - Rounding) / (float)(SeekBar.w - 2 * Rounding), 0.0f, 1.0f);
|
||||
|
||||
if(Input()->ShiftIsPressed())
|
||||
{
|
||||
AmountSeek = s_PrevAmount + (AmountSeek - s_PrevAmount) * 0.05f;
|
||||
if(AmountSeek >= 0.0f && AmountSeek <= 1.0f && absolute(s_PrevAmount - AmountSeek) >= 0.0001f)
|
||||
{
|
||||
Sound()->SetSampleCurrentTime(pSelectedSound->m_SoundID, AmountSeek);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AmountSeek >= 0.0f && AmountSeek <= 1.0f && absolute(s_PrevAmount - AmountSeek) >= 0.001f)
|
||||
{
|
||||
s_PrevAmount = AmountSeek;
|
||||
Sound()->SetSampleCurrentTime(pSelectedSound->m_SoundID, AmountSeek);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(UI()->HotItem() == pId)
|
||||
{
|
||||
if(UI()->MouseButton(0))
|
||||
{
|
||||
UI()->SetActiveItem(pId);
|
||||
}
|
||||
}
|
||||
|
||||
// duration
|
||||
{
|
||||
ToolBarBottom.VSplitLeft(5.0f, nullptr, &ToolBarBottom);
|
||||
char aDuration[32];
|
||||
char aDurationLabel[64];
|
||||
str_time_float(Sound()->GetSampleDuration(pSelectedSound->m_SoundID), TIME_HOURS, aDuration, sizeof(aDuration));
|
||||
str_format(aDurationLabel, sizeof(aDurationLabel), "Duration: %s", aDuration);
|
||||
UI()->DoLabel(&ToolBarBottom, aDurationLabel, 12.0f, TEXTALIGN_ML);
|
||||
if(Inside)
|
||||
UI()->SetHotItem(pId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4689,11 +4760,11 @@ void CEditor::RenderFileDialog()
|
|||
Sound()->Play(CSounds::CHN_GUI, m_FilePreviewSound, 0);
|
||||
}
|
||||
|
||||
char aDuration[32];
|
||||
char aDurationLabel[64];
|
||||
str_time_float(Sound()->GetSampleDuration(m_FilePreviewSound), TIME_HOURS, aDuration, sizeof(aDuration));
|
||||
str_format(aDurationLabel, sizeof(aDurationLabel), "Duration: %s", aDuration);
|
||||
UI()->DoLabel(&Preview, aDurationLabel, 12.0f, TEXTALIGN_ML);
|
||||
char aTotalTime[32];
|
||||
char aTotalTimeLabel[64];
|
||||
str_time_float(Sound()->GetSampleTotalTime(m_FilePreviewSound), TIME_HOURS, aTotalTime, sizeof(aTotalTime));
|
||||
str_format(aTotalTimeLabel, sizeof(aTotalTimeLabel), "Duration: %s", aTotalTime);
|
||||
UI()->DoLabel(&Preview, aTotalTimeLabel, 12.0f, TEXTALIGN_ML);
|
||||
}
|
||||
else if(m_FilePreviewState == PREVIEW_ERROR)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue