diff --git a/src/gui/gui.h b/src/gui/gui.h index 3041f310f..de5bd37e6 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2876,6 +2876,7 @@ class FurnaceGUI { bool NoteSelector(int* value, bool showOffRel, int octaveMin=-5, int octaveMax=9); // mixer stuff + bool chipMixer(int which, ImVec2 size=ImVec2(0.0f,0.0f)); ImVec2 calcPortSetSize(String label, int ins, int outs); bool portSet(String label, unsigned int portSetID, int ins, int outs, int activeIns, int activeOuts, int& clickedPort, std::map& portPos); @@ -2984,8 +2985,10 @@ class FurnaceGUI { void drawTutorial(); void drawXYOsc(); void drawUserPresets(); + float drawSystemChannelInfo(const DivSysDef* whichDef, int keyHitOffset=-1, float width=-1.0f); void drawSystemChannelInfoText(const DivSysDef* whichDef); + void drawVolMeterInternal(ImDrawList* dl, ImRect rect, float* data, int chans); void assignActionMap(std::map& actionMap, int first, int last); void drawKeybindSettingsTableRow(FurnaceGUIActions actionIdx); diff --git a/src/gui/mixer.cpp b/src/gui/mixer.cpp index b6c3af2a1..c8d7f214e 100644 --- a/src/gui/mixer.cpp +++ b/src/gui/mixer.cpp @@ -235,23 +235,7 @@ void FurnaceGUI::drawMixer() { if (ImGui::BeginChild("##mixerPerChipContainer",ImGui::GetContentRegionAvail())) { const float childWidth=60*dpiScale; for (int i=0; isong.systemLen; i++) { - ImGui::PushID(i); - if (ImGui::BeginChild(fmt::sprintf("##MixerChip%d", i).c_str(), ImVec2(childWidth,0))) { - float textHeight=ImGui::GetFontSize(); - ImGui::ScrollText(ImGui::GetID(i),fmt::sprintf("%d. %s",i+1,getSystemName(e->song.system[i])).c_str(),ImGui::GetCursorPos(),ImVec2(childWidth,textHeight)); - ImGui::Dummy(ImVec2(childWidth,textHeight)); - float volSliderHeight=ImGui::GetContentRegionAvail().y-ImGui::GetStyle().FramePadding.y*7-textHeight*2; - // ImGui::PushStyleColor(ImGuiCol_FrameBg,0); - // ImGui::PushStyleColor(ImGuiCol_FrameBgActive,0); - ImGui::VSliderFloat("##mixerVol", ImVec2(childWidth,volSliderHeight), &e->song.systemVol[i], 0.0f, 2.0f); - // ImGui::PopStyleColor(2); - ImGui::SetNextItemWidth(childWidth); - ImGui::SliderFloat("##mixerPan", &e->song.systemPan[i], -1.0f, 1.0f); - ImGui::SetNextItemWidth(childWidth); - ImGui::SliderFloat("##mixerPanFR", &e->song.systemPanFR[i], -1.0f, 1.0f); - } - ImGui::EndChild(); - ImGui::PopID(); + if (chipMixer(i, ImVec2(childWidth, ImGui::GetContentRegionAvail().y))) MARK_MODIFIED; ImGui::SameLine(); } } @@ -420,3 +404,32 @@ void FurnaceGUI::drawMixer() { if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_MIXER; ImGui::End(); } + +bool FurnaceGUI::chipMixer(int which, ImVec2 size) { + bool ret=false; + ImGui::PushID(which); + ImGui::BeginGroup(); + float textHeight=ImGui::GetFontSize(); + + float volSliderHeight=size.y-ImGui::GetStyle().FramePadding.y*8-textHeight*3; + // TODO: per-chip per-out peak + float vol[2]; + ImVec2 pos=ImGui::GetWindowPos()+ImGui::GetCursorPos(); + drawVolMeterInternal(ImGui::GetWindowDrawList(),ImRect(pos,pos+ImVec2(size.x,volSliderHeight)),vol,2); + + ImGui::PushStyleColor(ImGuiCol_FrameBg,0); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive,0); + if (ImGui::VSliderFloat("##ChipVol", ImVec2(size.x,volSliderHeight), &e->song.systemVol[which], 0.0f, 2.0f)) ret=true; + ImGui::PopStyleColor(2); + + ImGui::SetNextItemWidth(size.x); + if (ImGui::SliderFloat("##ChipPan", &e->song.systemPan[which], -1.0f, 1.0f)) ret=true; + ImGui::SetNextItemWidth(size.x); + if (ImGui::SliderFloat("##ChipPanFR", &e->song.systemPanFR[which], -1.0f, 1.0f)) ret=true; + + ImGui::ScrollText(ImGui::GetID(which),fmt::sprintf("%d. %s",which+1,getSystemName(e->song.system[which])).c_str(),ImGui::GetCursorPos(),ImVec2(size.x,textHeight)); + ImGui::Dummy(ImVec2(size.x,textHeight)); + ImGui::EndGroup(); + ImGui::PopID(); + return ret; +} diff --git a/src/gui/volMeter.cpp b/src/gui/volMeter.cpp index e2cd3de7f..66c870741 100644 --- a/src/gui/volMeter.cpp +++ b/src/gui/volMeter.cpp @@ -102,3 +102,48 @@ void FurnaceGUI::drawVolMeter() { if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_VOL_METER; ImGui::End(); } + +void FurnaceGUI::drawVolMeterInternal(ImDrawList* dl, ImRect rect, float* data, int chans) { + bool aspectRatio=(ImGui::GetWindowSize().x/ImGui::GetWindowSize().y)>1.0; + ImU32 lowColor=ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_LOW]); + ImGuiStyle& style=ImGui::GetStyle(); + ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding); + int isClipping=0; + for (int i=0; i0.0) { + isClipping=8; + logPeak=0.0; + } + logPeak+=1.0; + ImU32 highColor=ImGui::GetColorU32( + ImLerp(uiColors[GUI_COLOR_VOLMETER_LOW],uiColors[GUI_COLOR_VOLMETER_HIGH],logPeak) + ); + ImRect s; + if (aspectRatio) { + s=ImRect( + ImLerp(rect.Min,rect.Max,ImVec2(0,float(i)/chans)), + ImLerp(rect.Min,rect.Max,ImVec2(logPeak,float(i+1)/chans)) + ); + if (i!=(chans-1)) s.Max.y-=dpiScale; + if (isClipping) { + dl->AddRectFilled(s.Min,s.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_PEAK])); + } else { + dl->AddRectFilledMultiColor(s.Min,s.Max,lowColor,highColor,highColor,lowColor); + } + } else { + s=ImRect( + ImLerp(rect.Min,rect.Max,ImVec2(float(i)/chans,1.0-logPeak)), + ImLerp(rect.Min,rect.Max,ImVec2(float(i+1)/chans,1.0)) + ); + if (i!=(chans-1)) s.Max.x-=dpiScale; + if (isClipping) { + dl->AddRectFilled(s.Min,s.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_PEAK])); + } else { + dl->AddRectFilledMultiColor(s.Min,s.Max,highColor,highColor,lowColor,lowColor); + } + } + } +}