Merge branch 'tildearrow:master' into sysmgrtooltip_syschaninfo
This commit is contained in:
commit
fb29626f5d
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
some of the effect numbers are taken from ProTracker / FastTracker 2.
|
||||
|
||||
however, effects are continuous, which means you only need to type it once and then stop it with an effect value of `00` or no effect value at all.
|
||||
however, effects are continuous (unless specified), which means you only need to type it once and then stop it with an effect value of `00` or no effect value at all.
|
||||
|
||||
## volume
|
||||
|
||||
|
|
|
|||
BIN
instruments/C64/string_c64.fui
Normal file
BIN
instruments/C64/string_c64.fui
Normal file
Binary file not shown.
BIN
instruments/ESFM/Hi-Hat_ESFM.fui
Normal file
BIN
instruments/ESFM/Hi-Hat_ESFM.fui
Normal file
Binary file not shown.
BIN
instruments/OPZ/Fake SNES Bass_OPZ.fui
Normal file
BIN
instruments/OPZ/Fake SNES Bass_OPZ.fui
Normal file
Binary file not shown.
|
|
@ -1468,7 +1468,7 @@ void DivSample::render(unsigned int formatMask) {
|
|||
delta[0]=0;
|
||||
delta[1]=0;
|
||||
|
||||
void* codec=adpcm_create_context(1,4,NOISE_SHAPING_OFF,delta);
|
||||
void* codec=adpcm_create_context(1,1,NOISE_SHAPING_OFF,delta);
|
||||
if (codec==NULL) {
|
||||
logE("oh no IMA encoder could not be created!");
|
||||
} else {
|
||||
|
|
|
|||
127
src/gui/gui.cpp
127
src/gui/gui.cpp
|
|
@ -635,6 +635,73 @@ void FurnaceGUI::updateWindowTitle() {
|
|||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::autoDetectSystemIter(std::vector<FurnaceGUISysDef>& category, bool& isMatch, std::map<DivSystem,int>& defCountMap, std::map<DivSystem,DivConfig>& defConfMap, std::map<DivSystem,int>& sysCountMap, std::map<DivSystem,DivConfig>& sysConfMap) {
|
||||
for (FurnaceGUISysDef& j: category) {
|
||||
if (!j.orig.empty()) {
|
||||
defCountMap.clear();
|
||||
defConfMap.clear();
|
||||
for (FurnaceGUISysDefChip& k: j.orig) {
|
||||
auto it=defCountMap.find(k.sys);
|
||||
if (it==defCountMap.cend()) {
|
||||
defCountMap[k.sys]=1;
|
||||
} else {
|
||||
it->second++;
|
||||
}
|
||||
DivConfig dc;
|
||||
dc.loadFromMemory(k.flags);
|
||||
defConfMap[k.sys]=dc;
|
||||
}
|
||||
if (defCountMap.size()==sysCountMap.size()) {
|
||||
isMatch=true;
|
||||
/*logV("trying on defCountMap: %s",j.name);
|
||||
for (std::pair<DivSystem,int> k: defCountMap) {
|
||||
logV("- %s: %d",e->getSystemName(k.first),k.second);
|
||||
}*/
|
||||
for (std::pair<DivSystem,int> k: defCountMap) {
|
||||
auto countI=sysCountMap.find(k.first);
|
||||
if (countI==sysCountMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
} else if (countI->second!=k.second) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
|
||||
auto confI=sysConfMap.find(k.first);
|
||||
if (confI==sysConfMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
DivConfig& sysDC=confI->second;
|
||||
auto defConfI=defConfMap.find(k.first);
|
||||
if (defConfI==defConfMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
for (std::pair<String,String> l: defConfI->second.configMap()) {
|
||||
if (!sysDC.has(l.first)) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
if (sysDC.getString(l.first,"")!=l.second) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isMatch) break;
|
||||
}
|
||||
if (isMatch) {
|
||||
logV("match found!");
|
||||
e->song.systemName=j.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!j.subDefs.empty()) autoDetectSystemIter(j.subDefs,isMatch,defCountMap,defConfMap,sysCountMap,sysConfMap);
|
||||
if (isMatch) break;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::autoDetectSystem() {
|
||||
std::map<DivSystem,int> sysCountMap;
|
||||
std::map<DivSystem,DivConfig> sysConfMap;
|
||||
|
|
@ -657,65 +724,7 @@ void FurnaceGUI::autoDetectSystem() {
|
|||
std::map<DivSystem,int> defCountMap;
|
||||
std::map<DivSystem,DivConfig> defConfMap;
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
for (FurnaceGUISysDef& j: i.systems) {
|
||||
defCountMap.clear();
|
||||
defConfMap.clear();
|
||||
for (FurnaceGUISysDefChip& k: j.orig) {
|
||||
auto it=defCountMap.find(k.sys);
|
||||
if (it==defCountMap.cend()) {
|
||||
defCountMap[k.sys]=1;
|
||||
} else {
|
||||
it->second++;
|
||||
}
|
||||
DivConfig dc;
|
||||
dc.loadFromMemory(k.flags);
|
||||
defConfMap[k.sys]=dc;
|
||||
}
|
||||
if (defCountMap.size()!=sysCountMap.size()) continue;
|
||||
isMatch=true;
|
||||
/*logV("trying on defCountMap: %s",j.name);
|
||||
for (std::pair<DivSystem,int> k: defCountMap) {
|
||||
logV("- %s: %d",e->getSystemName(k.first),k.second);
|
||||
}*/
|
||||
for (std::pair<DivSystem,int> k: defCountMap) {
|
||||
auto countI=sysCountMap.find(k.first);
|
||||
if (countI==sysCountMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
} else if (countI->second!=k.second) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
|
||||
auto confI=sysConfMap.find(k.first);
|
||||
if (confI==sysConfMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
DivConfig& sysDC=confI->second;
|
||||
auto defConfI=defConfMap.find(k.first);
|
||||
if (defConfI==defConfMap.cend()) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
for (std::pair<String,String> l: defConfI->second.configMap()) {
|
||||
if (!sysDC.has(l.first)) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
if (sysDC.getString(l.first,"")!=l.second) {
|
||||
isMatch=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isMatch) break;
|
||||
}
|
||||
if (isMatch) {
|
||||
logV("match found!");
|
||||
e->song.systemName=j.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
autoDetectSystemIter(i.systems,isMatch,defCountMap,defConfMap,sysCountMap,sysConfMap);
|
||||
if (isMatch) break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1814,6 +1814,7 @@ class FurnaceGUI {
|
|||
int basicColors;
|
||||
int playbackTime;
|
||||
int shaderOsc;
|
||||
int cursorWheelStep;
|
||||
unsigned int maxUndoSteps;
|
||||
String mainFontPath;
|
||||
String headFontPath;
|
||||
|
|
@ -2018,6 +2019,7 @@ class FurnaceGUI {
|
|||
basicColors(1),
|
||||
playbackTime(1),
|
||||
shaderOsc(1),
|
||||
cursorWheelStep(0),
|
||||
maxUndoSteps(100),
|
||||
mainFontPath(""),
|
||||
headFontPath(""),
|
||||
|
|
@ -2511,6 +2513,7 @@ class FurnaceGUI {
|
|||
|
||||
void updateWindowTitle();
|
||||
void autoDetectSystem();
|
||||
void autoDetectSystemIter(std::vector<FurnaceGUISysDef>& category, bool& isMatch, std::map<DivSystem,int>& defCountMap, std::map<DivSystem,DivConfig>& defConfMap, std::map<DivSystem,int>& sysCountMap, std::map<DivSystem,DivConfig>& sysConfMap);
|
||||
void prepareLayout();
|
||||
ImVec4 channelColor(int ch);
|
||||
ImVec4 channelTextColor(int ch);
|
||||
|
|
@ -2549,6 +2552,8 @@ class FurnaceGUI {
|
|||
void waveListItem(int index, float* wavePreview, int dir, int asset);
|
||||
void sampleListItem(int index, int dir, int asset);
|
||||
|
||||
void drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& accepted, std::vector<int>& sysDefStack);
|
||||
|
||||
void toggleMobileUI(bool enable, bool force=false);
|
||||
|
||||
void pushToggleColors(bool status);
|
||||
|
|
@ -2712,6 +2717,9 @@ class FurnaceGUI {
|
|||
void initTutorial();
|
||||
void activateTutorial(FurnaceGUITutorials which);
|
||||
|
||||
bool loadUserPresets(bool redundancy=true);
|
||||
bool saveUserPresets(bool redundancy=true);
|
||||
|
||||
void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex=false, bool bit30=false);
|
||||
void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, unsigned char& macroLoop, int macroMin, int macroMax, unsigned char& macroRel, bool bit30=false);
|
||||
void decodeMMLStrW(String& source, int* macro, int& macroLen, int macroMin, int macroMax, bool hex=false);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,80 @@
|
|||
#include <fmt/printf.h>
|
||||
#include <algorithm>
|
||||
|
||||
String sysDefID;
|
||||
|
||||
void FurnaceGUI::drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& accepted, std::vector<int>& sysDefStack) {
|
||||
int index=0;
|
||||
String sysDefIDLeader="##NS";
|
||||
for (int i: sysDefStack) {
|
||||
sysDefIDLeader+=fmt::sprintf("/%d",i);
|
||||
}
|
||||
for (FurnaceGUISysDef& i: category) {
|
||||
bool treeNode=false;
|
||||
bool isHovered=false;
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (!i.subDefs.empty()) {
|
||||
if (i.orig.empty()) {
|
||||
sysDefID=fmt::sprintf("%s%s/%dS",i.name,sysDefIDLeader,index);
|
||||
} else {
|
||||
sysDefID=fmt::sprintf("%s/%dS",sysDefIDLeader,index);
|
||||
}
|
||||
treeNode=ImGui::TreeNodeEx(sysDefID.c_str(),i.orig.empty()?ImGuiTreeNodeFlags_SpanAvailWidth:0);
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (!i.orig.empty()) {
|
||||
sysDefID=fmt::sprintf("%s%s/%d",i.name,sysDefIDLeader,index);
|
||||
if (ImGui::Selectable(sysDefID.c_str(),false,ImGuiSelectableFlags_DontClosePopups)) {
|
||||
nextDesc=i.definition;
|
||||
nextDescName=i.name;
|
||||
accepted=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) isHovered=true;
|
||||
} else if (i.subDefs.empty()) {
|
||||
ImGui::TextUnformatted(i.name);
|
||||
if (ImGui::IsItemHovered()) isHovered=true;
|
||||
}
|
||||
if (treeNode) {
|
||||
sysDefStack.push_back(index);
|
||||
drawSysDefs(i.subDefs,accepted,sysDefStack);
|
||||
sysDefStack.erase(sysDefStack.end()-1);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (isHovered) {
|
||||
if (ImGui::BeginTooltip()) {
|
||||
std::map<DivSystem,int> chipCounts;
|
||||
std::vector<DivSystem> chips;
|
||||
for (FurnaceGUISysDefChip chip: i.orig) {
|
||||
if (chipCounts.find(chip.sys)==chipCounts.end()) {
|
||||
chipCounts[chip.sys]=1;
|
||||
chips.push_back(chip.sys);
|
||||
} else {
|
||||
chipCounts[chip.sys]+=1;
|
||||
}
|
||||
}
|
||||
for (size_t chipIndex=0; chipIndex<chips.size(); chipIndex++) {
|
||||
DivSystem chip=chips[chipIndex];
|
||||
const DivSysDef* sysDef=e->getSystemDef(chip);
|
||||
ImGui::PushTextWrapPos(MIN(scrW*dpiScale,400.0f*dpiScale));
|
||||
ImGui::Text("%s (x%d): ",sysDef->name,chipCounts[chip]);
|
||||
ImGui::Text("%s",sysDef->description);
|
||||
ImGui::PopTextWrapPos();
|
||||
if (chipIndex+1<chips.size()) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawNewSong() {
|
||||
bool accepted=false;
|
||||
std::vector<int> sysDefStack;
|
||||
|
||||
ImGui::PushFont(bigFont);
|
||||
ImGui::SetCursorPosX((ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("Choose a System!").x)*0.5);
|
||||
|
|
@ -97,6 +169,7 @@ void FurnaceGUI::drawNewSong() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s",i.description);
|
||||
}
|
||||
if (strcmp(i.name,"User")==0) ImGui::Separator();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
|
@ -105,43 +178,19 @@ void FurnaceGUI::drawNewSong() {
|
|||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginTable("Systems",1,ImGuiTableFlags_BordersInnerV|ImGuiTableFlags_ScrollY)) {
|
||||
std::vector<FurnaceGUISysDef>& category=(newSongQuery.empty())?(sysCategories[newSongCategory].systems):(newSongSearchResults);
|
||||
for (FurnaceGUISysDef& i: category) {
|
||||
if (category.empty()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(i.name,false,ImGuiSelectableFlags_DontClosePopups)) {
|
||||
nextDesc=i.definition;
|
||||
nextDescName=i.name;
|
||||
accepted=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::BeginTooltip()) {
|
||||
std::map<DivSystem,int> chipCounts;
|
||||
std::vector<DivSystem> chips;
|
||||
for (FurnaceGUISysDefChip chip: i.orig) {
|
||||
if (chipCounts.find(chip.sys)==chipCounts.end()) {
|
||||
chipCounts[chip.sys]=1;
|
||||
chips.push_back(chip.sys);
|
||||
} else {
|
||||
chipCounts[chip.sys]+=1;
|
||||
}
|
||||
}
|
||||
for (size_t chipIndex=0; chipIndex<chips.size(); chipIndex++) {
|
||||
DivSystem chip=chips[chipIndex];
|
||||
const DivSysDef* sysDef=e->getSystemDef(chip);
|
||||
ImGui::PushTextWrapPos(MIN(scrW*dpiScale,400.0f*dpiScale));
|
||||
ImGui::Text("%s (x%d): ",sysDef->name,chipCounts[chip]);
|
||||
ImGui::Text("%s",sysDef->description);
|
||||
ImGui::PopTextWrapPos();
|
||||
if (chipIndex+1<chips.size()) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
if (newSongQuery.empty()) {
|
||||
ImGui::Text("no systems here yet!");
|
||||
} else {
|
||||
ImGui::Text("no results");
|
||||
}
|
||||
} else {
|
||||
sysDefStack.push_back(newSongQuery.empty()?newSongCategory:-1);
|
||||
drawSysDefs(category,accepted,sysDefStack);
|
||||
sysDefStack.erase(sysDefStack.end()-1);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,10 @@ void FurnaceGUI::drawPattern() {
|
|||
nextAddScroll=0.0f;
|
||||
}
|
||||
ImDrawList* tdl=NULL;
|
||||
if (ImGui::BeginTable("PatternView",displayChans+2,ImGuiTableFlags_BordersInnerV|ImGuiTableFlags_ScrollX|ImGuiTableFlags_ScrollY|ImGuiTableFlags_NoPadInnerX|ImGuiTableFlags_NoBordersInFrozenArea|((settings.cursorFollowsWheel || wheelCalmDown)?ImGuiTableFlags_NoScrollWithMouse:0))) {
|
||||
|
||||
if (chans<1) {
|
||||
ImGui::Text("there aren't any channels to show.");
|
||||
} else if (ImGui::BeginTable("PatternView",displayChans+2,ImGuiTableFlags_BordersInnerV|ImGuiTableFlags_ScrollX|ImGuiTableFlags_ScrollY|ImGuiTableFlags_NoPadInnerX|ImGuiTableFlags_NoBordersInFrozenArea|((settings.cursorFollowsWheel || wheelCalmDown)?ImGuiTableFlags_NoScrollWithMouse:0))) {
|
||||
ImGui::TableSetupColumn("pos",ImGuiTableColumnFlags_WidthFixed);
|
||||
char chanID[2048];
|
||||
float lineHeight=(ImGui::GetTextLineHeight()+2*dpiScale);
|
||||
|
|
@ -1176,7 +1179,13 @@ void FurnaceGUI::drawPattern() {
|
|||
// cursor follows wheel
|
||||
if (settings.cursorFollowsWheel && (!e->isPlaying() || !followPattern) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) {
|
||||
if (wheelX!=0 || wheelY!=0) {
|
||||
moveCursor(wheelX,(settings.cursorFollowsWheel==2)?wheelY:-wheelY,false);
|
||||
int xAmount=wheelX;
|
||||
int yAmount=(settings.cursorFollowsWheel==2)?wheelY:-wheelY;
|
||||
if (settings.cursorWheelStep==1) {
|
||||
xAmount*=MAX(1,editStep);
|
||||
yAmount*=MAX(1,editStep);
|
||||
}
|
||||
moveCursor(xAmount,yAmount,false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
4382
src/gui/presets.cpp
4382
src/gui/presets.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -2423,6 +2423,18 @@ void FurnaceGUI::drawSettings() {
|
|||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
if (settings.cursorFollowsWheel) {
|
||||
ImGui::Text("How many steps to move with each scroll wheel step?");
|
||||
if (ImGui::RadioButton("One##cws0",settings.cursorWheelStep==0)) {
|
||||
settings.cursorWheelStep=0;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton("Edit Step##cws1",settings.cursorWheelStep==1)) {
|
||||
settings.cursorWheelStep=1;
|
||||
settingsChanged=true;
|
||||
}
|
||||
}
|
||||
|
||||
// SUBSECTION ASSETS
|
||||
CONFIG_SUBSECTION("Assets");
|
||||
|
||||
|
|
@ -3992,6 +4004,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.insertBehavior=conf.getInt("insertBehavior",1);
|
||||
settings.pullDeleteRow=conf.getInt("pullDeleteRow",1);
|
||||
settings.cursorFollowsWheel=conf.getInt("cursorFollowsWheel",0);
|
||||
settings.cursorWheelStep=conf.getInt("cursorWheelStep",0);
|
||||
settings.removeInsOff=conf.getInt("removeInsOff",0);
|
||||
settings.removeVolOff=conf.getInt("removeVolOff",0);
|
||||
settings.insTypeMenu=conf.getInt("insTypeMenu",1);
|
||||
|
|
@ -4323,6 +4336,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.playbackTime,0,1);
|
||||
clampSetting(settings.shaderOsc,0,1);
|
||||
clampSetting(settings.oscLineSize,0.25f,16.0f);
|
||||
clampSetting(settings.cursorWheelStep,0,1);
|
||||
|
||||
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||
|
|
@ -4462,6 +4476,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("insertBehavior",settings.insertBehavior);
|
||||
conf.set("pullDeleteRow",settings.pullDeleteRow);
|
||||
conf.set("cursorFollowsWheel",settings.cursorFollowsWheel);
|
||||
conf.set("cursorWheelStep",settings.cursorWheelStep);
|
||||
conf.set("removeInsOff",settings.removeInsOff);
|
||||
conf.set("removeVolOff",settings.removeVolOff);
|
||||
conf.set("insTypeMenu",settings.insTypeMenu);
|
||||
|
|
|
|||
Loading…
Reference in a new issue