commit
						a642cb4d4b
					
				| 
						 | 
					@ -779,6 +779,7 @@ src/gui/doAction.cpp
 | 
				
			||||||
src/gui/editing.cpp
 | 
					src/gui/editing.cpp
 | 
				
			||||||
src/gui/editControls.cpp
 | 
					src/gui/editControls.cpp
 | 
				
			||||||
src/gui/effectList.cpp
 | 
					src/gui/effectList.cpp
 | 
				
			||||||
 | 
					src/gui/exportOptions.cpp
 | 
				
			||||||
src/gui/findReplace.cpp
 | 
					src/gui/findReplace.cpp
 | 
				
			||||||
src/gui/fmPreview.cpp
 | 
					src/gui/fmPreview.cpp
 | 
				
			||||||
src/gui/gradient.cpp
 | 
					src/gui/gradient.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,9 @@ void FurnaceGUI::doAction(int what) {
 | 
				
			||||||
    case GUI_ACTION_SAVE_AS:
 | 
					    case GUI_ACTION_SAVE_AS:
 | 
				
			||||||
      openFileDialog(GUI_FILE_SAVE);
 | 
					      openFileDialog(GUI_FILE_SAVE);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					    case GUI_ACTION_EXPORT:
 | 
				
			||||||
 | 
					      displayExport=true;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
    case GUI_ACTION_UNDO:
 | 
					    case GUI_ACTION_UNDO:
 | 
				
			||||||
      if (curWindow==GUI_WINDOW_SAMPLE_EDIT) {
 | 
					      if (curWindow==GUI_WINDOW_SAMPLE_EDIT) {
 | 
				
			||||||
        doUndoSample();
 | 
					        doUndoSample();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										270
									
								
								src/gui/exportOptions.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/gui/exportOptions.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,270 @@
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Furnace Tracker - multi-system chiptune tracker
 | 
				
			||||||
 | 
					 * Copyright (C) 2021-2023 tildearrow and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gui.h"
 | 
				
			||||||
 | 
					#include "guiConst.h"
 | 
				
			||||||
 | 
					#include "../fileutils.h"
 | 
				
			||||||
 | 
					#include "misc/cpp/imgui_stdlib.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportAudio() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ImGui::RadioButton("one file",&audioExportType,0);
 | 
				
			||||||
 | 
					  ImGui::RadioButton("multiple files (one per chip)",&audioExportType,1);
 | 
				
			||||||
 | 
					  ImGui::RadioButton("multiple files (one per channel)",&audioExportType,2);
 | 
				
			||||||
 | 
					  if (ImGui::InputInt("Loops",&exportLoops,1,2)) {
 | 
				
			||||||
 | 
					    if (exportLoops<0) exportLoops=0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) {
 | 
				
			||||||
 | 
					    if (exportFadeOut<0.0) exportFadeOut=0.0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (ImGui::Button("Export")) {
 | 
				
			||||||
 | 
					    switch (audioExportType) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportVGM() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ImGui::Text("settings:");
 | 
				
			||||||
 | 
					  if (ImGui::BeginCombo("format version",fmt::sprintf("%d.%.2x",vgmExportVersion>>8,vgmExportVersion&0xff).c_str())) {
 | 
				
			||||||
 | 
					    for (int i=0; i<7; i++) {
 | 
				
			||||||
 | 
					      if (ImGui::Selectable(fmt::sprintf("%d.%.2x",vgmVersions[i]>>8,vgmVersions[i]&0xff).c_str(),vgmExportVersion==vgmVersions[i])) {
 | 
				
			||||||
 | 
					        vgmExportVersion=vgmVersions[i];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ImGui::EndCombo();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Checkbox("loop",&vgmExportLoop);
 | 
				
			||||||
 | 
					  if (vgmExportLoop && e->song.loopModality==2) {
 | 
				
			||||||
 | 
					    ImGui::Text("loop trail:");
 | 
				
			||||||
 | 
					    ImGui::Indent();
 | 
				
			||||||
 | 
					    if (ImGui::RadioButton("auto-detect",vgmExportTrailingTicks==-1)) {
 | 
				
			||||||
 | 
					      vgmExportTrailingTicks=-1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (ImGui::RadioButton("add one loop",vgmExportTrailingTicks==-2)) {
 | 
				
			||||||
 | 
					      vgmExportTrailingTicks=-2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (ImGui::RadioButton("custom",vgmExportTrailingTicks>=0)) {
 | 
				
			||||||
 | 
					      vgmExportTrailingTicks=0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vgmExportTrailingTicks>=0) {
 | 
				
			||||||
 | 
					      ImGui::SameLine();
 | 
				
			||||||
 | 
					      if (ImGui::InputInt("##TrailTicks",&vgmExportTrailingTicks,1,100)) {
 | 
				
			||||||
 | 
					        if (vgmExportTrailingTicks<0) vgmExportTrailingTicks=0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ImGui::Unindent();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints);
 | 
				
			||||||
 | 
					  if (ImGui::IsItemHovered()) {
 | 
				
			||||||
 | 
					    ImGui::SetTooltip(
 | 
				
			||||||
 | 
					      "inserts data blocks on pattern changes.\n"
 | 
				
			||||||
 | 
					      "useful if you are writing a playback routine.\n\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "the format of a pattern change data block is:\n"
 | 
				
			||||||
 | 
					      "67 66 FE ll ll ll ll 01 oo rr pp pp pp ...\n"
 | 
				
			||||||
 | 
					      "- ll: length, a 32-bit little-endian number\n"
 | 
				
			||||||
 | 
					      "- oo: order\n"
 | 
				
			||||||
 | 
					      "- rr: initial row (a 0Dxx effect is able to select a different row)\n"
 | 
				
			||||||
 | 
					      "- pp: pattern index (one per channel)\n\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "pattern indexes are ordered as they appear in the song."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Checkbox("direct stream mode",&vgmExportDirectStream);
 | 
				
			||||||
 | 
					  if (ImGui::IsItemHovered()) {
 | 
				
			||||||
 | 
					    ImGui::SetTooltip(
 | 
				
			||||||
 | 
					      "required for DualPCM and MSM6258 export.\n\n"
 | 
				
			||||||
 | 
					      "allows for volume/direction changes when playing samples,\n"
 | 
				
			||||||
 | 
					      "at the cost of a massive increase in file size."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Text("chips to export:");
 | 
				
			||||||
 | 
					  bool hasOneAtLeast=false;
 | 
				
			||||||
 | 
					  for (int i=0; i<e->song.systemLen; i++) {
 | 
				
			||||||
 | 
					    int minVersion=e->minVGMVersion(e->song.system[i]);
 | 
				
			||||||
 | 
					    ImGui::BeginDisabled(minVersion>vgmExportVersion || minVersion==0);
 | 
				
			||||||
 | 
					    ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]);
 | 
				
			||||||
 | 
					    ImGui::EndDisabled();
 | 
				
			||||||
 | 
					    if (minVersion>vgmExportVersion) {
 | 
				
			||||||
 | 
					      if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
 | 
				
			||||||
 | 
					        ImGui::SetTooltip("this chip is only available in VGM %d.%.2x and higher!",minVersion>>8,minVersion&0xff);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else if (minVersion==0) {
 | 
				
			||||||
 | 
					      if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
 | 
				
			||||||
 | 
					        ImGui::SetTooltip("this chip is not supported by the VGM format!");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      if (willExport[i]) hasOneAtLeast=true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Text("select the chip you wish to export, but only up to %d of each type.",(vgmExportVersion>=0x151)?2:1);
 | 
				
			||||||
 | 
					  if (hasOneAtLeast) {
 | 
				
			||||||
 | 
					    if (ImGui::Button("Export")) {
 | 
				
			||||||
 | 
					      openFileDialog(GUI_FILE_EXPORT_VGM);
 | 
				
			||||||
 | 
					      ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    ImGui::Text("nothing to export");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportZSM() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ImGui::Text("Commander X16 Zsound Music File");
 | 
				
			||||||
 | 
					  if (ImGui::InputInt("Tick Rate (Hz)",&zsmExportTickRate,1,2)) {
 | 
				
			||||||
 | 
					    if (zsmExportTickRate<1) zsmExportTickRate=1;
 | 
				
			||||||
 | 
					    if (zsmExportTickRate>44100) zsmExportTickRate=44100;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Checkbox("loop",&zsmExportLoop);
 | 
				
			||||||
 | 
					  ImGui::SameLine();
 | 
				
			||||||
 | 
					  ImGui::Checkbox("optimize size",&zsmExportOptimize);
 | 
				
			||||||
 | 
					  if (ImGui::Button("Export")) {
 | 
				
			||||||
 | 
					    openFileDialog(GUI_FILE_EXPORT_ZSM);
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportAmigaVal() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ImGui::Text(
 | 
				
			||||||
 | 
					    "this is NOT ROM export! only use for making sure the\n"
 | 
				
			||||||
 | 
					    "Furnace Amiga emulator is working properly by\n"
 | 
				
			||||||
 | 
					    "comparing it with real Amiga output."
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  ImGui::AlignTextToFramePadding();
 | 
				
			||||||
 | 
					  ImGui::Text("Directory");
 | 
				
			||||||
 | 
					  ImGui::SameLine();
 | 
				
			||||||
 | 
					  ImGui::InputText("##AVDPath",&workingDirROMExport);
 | 
				
			||||||
 | 
					  if (ImGui::Button("Bake Data")) {
 | 
				
			||||||
 | 
					    std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
 | 
				
			||||||
 | 
					    if (workingDirROMExport.size()>0) {
 | 
				
			||||||
 | 
					      if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (DivROMExportOutput& i: out) {
 | 
				
			||||||
 | 
					      String path=workingDirROMExport+i.name;
 | 
				
			||||||
 | 
					      FILE* outFile=ps_fopen(path.c_str(),"wb");
 | 
				
			||||||
 | 
					      if (outFile!=NULL) {
 | 
				
			||||||
 | 
					        fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
 | 
				
			||||||
 | 
					        fclose(outFile);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      i.data->finish();
 | 
				
			||||||
 | 
					      delete i.data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    showError(fmt::sprintf("Done! Baked %d files.",(int)out.size()));
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportText() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ImGui::Text(
 | 
				
			||||||
 | 
					    "this option exports the song to a text file.\n"
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  if (ImGui::Button("Export")) {
 | 
				
			||||||
 | 
					    openFileDialog(GUI_FILE_EXPORT_TEXT);
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExportCommand() {
 | 
				
			||||||
 | 
					  exitDisabledTimer=1;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  ImGui::Text(
 | 
				
			||||||
 | 
					    "this option exports a text or binary file which\n"
 | 
				
			||||||
 | 
					    "contains a dump of the internal command stream\n"
 | 
				
			||||||
 | 
					    "produced when playing the song.\n\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "technical/development use only!"
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  if (ImGui::Button("Export (binary)")) {
 | 
				
			||||||
 | 
					    openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY);
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (ImGui::Button("Export (text)")) {
 | 
				
			||||||
 | 
					    openFileDialog(GUI_FILE_EXPORT_CMDSTREAM);
 | 
				
			||||||
 | 
					    ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FurnaceGUI::drawExport() {
 | 
				
			||||||
 | 
					  ImVec2 avail=ImGui::GetContentRegionAvail();
 | 
				
			||||||
 | 
					  avail.y-=ImGui::GetFrameHeightWithSpacing();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (ImGui::BeginChild("sysPickerC",avail,false,ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar)) {
 | 
				
			||||||
 | 
					    if (ImGui::BeginTabBar("ExportTypes")) {
 | 
				
			||||||
 | 
					      if (ImGui::BeginTabItem("Audio")) {
 | 
				
			||||||
 | 
					        drawExportAudio();
 | 
				
			||||||
 | 
					        ImGui::EndTabItem();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (ImGui::BeginTabItem("VGM")) {
 | 
				
			||||||
 | 
					        drawExportVGM();
 | 
				
			||||||
 | 
					        ImGui::EndTabItem();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      int numZSMCompat=0;
 | 
				
			||||||
 | 
					      for (int i=0; i<e->song.systemLen; i++) {
 | 
				
			||||||
 | 
					        if ((e->song.system[i]==DIV_SYSTEM_VERA) || (e->song.system[i]==DIV_SYSTEM_YM2151)) numZSMCompat++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (numZSMCompat>0) {
 | 
				
			||||||
 | 
					        if (ImGui::BeginTabItem("ZSM")) {
 | 
				
			||||||
 | 
					          drawExportZSM();
 | 
				
			||||||
 | 
					          ImGui::EndTabItem();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      int numAmiga=0;
 | 
				
			||||||
 | 
					      for (int i=0; i<e->song.systemLen; i++) {
 | 
				
			||||||
 | 
					        if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (numAmiga && settings.iCannotWait) {
 | 
				
			||||||
 | 
					        if (ImGui::BeginTabItem("Amiga Validation")) {
 | 
				
			||||||
 | 
					          drawExportAmigaVal();
 | 
				
			||||||
 | 
					          ImGui::EndTabItem();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (ImGui::BeginTabItem("Text")) {
 | 
				
			||||||
 | 
					        drawExportText();
 | 
				
			||||||
 | 
					        ImGui::EndTabItem();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (ImGui::BeginTabItem("Command Stream")) {
 | 
				
			||||||
 | 
					        drawExportCommand();
 | 
				
			||||||
 | 
					        ImGui::EndTabItem();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ImGui::EndTabBar();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ImGui::EndChild();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ImGui::Separator();
 | 
				
			||||||
 | 
					  if (ImGui::Button("Cancel")) ImGui::CloseCurrentPopup();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										225
									
								
								src/gui/gui.cpp
									
									
									
									
									
								
							
							
						
						
									
										225
									
								
								src/gui/gui.cpp
									
									
									
									
									
								
							| 
						 | 
					@ -4101,197 +4101,47 @@ bool FurnaceGUI::loop() {
 | 
				
			||||||
          openFileDialog(GUI_FILE_SAVE_DMF_LEGACY);
 | 
					          openFileDialog(GUI_FILE_SAVE_DMF_LEGACY);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ImGui::Separator();
 | 
					        ImGui::Separator();
 | 
				
			||||||
        if (ImGui::BeginMenu("export audio...")) {
 | 
					        if (settings.exportOptionsLayout) {
 | 
				
			||||||
          exitDisabledTimer=1;
 | 
					          if (ImGui::BeginMenu("export audio...")) {
 | 
				
			||||||
          if (ImGui::MenuItem("one file")) {
 | 
					            drawExportAudio();
 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE);
 | 
					            ImGui::EndMenu();
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (ImGui::MenuItem("multiple files (one per chip)")) {
 | 
					          if (ImGui::BeginMenu("export VGM...")) {
 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS);
 | 
					            drawExportVGM();
 | 
				
			||||||
 | 
					            ImGui::EndMenu();
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (ImGui::MenuItem("multiple files (one per channel)")) {
 | 
					          int numZSMCompat=0;
 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          if (ImGui::InputInt("Loops",&exportLoops,1,2)) {
 | 
					 | 
				
			||||||
            if (exportLoops<0) exportLoops=0;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) {
 | 
					 | 
				
			||||||
            if (exportFadeOut<0.0) exportFadeOut=0.0;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::EndMenu();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (ImGui::BeginMenu("export VGM...")) {
 | 
					 | 
				
			||||||
          exitDisabledTimer=1;
 | 
					 | 
				
			||||||
          ImGui::Text("settings:");
 | 
					 | 
				
			||||||
          if (ImGui::BeginCombo("format version",fmt::sprintf("%d.%.2x",vgmExportVersion>>8,vgmExportVersion&0xff).c_str())) {
 | 
					 | 
				
			||||||
            for (int i=0; i<7; i++) {
 | 
					 | 
				
			||||||
              if (ImGui::Selectable(fmt::sprintf("%d.%.2x",vgmVersions[i]>>8,vgmVersions[i]&0xff).c_str(),vgmExportVersion==vgmVersions[i])) {
 | 
					 | 
				
			||||||
                vgmExportVersion=vgmVersions[i];
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ImGui::EndCombo();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::Checkbox("loop",&vgmExportLoop);
 | 
					 | 
				
			||||||
          if (vgmExportLoop && e->song.loopModality==2) {
 | 
					 | 
				
			||||||
            ImGui::Text("loop trail:");
 | 
					 | 
				
			||||||
            ImGui::Indent();
 | 
					 | 
				
			||||||
            if (ImGui::RadioButton("auto-detect",vgmExportTrailingTicks==-1)) {
 | 
					 | 
				
			||||||
              vgmExportTrailingTicks=-1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (ImGui::RadioButton("add one loop",vgmExportTrailingTicks==-2)) {
 | 
					 | 
				
			||||||
              vgmExportTrailingTicks=-2;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (ImGui::RadioButton("custom",vgmExportTrailingTicks>=0)) {
 | 
					 | 
				
			||||||
              vgmExportTrailingTicks=0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (vgmExportTrailingTicks>=0) {
 | 
					 | 
				
			||||||
              ImGui::SameLine();
 | 
					 | 
				
			||||||
              if (ImGui::InputInt("##TrailTicks",&vgmExportTrailingTicks,1,100)) {
 | 
					 | 
				
			||||||
                if (vgmExportTrailingTicks<0) vgmExportTrailingTicks=0;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ImGui::Unindent();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints);
 | 
					 | 
				
			||||||
          if (ImGui::IsItemHovered()) {
 | 
					 | 
				
			||||||
            ImGui::SetTooltip(
 | 
					 | 
				
			||||||
              "inserts data blocks on pattern changes.\n"
 | 
					 | 
				
			||||||
              "useful if you are writing a playback routine.\n\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              "the format of a pattern change data block is:\n"
 | 
					 | 
				
			||||||
              "67 66 FE ll ll ll ll 01 oo rr pp pp pp ...\n"
 | 
					 | 
				
			||||||
              "- ll: length, a 32-bit little-endian number\n"
 | 
					 | 
				
			||||||
              "- oo: order\n"
 | 
					 | 
				
			||||||
              "- rr: initial row (a 0Dxx effect is able to select a different row)\n"
 | 
					 | 
				
			||||||
              "- pp: pattern index (one per channel)\n\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              "pattern indexes are ordered as they appear in the song."
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::Checkbox("direct stream mode",&vgmExportDirectStream);
 | 
					 | 
				
			||||||
          if (ImGui::IsItemHovered()) {
 | 
					 | 
				
			||||||
            ImGui::SetTooltip(
 | 
					 | 
				
			||||||
              "required for DualPCM and MSM6258 export.\n\n"
 | 
					 | 
				
			||||||
              "allows for volume/direction changes when playing samples,\n"
 | 
					 | 
				
			||||||
              "at the cost of a massive increase in file size."
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::Text("chips to export:");
 | 
					 | 
				
			||||||
          bool hasOneAtLeast=false;
 | 
					 | 
				
			||||||
          for (int i=0; i<e->song.systemLen; i++) {
 | 
					          for (int i=0; i<e->song.systemLen; i++) {
 | 
				
			||||||
            int minVersion=e->minVGMVersion(e->song.system[i]);
 | 
					            if ((e->song.system[i]==DIV_SYSTEM_VERA) || (e->song.system[i]==DIV_SYSTEM_YM2151)) numZSMCompat++;
 | 
				
			||||||
            ImGui::BeginDisabled(minVersion>vgmExportVersion || minVersion==0);
 | 
					          }
 | 
				
			||||||
            ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]);
 | 
					          if (numZSMCompat > 0) {
 | 
				
			||||||
            ImGui::EndDisabled();
 | 
					            if (ImGui::BeginMenu("export ZSM...")) {
 | 
				
			||||||
            if (minVersion>vgmExportVersion) {
 | 
					              drawExportZSM();
 | 
				
			||||||
              if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
 | 
					              ImGui::EndMenu();
 | 
				
			||||||
                ImGui::SetTooltip("this chip is only available in VGM %d.%.2x and higher!",minVersion>>8,minVersion&0xff);
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            } else if (minVersion==0) {
 | 
					 | 
				
			||||||
              if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
 | 
					 | 
				
			||||||
                ImGui::SetTooltip("this chip is not supported by the VGM format!");
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              if (willExport[i]) hasOneAtLeast=true;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          ImGui::Text("select the chip you wish to export,");
 | 
					          int numAmiga=0;
 | 
				
			||||||
          ImGui::Text("but only up to %d of each type.",(vgmExportVersion>=0x151)?2:1);
 | 
					          for (int i=0; i<e->song.systemLen; i++) {
 | 
				
			||||||
          if (hasOneAtLeast) {
 | 
					            if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
 | 
				
			||||||
            if (ImGui::MenuItem("click to export")) {
 | 
					 | 
				
			||||||
              openFileDialog(GUI_FILE_EXPORT_VGM);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            ImGui::Text("nothing to export");
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          ImGui::EndMenu();
 | 
					          if (numAmiga && settings.iCannotWait) {
 | 
				
			||||||
        }
 | 
					            if (ImGui::BeginMenu("export Amiga validation data...")) {
 | 
				
			||||||
        int numZSMCompat=0;
 | 
					              drawExportAmigaVal();
 | 
				
			||||||
        for (int i=0; i<e->song.systemLen; i++) {
 | 
					              ImGui::EndMenu();
 | 
				
			||||||
          if ((e->song.system[i] == DIV_SYSTEM_VERA) || (e->song.system[i] == DIV_SYSTEM_YM2151)) numZSMCompat++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (numZSMCompat > 0) {
 | 
					 | 
				
			||||||
          if (ImGui::BeginMenu("export ZSM...")) {
 | 
					 | 
				
			||||||
            exitDisabledTimer=1;
 | 
					 | 
				
			||||||
            ImGui::Text("Commander X16 Zsound Music File");
 | 
					 | 
				
			||||||
            if (ImGui::InputInt("Tick Rate (Hz)",&zsmExportTickRate,1,10)) {
 | 
					 | 
				
			||||||
              if (zsmExportTickRate<1) zsmExportTickRate=1;
 | 
					 | 
				
			||||||
              if (zsmExportTickRate>44100) zsmExportTickRate=44100;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ImGui::Checkbox("loop",&zsmExportLoop);
 | 
					 | 
				
			||||||
            ImGui::SameLine();
 | 
					 | 
				
			||||||
            ImGui::Checkbox("optimize size",&zsmExportOptimize);
 | 
					 | 
				
			||||||
            ImGui::SameLine();
 | 
					 | 
				
			||||||
            if (ImGui::Button("Begin Export")) {
 | 
					 | 
				
			||||||
              openFileDialog(GUI_FILE_EXPORT_ZSM);
 | 
					 | 
				
			||||||
              ImGui::CloseCurrentPopup();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (ImGui::BeginMenu("export text...")) {
 | 
				
			||||||
 | 
					            drawExportText();
 | 
				
			||||||
            ImGui::EndMenu();
 | 
					            ImGui::EndMenu();
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					          if (ImGui::BeginMenu("export command stream...")) {
 | 
				
			||||||
        int numAmiga=0;
 | 
					            drawExportCommand();
 | 
				
			||||||
        for (int i=0; i<e->song.systemLen; i++) {
 | 
					 | 
				
			||||||
          if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (numAmiga && settings.iCannotWait) {
 | 
					 | 
				
			||||||
          if (ImGui::BeginMenu("export Amiga validation data...")) {
 | 
					 | 
				
			||||||
            exitDisabledTimer=1;
 | 
					 | 
				
			||||||
            ImGui::Text(
 | 
					 | 
				
			||||||
              "this is NOT ROM export! only use for making sure the\n"
 | 
					 | 
				
			||||||
              "Furnace Amiga emulator is working properly by\n"
 | 
					 | 
				
			||||||
              "comparing it with real Amiga output."
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            ImGui::AlignTextToFramePadding();
 | 
					 | 
				
			||||||
            ImGui::Text("Directory");
 | 
					 | 
				
			||||||
            ImGui::SameLine();
 | 
					 | 
				
			||||||
            ImGui::InputText("##AVDPath",&workingDirROMExport);
 | 
					 | 
				
			||||||
            if (ImGui::Button("Bake Data")) {
 | 
					 | 
				
			||||||
              std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
 | 
					 | 
				
			||||||
              if (workingDirROMExport.size()>0) {
 | 
					 | 
				
			||||||
                if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              for (DivROMExportOutput& i: out) {
 | 
					 | 
				
			||||||
                String path=workingDirROMExport+i.name;
 | 
					 | 
				
			||||||
                FILE* outFile=ps_fopen(path.c_str(),"wb");
 | 
					 | 
				
			||||||
                if (outFile!=NULL) {
 | 
					 | 
				
			||||||
                  fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
 | 
					 | 
				
			||||||
                  fclose(outFile);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                i.data->finish();
 | 
					 | 
				
			||||||
                delete i.data;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              showError(fmt::sprintf("Done! Baked %d files.",(int)out.size()));
 | 
					 | 
				
			||||||
              ImGui::CloseCurrentPopup();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ImGui::EndMenu();
 | 
					            ImGui::EndMenu();
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        } else {
 | 
				
			||||||
        if (ImGui::BeginMenu("export text...")) {
 | 
					          if (ImGui::MenuItem("export...",BIND_FOR(GUI_ACTION_EXPORT))) {
 | 
				
			||||||
          exitDisabledTimer=1;
 | 
					            displayExport=true;
 | 
				
			||||||
          ImGui::Text(
 | 
					 | 
				
			||||||
            "this option exports the song to a text file.\n"
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          if (ImGui::Button("export")) {
 | 
					 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_TEXT);
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          ImGui::EndMenu();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (ImGui::BeginMenu("export command stream...")) {
 | 
					 | 
				
			||||||
          exitDisabledTimer=1;
 | 
					 | 
				
			||||||
          ImGui::Text(
 | 
					 | 
				
			||||||
            "this option exports a text or binary file which\n"
 | 
					 | 
				
			||||||
            "contains a dump of the internal command stream\n"
 | 
					 | 
				
			||||||
            "produced when playing the song.\n\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            "technical/development use only!"
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          if (ImGui::Button("export (binary)")) {
 | 
					 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          if (ImGui::Button("export (text)")) {
 | 
					 | 
				
			||||||
            openFileDialog(GUI_FILE_EXPORT_CMDSTREAM);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          ImGui::EndMenu();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ImGui::Separator();
 | 
					        ImGui::Separator();
 | 
				
			||||||
        if (!settings.classicChipOptions) {
 | 
					        if (!settings.classicChipOptions) {
 | 
				
			||||||
| 
						 | 
					@ -5487,6 +5337,11 @@ bool FurnaceGUI::loop() {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (displayExport) {
 | 
				
			||||||
 | 
					      displayExport=false;
 | 
				
			||||||
 | 
					      ImGui::OpenPopup("Export");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (displayEditString) {
 | 
					    if (displayEditString) {
 | 
				
			||||||
      ImGui::OpenPopup("EditString");
 | 
					      ImGui::OpenPopup("EditString");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -5528,6 +5383,15 @@ bool FurnaceGUI::loop() {
 | 
				
			||||||
      ImGui::EndPopup();
 | 
					      ImGui::EndPopup();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ImGui::BeginPopupModal("Export",NULL,ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar)) {
 | 
				
			||||||
 | 
					      ImGui::SetWindowPos(ImVec2(((canvasW)-ImGui::GetWindowSize().x)*0.5,((canvasH)-ImGui::GetWindowSize().y)*0.5));
 | 
				
			||||||
 | 
					      if (ImGui::GetWindowSize().x<newSongMinSize.x || ImGui::GetWindowSize().y<newSongMinSize.y) {
 | 
				
			||||||
 | 
					        ImGui::SetWindowSize(newSongMinSize,ImGuiCond_Always);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      drawExport();
 | 
				
			||||||
 | 
					      ImGui::EndPopup();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    centerNextWindow("Error",canvasW,canvasH);
 | 
					    centerNextWindow("Error",canvasW,canvasH);
 | 
				
			||||||
    if (ImGui::BeginPopupModal("Error",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
 | 
					    if (ImGui::BeginPopupModal("Error",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
 | 
				
			||||||
      ImGui::Text("%s",errorString.c_str());
 | 
					      ImGui::Text("%s",errorString.c_str());
 | 
				
			||||||
| 
						 | 
					@ -7729,7 +7593,8 @@ FurnaceGUI::FurnaceGUI():
 | 
				
			||||||
  introSkipDo(false),
 | 
					  introSkipDo(false),
 | 
				
			||||||
  introStopped(false),
 | 
					  introStopped(false),
 | 
				
			||||||
  curTutorial(-1),
 | 
					  curTutorial(-1),
 | 
				
			||||||
  curTutorialStep(0) {
 | 
					  curTutorialStep(0),
 | 
				
			||||||
 | 
					  audioExportType(0) {
 | 
				
			||||||
  // value keys
 | 
					  // value keys
 | 
				
			||||||
  valueKeys[SDLK_0]=0;
 | 
					  valueKeys[SDLK_0]=0;
 | 
				
			||||||
  valueKeys[SDLK_1]=1;
 | 
					  valueKeys[SDLK_1]=1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -562,6 +562,7 @@ enum FurnaceGUIActions {
 | 
				
			||||||
  GUI_ACTION_OPEN_BACKUP,
 | 
					  GUI_ACTION_OPEN_BACKUP,
 | 
				
			||||||
  GUI_ACTION_SAVE,
 | 
					  GUI_ACTION_SAVE,
 | 
				
			||||||
  GUI_ACTION_SAVE_AS,
 | 
					  GUI_ACTION_SAVE_AS,
 | 
				
			||||||
 | 
					  GUI_ACTION_EXPORT,
 | 
				
			||||||
  GUI_ACTION_UNDO,
 | 
					  GUI_ACTION_UNDO,
 | 
				
			||||||
  GUI_ACTION_REDO,
 | 
					  GUI_ACTION_REDO,
 | 
				
			||||||
  GUI_ACTION_PLAY_TOGGLE,
 | 
					  GUI_ACTION_PLAY_TOGGLE,
 | 
				
			||||||
| 
						 | 
					@ -1433,7 +1434,7 @@ class FurnaceGUI {
 | 
				
			||||||
  bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList;
 | 
					  bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList;
 | 
				
			||||||
  bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed;
 | 
					  bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed;
 | 
				
			||||||
  bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
 | 
					  bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
 | 
				
			||||||
  bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange;
 | 
					  bool displayNew, displayExport, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange;
 | 
				
			||||||
  bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
 | 
					  bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
 | 
				
			||||||
  bool mobileEdit;
 | 
					  bool mobileEdit;
 | 
				
			||||||
  bool killGraphics;
 | 
					  bool killGraphics;
 | 
				
			||||||
| 
						 | 
					@ -1688,6 +1689,7 @@ class FurnaceGUI {
 | 
				
			||||||
    int centerPopup;
 | 
					    int centerPopup;
 | 
				
			||||||
    int insIconsStyle;
 | 
					    int insIconsStyle;
 | 
				
			||||||
    int classicChipOptions;
 | 
					    int classicChipOptions;
 | 
				
			||||||
 | 
					    int exportOptionsLayout;
 | 
				
			||||||
    int wasapiEx;
 | 
					    int wasapiEx;
 | 
				
			||||||
    int chanOscThreads;
 | 
					    int chanOscThreads;
 | 
				
			||||||
    int renderPoolThreads;
 | 
					    int renderPoolThreads;
 | 
				
			||||||
| 
						 | 
					@ -1884,6 +1886,7 @@ class FurnaceGUI {
 | 
				
			||||||
      centerPopup(1),
 | 
					      centerPopup(1),
 | 
				
			||||||
      insIconsStyle(1),
 | 
					      insIconsStyle(1),
 | 
				
			||||||
      classicChipOptions(0),
 | 
					      classicChipOptions(0),
 | 
				
			||||||
 | 
					      exportOptionsLayout(1),
 | 
				
			||||||
      wasapiEx(0),
 | 
					      wasapiEx(0),
 | 
				
			||||||
      chanOscThreads(0),
 | 
					      chanOscThreads(0),
 | 
				
			||||||
      renderPoolThreads(0),
 | 
					      renderPoolThreads(0),
 | 
				
			||||||
| 
						 | 
					@ -2331,6 +2334,16 @@ class FurnaceGUI {
 | 
				
			||||||
  // tutorial
 | 
					  // tutorial
 | 
				
			||||||
  int curTutorial, curTutorialStep;
 | 
					  int curTutorial, curTutorialStep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // audio export types (export options)
 | 
				
			||||||
 | 
					  int audioExportType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void drawExportAudio();
 | 
				
			||||||
 | 
					  void drawExportVGM();
 | 
				
			||||||
 | 
					  void drawExportZSM();
 | 
				
			||||||
 | 
					  void drawExportAmigaVal();
 | 
				
			||||||
 | 
					  void drawExportText();
 | 
				
			||||||
 | 
					  void drawExportCommand();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void drawSSGEnv(unsigned char type, const ImVec2& size);
 | 
					  void drawSSGEnv(unsigned char type, const ImVec2& size);
 | 
				
			||||||
  void drawWaveform(unsigned char type, bool opz, const ImVec2& size);
 | 
					  void drawWaveform(unsigned char type, bool opz, const ImVec2& size);
 | 
				
			||||||
  void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size);
 | 
					  void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size);
 | 
				
			||||||
| 
						 | 
					@ -2442,6 +2455,7 @@ class FurnaceGUI {
 | 
				
			||||||
  void drawSettings();
 | 
					  void drawSettings();
 | 
				
			||||||
  void drawDebug();
 | 
					  void drawDebug();
 | 
				
			||||||
  void drawNewSong();
 | 
					  void drawNewSong();
 | 
				
			||||||
 | 
					  void drawExport();
 | 
				
			||||||
  void drawLog();
 | 
					  void drawLog();
 | 
				
			||||||
  void drawEffectList();
 | 
					  void drawEffectList();
 | 
				
			||||||
  void drawSubSongs(bool asChild=false);
 | 
					  void drawSubSongs(bool asChild=false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -537,6 +537,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
 | 
				
			||||||
  D("OPEN_BACKUP", "Restore backup", 0),
 | 
					  D("OPEN_BACKUP", "Restore backup", 0),
 | 
				
			||||||
  D("SAVE", "Save file", FURKMOD_CMD|SDLK_s),
 | 
					  D("SAVE", "Save file", FURKMOD_CMD|SDLK_s),
 | 
				
			||||||
  D("SAVE_AS", "Save as", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_s),
 | 
					  D("SAVE_AS", "Save as", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_s),
 | 
				
			||||||
 | 
					  D("EXPORT", "Export", FURKMOD_CMD|SDLK_e),
 | 
				
			||||||
  D("UNDO", "Undo", FURKMOD_CMD|SDLK_z),
 | 
					  D("UNDO", "Undo", FURKMOD_CMD|SDLK_z),
 | 
				
			||||||
#ifdef __APPLE__
 | 
					#ifdef __APPLE__
 | 
				
			||||||
  D("REDO", "Redo", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_z),
 | 
					  D("REDO", "Redo", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_z),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1672,6 +1672,7 @@ void FurnaceGUI::drawSettings() {
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_OPEN_BACKUP);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_OPEN_BACKUP);
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_SAVE);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_SAVE);
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_SAVE_AS);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_SAVE_AS);
 | 
				
			||||||
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_EXPORT);
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_UNDO);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_UNDO);
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_REDO);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_REDO);
 | 
				
			||||||
          UI_KEYBIND_CONFIG(GUI_ACTION_PLAY_TOGGLE);
 | 
					          UI_KEYBIND_CONFIG(GUI_ACTION_PLAY_TOGGLE);
 | 
				
			||||||
| 
						 | 
					@ -2659,6 +2660,20 @@ void FurnaceGUI::drawSettings() {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ImGui::Unindent();
 | 
					        ImGui::Unindent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ImGui::Text("Export options layout:");
 | 
				
			||||||
 | 
					        if (ImGui::RadioButton("Sub-menus in File menu##eol0",settings.exportOptionsLayout==0)) {
 | 
				
			||||||
 | 
					          settings.exportOptionsLayout=0;
 | 
				
			||||||
 | 
					          settingsChanged=true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (ImGui::RadioButton("Modal window with tabs##eol1",settings.exportOptionsLayout==1)) {
 | 
				
			||||||
 | 
					          settings.exportOptionsLayout=1;
 | 
				
			||||||
 | 
					          settingsChanged=true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (ImGui::RadioButton("Modal windows with options in File menu##eol2",settings.exportOptionsLayout==2)) {
 | 
				
			||||||
 | 
					          settings.exportOptionsLayout=2;
 | 
				
			||||||
 | 
					          settingsChanged=true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool capitalMenuBarB=settings.capitalMenuBar;
 | 
					        bool capitalMenuBarB=settings.capitalMenuBar;
 | 
				
			||||||
        if (ImGui::Checkbox("Capitalize menu bar",&capitalMenuBarB)) {
 | 
					        if (ImGui::Checkbox("Capitalize menu bar",&capitalMenuBarB)) {
 | 
				
			||||||
          settings.capitalMenuBar=capitalMenuBarB;
 | 
					          settings.capitalMenuBar=capitalMenuBarB;
 | 
				
			||||||
| 
						 | 
					@ -3866,6 +3881,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
 | 
				
			||||||
  settings.centerPopup=conf.getInt("centerPopup",1);
 | 
					  settings.centerPopup=conf.getInt("centerPopup",1);
 | 
				
			||||||
  settings.insIconsStyle=conf.getInt("insIconsStyle",1);
 | 
					  settings.insIconsStyle=conf.getInt("insIconsStyle",1);
 | 
				
			||||||
  settings.classicChipOptions=conf.getInt("classicChipOptions",0);
 | 
					  settings.classicChipOptions=conf.getInt("classicChipOptions",0);
 | 
				
			||||||
 | 
					  settings.exportOptionsLayout=conf.getInt("exportOptionsLayout",1);
 | 
				
			||||||
  settings.wasapiEx=conf.getInt("wasapiEx",0);
 | 
					  settings.wasapiEx=conf.getInt("wasapiEx",0);
 | 
				
			||||||
  settings.chanOscThreads=conf.getInt("chanOscThreads",0);
 | 
					  settings.chanOscThreads=conf.getInt("chanOscThreads",0);
 | 
				
			||||||
  settings.renderPoolThreads=conf.getInt("renderPoolThreads",0);
 | 
					  settings.renderPoolThreads=conf.getInt("renderPoolThreads",0);
 | 
				
			||||||
| 
						 | 
					@ -4034,6 +4050,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
 | 
				
			||||||
  clampSetting(settings.centerPopup,0,1);
 | 
					  clampSetting(settings.centerPopup,0,1);
 | 
				
			||||||
  clampSetting(settings.insIconsStyle,0,2);
 | 
					  clampSetting(settings.insIconsStyle,0,2);
 | 
				
			||||||
  clampSetting(settings.classicChipOptions,0,1);
 | 
					  clampSetting(settings.classicChipOptions,0,1);
 | 
				
			||||||
 | 
					  clampSetting(settings.exportOptionsLayout,0,2);
 | 
				
			||||||
  clampSetting(settings.wasapiEx,0,1);
 | 
					  clampSetting(settings.wasapiEx,0,1);
 | 
				
			||||||
  clampSetting(settings.chanOscThreads,0,256);
 | 
					  clampSetting(settings.chanOscThreads,0,256);
 | 
				
			||||||
  clampSetting(settings.renderPoolThreads,0,DIV_MAX_CHIPS);
 | 
					  clampSetting(settings.renderPoolThreads,0,DIV_MAX_CHIPS);
 | 
				
			||||||
| 
						 | 
					@ -4283,6 +4300,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
 | 
				
			||||||
  conf.set("centerPopup",settings.centerPopup);
 | 
					  conf.set("centerPopup",settings.centerPopup);
 | 
				
			||||||
  conf.set("insIconsStyle",settings.insIconsStyle);
 | 
					  conf.set("insIconsStyle",settings.insIconsStyle);
 | 
				
			||||||
  conf.set("classicChipOptions",settings.classicChipOptions);
 | 
					  conf.set("classicChipOptions",settings.classicChipOptions);
 | 
				
			||||||
 | 
					  conf.set("exportOptionsLayout",settings.exportOptionsLayout);
 | 
				
			||||||
  conf.set("wasapiEx",settings.wasapiEx);
 | 
					  conf.set("wasapiEx",settings.wasapiEx);
 | 
				
			||||||
  conf.set("chanOscThreads",settings.chanOscThreads);
 | 
					  conf.set("chanOscThreads",settings.chanOscThreads);
 | 
				
			||||||
  conf.set("renderPoolThreads",settings.renderPoolThreads);
 | 
					  conf.set("renderPoolThreads",settings.renderPoolThreads);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue