Merge branch 'chanColorsEtc' into inf2
This commit is contained in:
commit
fea3bab550
11 changed files with 207 additions and 92 deletions
|
|
@ -649,6 +649,7 @@ void DivEngine::copyChannel(int src, int dest) {
|
|||
curSubSong->chanShow[dest]=curSubSong->chanShow[src];
|
||||
curSubSong->chanShowChanOsc[dest]=curSubSong->chanShowChanOsc[src];
|
||||
curSubSong->chanCollapse[dest]=curSubSong->chanCollapse[src];
|
||||
curSubSong->chanColor[dest]=curSubSong->chanColor[src];
|
||||
}
|
||||
|
||||
void DivEngine::swapChannels(int src, int dest) {
|
||||
|
|
@ -677,17 +678,21 @@ void DivEngine::swapChannels(int src, int dest) {
|
|||
bool prevChanShow=curSubSong->chanShow[src];
|
||||
bool prevChanShowChanOsc=curSubSong->chanShowChanOsc[src];
|
||||
unsigned char prevChanCollapse=curSubSong->chanCollapse[src];
|
||||
unsigned int prevChanColor=curSubSong->chanColor[src];
|
||||
|
||||
curSubSong->chanName[src]=curSubSong->chanName[dest];
|
||||
curSubSong->chanShortName[src]=curSubSong->chanShortName[dest];
|
||||
curSubSong->chanShow[src]=curSubSong->chanShow[dest];
|
||||
curSubSong->chanShowChanOsc[src]=curSubSong->chanShowChanOsc[dest];
|
||||
curSubSong->chanCollapse[src]=curSubSong->chanCollapse[dest];
|
||||
curSubSong->chanColor[src]=curSubSong->chanColor[dest];
|
||||
|
||||
curSubSong->chanName[dest]=prevChanName;
|
||||
curSubSong->chanShortName[dest]=prevChanShortName;
|
||||
curSubSong->chanShow[dest]=prevChanShow;
|
||||
curSubSong->chanShowChanOsc[dest]=prevChanShowChanOsc;
|
||||
curSubSong->chanCollapse[dest]=prevChanCollapse;
|
||||
curSubSong->chanColor[dest]=prevChanColor;
|
||||
}
|
||||
|
||||
void DivEngine::stompChannel(int ch) {
|
||||
|
|
@ -702,6 +707,7 @@ void DivEngine::stompChannel(int ch) {
|
|||
curSubSong->chanShow[ch]=true;
|
||||
curSubSong->chanShowChanOsc[ch]=true;
|
||||
curSubSong->chanCollapse[ch]=false;
|
||||
curSubSong->chanColor[ch]=0;
|
||||
}
|
||||
|
||||
void DivEngine::changeSong(size_t songIndex) {
|
||||
|
|
@ -789,6 +795,8 @@ int DivEngine::duplicateSubSong(int index) {
|
|||
memcpy(theCopy->chanShowChanOsc,theOrig->chanShowChanOsc,DIV_MAX_CHANS*sizeof(bool));
|
||||
memcpy(theCopy->chanCollapse,theOrig->chanCollapse,DIV_MAX_CHANS);
|
||||
|
||||
memcpy(theCopy->chanColor,theOrig->chanColor,DIV_MAX_CHANS*sizeof(unsigned int));
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
theCopy->chanName[i]=theOrig->chanName[i];
|
||||
theCopy->chanShortName[i]=theOrig->chanShortName[i];
|
||||
|
|
@ -1220,6 +1228,7 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) {
|
|||
i->chanCollapse[destChan+j]=i->chanCollapse[srcChan+j];
|
||||
i->chanName[destChan+j]=i->chanName[srcChan+j];
|
||||
i->chanShortName[destChan+j]=i->chanShortName[srcChan+j];
|
||||
i->chanColor[destChan+j]=i->chanColor[srcChan+j];
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
if (i->pat[srcChan+j].data[k]!=NULL) {
|
||||
i->pat[srcChan+j].data[k]->copyOn(i->pat[destChan+j].getPattern(k,true));
|
||||
|
|
@ -1372,6 +1381,7 @@ void DivEngine::swapSystemUnsafe(int src, int dest, bool preserveOrder) {
|
|||
bool prevChanShow[DIV_MAX_CHANS];
|
||||
bool prevChanShowChanOsc[DIV_MAX_CHANS];
|
||||
unsigned char prevChanCollapse[DIV_MAX_CHANS];
|
||||
unsigned int prevChanColor[DIV_MAX_CHANS];
|
||||
|
||||
for (int j=0; j<tchans; j++) {
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
|
|
@ -1384,6 +1394,7 @@ void DivEngine::swapSystemUnsafe(int src, int dest, bool preserveOrder) {
|
|||
prevChanShow[j]=song.subsong[i]->chanShow[j];
|
||||
prevChanShowChanOsc[j]=song.subsong[i]->chanShowChanOsc[j];
|
||||
prevChanCollapse[j]=song.subsong[i]->chanCollapse[j];
|
||||
prevChanColor[j]=song.subsong[i]->chanColor[j];
|
||||
}
|
||||
|
||||
for (int j=0; j<tchans; j++) {
|
||||
|
|
@ -1398,6 +1409,7 @@ void DivEngine::swapSystemUnsafe(int src, int dest, bool preserveOrder) {
|
|||
song.subsong[i]->chanShow[j]=prevChanShow[swappedChannels[j]];
|
||||
song.subsong[i]->chanShowChanOsc[j]=prevChanShowChanOsc[swappedChannels[j]];
|
||||
song.subsong[i]->chanCollapse[j]=prevChanCollapse[swappedChannels[j]];
|
||||
song.subsong[i]->chanColor[j]=prevChanColor[swappedChannels[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -845,6 +845,7 @@ void DivSong::findSubSongs() {
|
|||
memcpy(theCopy->chanShow,i->chanShow,DIV_MAX_CHANS*sizeof(bool));
|
||||
memcpy(theCopy->chanShowChanOsc,i->chanShowChanOsc,DIV_MAX_CHANS*sizeof(bool));
|
||||
memcpy(theCopy->chanCollapse,i->chanCollapse,DIV_MAX_CHANS);
|
||||
memcpy(theCopy->chanColor,i->chanColor,DIV_MAX_CHANS*sizeof(unsigned int));
|
||||
|
||||
for (int k=0; k<DIV_MAX_CHANS; k++) {
|
||||
theCopy->chanName[k]=i->chanName[k];
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ struct DivSubSong {
|
|||
unsigned char chanCollapse[DIV_MAX_CHANS];
|
||||
String chanName[DIV_MAX_CHANS];
|
||||
String chanShortName[DIV_MAX_CHANS];
|
||||
unsigned int chanColor[DIV_MAX_CHANS];
|
||||
|
||||
// song timestamps
|
||||
DivSongTimestamps ts;
|
||||
|
|
@ -162,6 +163,7 @@ struct DivSubSong {
|
|||
chanShow[i]=true;
|
||||
chanShowChanOsc[i]=true;
|
||||
chanCollapse[i]=0;
|
||||
chanColor[i]=0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
float FurnaceGUI::computeGradPos(int type, int chan) {
|
||||
float FurnaceGUI::computeGradPos(int type, int chan, int totalChans) {
|
||||
switch (type) {
|
||||
case GUI_OSCREF_NONE:
|
||||
return 0.0f;
|
||||
|
|
@ -74,10 +74,10 @@ float FurnaceGUI::computeGradPos(int type, int chan) {
|
|||
return chanOscVol[chan];
|
||||
break;
|
||||
case GUI_OSCREF_CHANNEL:
|
||||
return (float)chan/(float)(e->getTotalChannelCount()-1);
|
||||
return (float)chan/(float)(totalChans-1);
|
||||
break;
|
||||
case GUI_OSCREF_BRIGHT:
|
||||
return chanOscBright[chan];
|
||||
return chanOscBright[chan]; // this array is set to only 0 (???)
|
||||
break;
|
||||
case GUI_OSCREF_NOTE_TRIGGER:
|
||||
return keyHit1[chan];
|
||||
|
|
@ -87,10 +87,6 @@ float FurnaceGUI::computeGradPos(int type, int chan) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::calcChanOsc() {
|
||||
std::vector<DivDispatchOscBuffer*> oscBufs;
|
||||
std::vector<ChanOscStatus*> oscFFTs;
|
||||
std::vector<int> oscChans;
|
||||
|
||||
int chans=e->getTotalChannelCount();
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
|
|
@ -143,10 +139,12 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::Text(_("Columns"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::BeginDisabled(chanOscAutoCols);
|
||||
if (ImGui::InputInt("##COSColumns",&chanOscCols,1,3)) {
|
||||
if (chanOscCols<1) chanOscCols=1;
|
||||
if (chanOscCols>64) chanOscCols=64;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(_("Size (ms)"));
|
||||
|
|
@ -160,18 +158,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text(_("Automatic columns"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
const char* previewColType=autoColsTypes[chanOscAutoColsType&3];
|
||||
if (ImGui::BeginCombo("##AutoCols",previewColType)) {
|
||||
for (int j=0; j<4; j++) {
|
||||
const bool isSelected=(chanOscAutoColsType==j);
|
||||
if (ImGui::Selectable(autoColsTypes[j],isSelected)) chanOscAutoColsType=j;
|
||||
if (isSelected) ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::Checkbox(_("Automatic columns"),&chanOscAutoCols);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox(_("Center waveform"),&chanOscWaveCorr)) {
|
||||
|
|
@ -350,9 +337,30 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::ColorEdit4(_("Background"),(float*)&chanOscGrad.bgColor)) {
|
||||
ImGui::Text(_("Background:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("Solid color"),chanOscColorMode==0)) {
|
||||
chanOscColorMode=0;
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
if (chanOscColorMode==0) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::ColorEdit4(_("Color"),(float*)&chanOscGrad.bgColor)) {
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
if (ImGui::RadioButton(_("Channel color"),chanOscColorMode==1)) {
|
||||
chanOscColorMode=1;
|
||||
chanOscGrad.bgColor.x=0.0f;
|
||||
chanOscGrad.bgColor.y=0.0f;
|
||||
chanOscGrad.bgColor.z=0.0f;
|
||||
chanOscGrad.bgColor.w=0.0f;
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
// in preparation of image texture
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Combo(_("X Axis##AxisX"),&chanOscColorX,LocalizedComboGetter,chanOscRefs,GUI_OSCREF_MAX);
|
||||
ImGui::Combo(_("Y Axis##AxisY"),&chanOscColorY,LocalizedComboGetter,chanOscRefs,GUI_OSCREF_MAX);
|
||||
|
||||
|
|
@ -360,7 +368,13 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
} else {
|
||||
ImGui::SetNextItemWidth(400.0f*dpiScale);
|
||||
ImGui::ColorPicker4(_("Color"),(float*)&chanOscColor);
|
||||
bool chanOscColorModeB=chanOscColorMode;
|
||||
ImGui::BeginDisabled(chanOscColorModeB);
|
||||
ImGui::ColorEdit4(_("Color"),(float*)&chanOscColor);
|
||||
ImGui::EndDisabled();
|
||||
if (ImGui::Checkbox(_("Set to channel color"), &chanOscColorModeB)) {
|
||||
chanOscColorMode=chanOscColorModeB;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
|
@ -401,9 +415,12 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(0.0f,0.0f));
|
||||
float availY=ImGui::GetContentRegionAvail().y;
|
||||
if (ImGui::BeginTable("ChanOsc",chanOscCols,ImGuiTableFlags_Borders|ImGuiTableFlags_NoClip)) {
|
||||
std::vector<DivDispatchOscBuffer*> oscBufs;
|
||||
std::vector<ChanOscStatus*> oscFFTs;
|
||||
std::vector<int> oscChans;
|
||||
struct OscData {
|
||||
DivDispatchOscBuffer* buf;
|
||||
ChanOscStatus* fft;
|
||||
int chan;
|
||||
};
|
||||
std::vector<OscData> oscData;
|
||||
int chans=e->getTotalChannelCount();
|
||||
ImGuiWindow* window=ImGui::GetCurrentWindow();
|
||||
|
||||
|
|
@ -420,18 +437,16 @@ void FurnaceGUI::drawChanOsc() {
|
|||
for (int i=0; i<chans; i++) {
|
||||
DivDispatchOscBuffer* buf=e->getOscBuffer(i);
|
||||
if (buf!=NULL && e->curSubSong->chanShowChanOsc[i]) {
|
||||
oscBufs.push_back(buf);
|
||||
oscFFTs.push_back(&chanOscChan[i]);
|
||||
oscChans.push_back(i);
|
||||
oscData.push_back({buf,&chanOscChan[i],i});
|
||||
}
|
||||
}
|
||||
|
||||
// process
|
||||
for (size_t i=0; i<oscBufs.size(); i++) {
|
||||
ChanOscStatus* fft_=oscFFTs[i];
|
||||
for (size_t i=0; i<oscData.size(); i++) {
|
||||
ChanOscStatus* fft_=oscData[i].fft;
|
||||
|
||||
fft_->relatedBuf=oscBufs[i];
|
||||
fft_->relatedCh=oscChans[i];
|
||||
fft_->relatedBuf=oscData[i].buf;
|
||||
fft_->relatedCh=oscData[i].chan;
|
||||
|
||||
if (fft_->relatedBuf!=NULL) {
|
||||
// prepare
|
||||
|
|
@ -590,35 +605,21 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
}
|
||||
chanOscWorkPool->wait();
|
||||
|
||||
// 0: none
|
||||
// 1: sqrt(chans)
|
||||
// 2: sqrt(chans+1)
|
||||
// 3: sqrt(chans)+1
|
||||
switch (chanOscAutoColsType) {
|
||||
case 1:
|
||||
chanOscCols=sqrt(oscChans.size());
|
||||
break;
|
||||
case 2:
|
||||
chanOscCols=sqrt(oscChans.size()+1);
|
||||
break;
|
||||
case 3:
|
||||
chanOscCols=sqrt(oscChans.size())+1;
|
||||
break;
|
||||
}
|
||||
if (chanOscCols<1) chanOscCols=1;
|
||||
if (chanOscCols>64) chanOscCols=64;
|
||||
|
||||
int rows=(oscBufs.size()+(chanOscCols-1))/chanOscCols;
|
||||
if (chanOscAutoCols) {
|
||||
chanOscCols=sqrt(oscData.size());
|
||||
if (chanOscCols>64) chanOscCols=64;
|
||||
}
|
||||
int rows=(oscData.size()+(chanOscCols-1))/chanOscCols;
|
||||
|
||||
// render
|
||||
for (size_t i=0; i<oscBufs.size(); i++) {
|
||||
for (size_t i=0; i<oscData.size(); i++) {
|
||||
if (i%chanOscCols==0) ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
DivDispatchOscBuffer* buf=oscBufs[i];
|
||||
ChanOscStatus* fft=oscFFTs[i];
|
||||
int ch=oscChans[i];
|
||||
DivDispatchOscBuffer* buf=oscData[i].buf;
|
||||
ChanOscStatus* fft=oscData[i].fft;
|
||||
int ch=oscData[i].chan;
|
||||
if (buf==NULL) {
|
||||
ImGui::Text(_("Error!"));
|
||||
} else {
|
||||
|
|
@ -793,15 +794,38 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
}
|
||||
}
|
||||
ImU32 color=ImGui::GetColorU32(chanOscColor);
|
||||
ImU32 color;
|
||||
switch (chanOscColorMode) {
|
||||
case 0:
|
||||
color=ImGui::GetColorU32(chanOscColor);
|
||||
break;
|
||||
case 1:
|
||||
color=ImGui::GetColorU32(channelColor(oscData[i].chan));
|
||||
break;
|
||||
}
|
||||
if (chanOscUseGrad) {
|
||||
float xVal=computeGradPos(chanOscColorX,ch);
|
||||
float yVal=computeGradPos(chanOscColorY,ch);
|
||||
float xVal=computeGradPos(chanOscColorX,ch,oscData.size());
|
||||
float yVal=computeGradPos(chanOscColorY,ch,oscData.size());
|
||||
|
||||
xVal=CLAMP(xVal,0.0f,1.0f);
|
||||
yVal=CLAMP(yVal,0.0f,1.0f);
|
||||
|
||||
color=chanOscGrad.get(xVal,1.0f-yVal);
|
||||
switch (chanOscColorMode) {
|
||||
case 0:
|
||||
color=chanOscGrad.get(xVal,1.0f-yVal);
|
||||
break;
|
||||
case 1:
|
||||
color=ImAlphaBlendColors(color,chanOscGrad.get(xVal,1.0f-yVal));
|
||||
break;
|
||||
}
|
||||
// char buf[256];
|
||||
// snprintf(buf, 256, "%f:%f",xVal,yVal);
|
||||
// dl->AddText(inRect.Min,-1,buf);
|
||||
// dl->AddCircleFilled(
|
||||
// ImVec2(
|
||||
// ImLerp(inRect.Min.x,inRect.Max.x,xVal),
|
||||
// ImLerp(inRect.Min.y,inRect.Max.y,1.0f-yVal)
|
||||
// ), 2, 0xffff0000);
|
||||
}
|
||||
|
||||
if (rend->supportsDrawOsc() && settings.shaderOsc) {
|
||||
|
|
@ -901,15 +925,21 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
case 'n': {
|
||||
DivChannelState* chanState=e->getChanState(ch);
|
||||
if (chanState==NULL || !(chanState->keyOn)) break;
|
||||
// no more conversion necessary after the note/octave unification :>
|
||||
text+=fmt::sprintf("%s",noteName(chanState->note+60));
|
||||
// ik its pretty hacky but it works
|
||||
// the templated stuff is after the member we need to access so it shouldnt matter
|
||||
// and no segfaults should occur
|
||||
SharedChannel<char>* chan=(SharedChannel<char>*)e->getDispatchChanState(ch);
|
||||
if (chanState==NULL || chan==NULL || !chan->active) {
|
||||
text+="---";
|
||||
} else {
|
||||
// no more conversion necessary after the note/octave unification :>
|
||||
text+=fmt::sprintf("%s",noteName(chanState->note+60));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
case 'l':
|
||||
text+='\n';
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
text+='%';
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,13 @@ void FurnaceGUI::drawChannels() {
|
|||
//ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Channels",&channelsOpen,globalWinFlags,_("Channels"))) {
|
||||
if (ImGui::BeginTable("ChannelList",5)) {
|
||||
if (ImGui::BeginTable("ChannelList",6)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.0);
|
||||
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthFixed,48.0f*dpiScale);
|
||||
ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthFixed,0.0f);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(_("Pat"));
|
||||
|
|
@ -52,6 +53,9 @@ void FurnaceGUI::drawChannels() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(_("Color"));
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
ImGui::PushID(i);
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -106,6 +110,25 @@ void FurnaceGUI::drawChannels() {
|
|||
if (ImGui::InputTextWithHint("##ChanShortName",e->getChannelShortName(i),&e->curSubSong->chanShortName[i])) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImVec4 curColor=e->curSubSong->chanColor[i]?ImGui::ColorConvertU32ToFloat4(e->curSubSong->chanColor[i]):uiColors[GUI_COLOR_CHANNEL_FM+e->getChannelType(i)];
|
||||
ImGui::ColorButton("##ChanColor",curColor);
|
||||
if (ImGui::BeginPopupContextItem("##ChanColorEditPopup", ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::ColorPicker4("##ChanColorEdit", (float*)&curColor);
|
||||
e->curSubSong->chanColor[i]=ImGui::ColorConvertFloat4ToU32(curColor);
|
||||
MARK_MODIFIED;
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(e->curSubSong->chanColor[i]==0);
|
||||
if (ImGui::Button(ICON_FA_REFRESH "##ChanColorReset")) {
|
||||
e->curSubSong->chanColor[i]=0;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("Reset color"));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
|
|
|
|||
|
|
@ -109,21 +109,28 @@ void Gradient2D::render() {
|
|||
if (dist>1) dist=1;
|
||||
|
||||
ImU32 shadeColor=ImGui::ColorConvertFloat4ToU32(
|
||||
// ps: multiplying dist to the color channels fixes old
|
||||
// mixing, but breaks if the bg is 0. and vice versa (not
|
||||
// multiplying fixes 0 bg mixing)
|
||||
ImVec4(
|
||||
i.color.x*i.color.w*dist,
|
||||
i.color.y*i.color.w*dist,
|
||||
i.color.z*i.color.w*dist,
|
||||
1.0f
|
||||
1.0f*dist // this idk
|
||||
)
|
||||
);
|
||||
|
||||
ImU32 origColor=g[j*width+k];
|
||||
// note: this really breaks the color mixing if theres a background
|
||||
// and the bitshifts are necessary to avoid overflow (but prob only for alpha)
|
||||
// this needs to be redone, its a temporary proof-of-concept solution anyway
|
||||
g[j*width+k]=(
|
||||
(MIN( 0xff, (origColor&0xff) + (shadeColor&0xff) )) | // R
|
||||
(MIN( 0xff00, (origColor&0xff00) + (shadeColor&0xff00) )) | // G
|
||||
(MIN(0xff0000,(origColor&0xff0000)+(shadeColor&0xff0000))) | // B
|
||||
(origColor&0xff000000) // A
|
||||
(MIN(0xff,(origColor &0xff)+(shadeColor &0xff)) ) | // R
|
||||
(MIN(0xff,(origColor>> 8&0xff)+(shadeColor>> 8&0xff))<< 8) | // G
|
||||
(MIN(0xff,(origColor>>16&0xff)+(shadeColor>>16&0xff))<<16) | // B
|
||||
(MIN(0xff,(origColor>>24&0xff)+(shadeColor>>24&0xff))<<24) // A
|
||||
);
|
||||
// ps 2: replacing this with ImAlphaBlendColors doesnt work
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -942,7 +942,7 @@ ImVec4 FurnaceGUI::channelColor(int ch) {
|
|||
return uiColors[GUI_COLOR_CHANNEL_BG];
|
||||
break;
|
||||
case 1:
|
||||
return uiColors[GUI_COLOR_CHANNEL_FM+e->getChannelType(ch)];
|
||||
return e->curSubSong->chanColor[ch]?ImGui::ColorConvertU32ToFloat4(e->curSubSong->chanColor[ch]):uiColors[GUI_COLOR_CHANNEL_FM+e->getChannelType(ch)];
|
||||
break;
|
||||
case 2:
|
||||
return uiColors[GUI_COLOR_INSTR_STD+e->getPreferInsType(ch)];
|
||||
|
|
@ -8377,7 +8377,7 @@ void FurnaceGUI::syncState() {
|
|||
pianoLabelsMode=e->getConfInt("pianoLabelsMode",pianoLabelsMode);
|
||||
|
||||
chanOscCols=e->getConfInt("chanOscCols",3);
|
||||
chanOscAutoColsType=e->getConfInt("chanOscAutoColsType",0);
|
||||
chanOscAutoCols=e->getConfBool("chanOscAutoColsType",0);
|
||||
chanOscColorX=e->getConfInt("chanOscColorX",GUI_OSCREF_CENTER);
|
||||
chanOscColorY=e->getConfInt("chanOscColorY",GUI_OSCREF_CENTER);
|
||||
chanOscCenterStrat=e->getConfInt("chanOscCenterStrat",1);
|
||||
|
|
@ -8400,6 +8400,7 @@ void FurnaceGUI::syncState() {
|
|||
chanOscTextColor.z=e->getConfFloat("chanOscTextColorB",1.0f);
|
||||
chanOscTextColor.w=e->getConfFloat("chanOscTextColorA",0.75f);
|
||||
chanOscUseGrad=e->getConfBool("chanOscUseGrad",false);
|
||||
chanOscColorMode=e->getConfInt("chanOscColorMode",0);
|
||||
chanOscGrad.fromString(e->getConfString("chanOscGrad",""));
|
||||
chanOscGrad.render();
|
||||
|
||||
|
|
@ -8550,7 +8551,7 @@ void FurnaceGUI::commitState(DivConfig& conf) {
|
|||
|
||||
// commit per-chan osc state
|
||||
conf.set("chanOscCols",chanOscCols);
|
||||
conf.set("chanOscAutoColsType",chanOscAutoColsType);
|
||||
conf.set("chanOscAutoColsType",chanOscAutoCols);
|
||||
conf.set("chanOscColorX",chanOscColorX);
|
||||
conf.set("chanOscColorY",chanOscColorY);
|
||||
conf.set("chanOscCenterStrat",chanOscCenterStrat);
|
||||
|
|
@ -8574,6 +8575,7 @@ void FurnaceGUI::commitState(DivConfig& conf) {
|
|||
conf.set("chanOscTextColorA",chanOscTextColor.w);
|
||||
conf.set("chanOscUseGrad",chanOscUseGrad);
|
||||
conf.set("chanOscGrad",chanOscGrad.toString());
|
||||
conf.set("chanOscColorMode",chanOscColorMode);
|
||||
|
||||
// commit x-y osc state
|
||||
conf.set("xyOscXChannel",xyOscXChannel);
|
||||
|
|
@ -9183,10 +9185,10 @@ FurnaceGUI::FurnaceGUI():
|
|||
oscInput1(0.0f),
|
||||
oscZoomSlider(false),
|
||||
chanOscCols(3),
|
||||
chanOscAutoColsType(0),
|
||||
chanOscColorX(GUI_OSCREF_CENTER),
|
||||
chanOscColorY(GUI_OSCREF_CENTER),
|
||||
chanOscCenterStrat(1),
|
||||
chanOscColorMode(0),
|
||||
chanOscWindowSize(20.0f),
|
||||
chanOscTextX(0.0f),
|
||||
chanOscTextY(0.0f),
|
||||
|
|
@ -9198,6 +9200,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
chanOscUseGrad(false),
|
||||
chanOscNormalize(false),
|
||||
chanOscRandomPhase(false),
|
||||
chanOscAutoCols(false),
|
||||
chanOscTextFormat("%c"),
|
||||
chanOscColor(1.0f,1.0f,1.0f,1.0f),
|
||||
chanOscTextColor(1.0f,1.0f,1.0f,0.75f),
|
||||
|
|
@ -9380,7 +9383,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
|
||||
memset(lastAudioLoads,0,sizeof(float)*120);
|
||||
|
||||
memset(pianoKeyHit,0,sizeof(float)*180);
|
||||
memset(pianoKeyHit,0,sizeof(pianoKeyState)*180); // posiblly repace with a for loop
|
||||
memset(pianoKeyPressed,0,sizeof(bool)*180);
|
||||
|
||||
memset(queryReplaceEffectMode,0,sizeof(int)*8);
|
||||
|
|
|
|||
|
|
@ -2090,6 +2090,7 @@ class FurnaceGUI {
|
|||
int sampleImportInstDetune;
|
||||
int mixerStyle;
|
||||
int mixerLayout;
|
||||
float channelFeedbackGamma;
|
||||
String mainFontPath;
|
||||
String headFontPath;
|
||||
String patFontPath;
|
||||
|
|
@ -2344,6 +2345,7 @@ class FurnaceGUI {
|
|||
sampleImportInstDetune(0),
|
||||
mixerStyle(1),
|
||||
mixerLayout(0),
|
||||
channelFeedbackGamma(1.0f),
|
||||
mainFontPath(""),
|
||||
headFontPath(""),
|
||||
patFontPath(""),
|
||||
|
|
@ -2696,9 +2698,10 @@ class FurnaceGUI {
|
|||
bool oscZoomSlider;
|
||||
|
||||
// per-channel oscilloscope
|
||||
int chanOscCols, chanOscAutoColsType, chanOscColorX, chanOscColorY, chanOscCenterStrat;
|
||||
int chanOscCols, chanOscColorX, chanOscColorY, chanOscCenterStrat, chanOscColorMode;
|
||||
float chanOscWindowSize, chanOscTextX, chanOscTextY, chanOscAmplify, chanOscLineSize;
|
||||
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad, chanOscNormalize, chanOscRandomPhase;
|
||||
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad;
|
||||
bool chanOscNormalize, chanOscRandomPhase, chanOscAutoCols;
|
||||
String chanOscTextFormat;
|
||||
ImVec4 chanOscColor, chanOscTextColor;
|
||||
Gradient2D chanOscGrad;
|
||||
|
|
@ -2838,7 +2841,11 @@ class FurnaceGUI {
|
|||
|
||||
int pianoOctaves, pianoOctavesEdit;
|
||||
bool pianoOptions, pianoSharePosition, pianoOptionsSet;
|
||||
float pianoKeyHit[180];
|
||||
struct pianoKeyState {
|
||||
float value;
|
||||
int chan;
|
||||
};
|
||||
pianoKeyState pianoKeyHit[180];
|
||||
bool pianoKeyPressed[180];
|
||||
bool pianoReadonly;
|
||||
int pianoOffset, pianoOffsetEdit;
|
||||
|
|
@ -3102,7 +3109,7 @@ class FurnaceGUI {
|
|||
bool importConfig(String path);
|
||||
bool exportConfig(String path);
|
||||
|
||||
float computeGradPos(int type, int chan);
|
||||
float computeGradPos(int type, int chan, int totalChans);
|
||||
|
||||
void resetColors();
|
||||
void resetKeybinds();
|
||||
|
|
|
|||
|
|
@ -666,7 +666,8 @@ void FurnaceGUI::drawPattern() {
|
|||
if (!muted) {
|
||||
int note=e->getChanState(i)->note+60;
|
||||
if (note>=0 && note<180) {
|
||||
pianoKeyHit[note]=1.0;
|
||||
pianoKeyHit[note].value=1.0;
|
||||
pianoKeyHit[note].chan=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -674,12 +675,13 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
if (settings.channelFeedbackStyle==2 && e->isRunning()) {
|
||||
float amount=((float)(e->getChanState(i)->volume>>8)/(float)e->getMaxVolumeChan(i));
|
||||
if (!e->getChanState(i)->keyOn) amount=0.0f;
|
||||
if (e->getChanState(i)->keyOff) amount=0.0f;
|
||||
keyHit[i]=amount*0.2f;
|
||||
if (!muted) {
|
||||
if (!muted && e->getChanState(i)->keyOn) {
|
||||
int note=e->getChanState(i)->note+60;
|
||||
if (note>=0 && note<180) {
|
||||
pianoKeyHit[note]=amount;
|
||||
pianoKeyHit[note].value=amount;
|
||||
pianoKeyHit[note].chan=i;
|
||||
}
|
||||
}
|
||||
} else if (settings.channelFeedbackStyle==3 && e->isRunning()) {
|
||||
|
|
@ -688,7 +690,19 @@ void FurnaceGUI::drawPattern() {
|
|||
if (!muted) {
|
||||
int note=e->getChanState(i)->note+60;
|
||||
if (note>=0 && note<180) {
|
||||
pianoKeyHit[note]=active?1.0f:0.0f;
|
||||
pianoKeyHit[note].value=active?1.0f:0.0f;
|
||||
pianoKeyHit[note].chan=i;
|
||||
}
|
||||
}
|
||||
} else if (settings.channelFeedbackStyle==4 && e->isRunning()) {
|
||||
float amount=powf(chanOscVol[i],settings.channelFeedbackGamma);
|
||||
if (e->getChanState(i)->keyOff) amount=0.0f;
|
||||
keyHit[i]=amount*0.2f;
|
||||
if (!muted && e->getChanState(i)->keyOn) {
|
||||
int note=e->getChanState(i)->note+60;
|
||||
if (note>=0 && note<180) {
|
||||
pianoKeyHit[note].value=amount;
|
||||
pianoKeyHit[note].chan=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,12 +297,12 @@ void FurnaceGUI::drawPiano() {
|
|||
int note=i+12*off;
|
||||
if (note<0) continue;
|
||||
if (note>=180) continue;
|
||||
float pkh=pianoKeyHit[note];
|
||||
float pkh=pianoKeyHit[note].value;
|
||||
ImVec4 color=isTopKey[i%12]?uiColors[GUI_COLOR_PIANO_KEY_TOP]:uiColors[GUI_COLOR_PIANO_KEY_BOTTOM];
|
||||
if (pianoKeyPressed[note]) {
|
||||
color=isTopKey[i%12]?uiColors[GUI_COLOR_PIANO_KEY_TOP_ACTIVE]:uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_ACTIVE];
|
||||
} else {
|
||||
ImVec4 colorHit=isTopKey[i%12]?uiColors[GUI_COLOR_PIANO_KEY_TOP_HIT]:uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_HIT];
|
||||
ImVec4 colorHit=1?channelColor(pianoKeyHit[note].chan):(isTopKey[i%12]?uiColors[GUI_COLOR_PIANO_KEY_TOP_HIT]:uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_HIT]);
|
||||
color.x+=(colorHit.x-color.x)*pkh;
|
||||
color.y+=(colorHit.y-color.y)*pkh;
|
||||
color.z+=(colorHit.z-color.z)*pkh;
|
||||
|
|
@ -355,12 +355,12 @@ void FurnaceGUI::drawPiano() {
|
|||
if (note<0) continue;
|
||||
if (note>=180) continue;
|
||||
|
||||
float pkh=pianoKeyHit[note];
|
||||
float pkh=pianoKeyHit[note].value;
|
||||
ImVec4 color=uiColors[GUI_COLOR_PIANO_KEY_BOTTOM];
|
||||
if (pianoKeyPressed[note]) {
|
||||
color=uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_ACTIVE];
|
||||
} else {
|
||||
ImVec4 colorHit=uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_HIT];
|
||||
ImVec4 colorHit=1?channelColor(pianoKeyHit[note].chan):uiColors[GUI_COLOR_PIANO_KEY_BOTTOM_HIT];
|
||||
color.x+=(colorHit.x-color.x)*pkh;
|
||||
color.y+=(colorHit.y-color.y)*pkh;
|
||||
color.z+=(colorHit.z-color.z)*pkh;
|
||||
|
|
@ -383,12 +383,12 @@ void FurnaceGUI::drawPiano() {
|
|||
int note=topKeyNotes[j]+12*(i+off);
|
||||
if (note<0) continue;
|
||||
if (note>=180) continue;
|
||||
float pkh=pianoKeyHit[note];
|
||||
float pkh=pianoKeyHit[note].value;
|
||||
ImVec4 color=uiColors[GUI_COLOR_PIANO_KEY_TOP];
|
||||
if (pianoKeyPressed[note]) {
|
||||
color=uiColors[GUI_COLOR_PIANO_KEY_TOP_ACTIVE];
|
||||
} else {
|
||||
ImVec4 colorHit=uiColors[GUI_COLOR_PIANO_KEY_TOP_HIT];
|
||||
ImVec4 colorHit=1?channelColor(pianoKeyHit[note].chan):uiColors[GUI_COLOR_PIANO_KEY_TOP_HIT];
|
||||
color.x+=(colorHit.x-color.x)*pkh;
|
||||
color.y+=(colorHit.y-color.y)*pkh;
|
||||
color.z+=(colorHit.z-color.z)*pkh;
|
||||
|
|
@ -407,8 +407,8 @@ void FurnaceGUI::drawPiano() {
|
|||
|
||||
const float reduction=ImGui::GetIO().DeltaTime*60.0f*0.12;
|
||||
for (int i=0; i<180; i++) {
|
||||
pianoKeyHit[i]-=reduction;
|
||||
if (pianoKeyHit[i]<0) pianoKeyHit[i]=0;
|
||||
pianoKeyHit[i].value-=reduction;
|
||||
if (pianoKeyHit[i].value<0) pianoKeyHit[i].value=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3505,6 +3505,19 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.channelFeedbackStyle=3;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("Volume (Real)##CHF4"),settings.channelFeedbackStyle==4)) {
|
||||
settings.channelFeedbackStyle=4;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (settings.channelFeedbackStyle==4) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::SliderFloat(_("Gamma##CHF"),&settings.channelFeedbackGamma,0.0f,2.0f)) {
|
||||
if (settings.channelFeedbackGamma<0.0f) settings.channelFeedbackGamma=0.0f;
|
||||
if (settings.channelFeedbackGamma>2.0f) settings.channelFeedbackGamma=2.0f;
|
||||
settingsChanged=true;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text(_("Channel font:"));
|
||||
|
|
@ -5123,6 +5136,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.channelStyle=conf.getInt("channelStyle",1);
|
||||
settings.channelVolStyle=conf.getInt("channelVolStyle",0);
|
||||
settings.channelFeedbackStyle=conf.getInt("channelFeedbackStyle",1);
|
||||
settings.channelFeedbackGamma=conf.getFloat("channelFeedbackGamma",1.0f);
|
||||
settings.channelFont=conf.getInt("channelFont",1);
|
||||
settings.channelTextCenter=conf.getInt("channelTextCenter",1);
|
||||
|
||||
|
|
@ -5399,7 +5413,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.channelTextColors,0,2);
|
||||
clampSetting(settings.channelStyle,0,5);
|
||||
clampSetting(settings.channelVolStyle,0,4);
|
||||
clampSetting(settings.channelFeedbackStyle,0,3);
|
||||
clampSetting(settings.channelFeedbackStyle,0,4);
|
||||
clampSetting(settings.channelFeedbackGamma,0.0f,2.0f);
|
||||
clampSetting(settings.channelFont,0,1);
|
||||
clampSetting(settings.channelTextCenter,0,1);
|
||||
clampSetting(settings.maxRecentFile,0,30);
|
||||
|
|
@ -5711,6 +5726,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("channelStyle",settings.channelStyle);
|
||||
conf.set("channelVolStyle",settings.channelVolStyle);
|
||||
conf.set("channelFeedbackStyle",settings.channelFeedbackStyle);
|
||||
conf.set("channelFeedbackGamma",settings.channelFeedbackGamma);
|
||||
conf.set("channelFont",settings.channelFont);
|
||||
conf.set("channelTextCenter",settings.channelTextCenter);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue